1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

監視におけるFalse Negative(偽陰性)とFalse Positive(偽陽性)について

Last updated at Posted at 2023-06-22

株式会社インディバースの代表、エンジニアのDAIです。
監視において、「見逃しと誤検知の問題」にちょうど取り掛かっているのですが、
良い資料がネットに見当たらなかったので、社内共有用もかねてのメモです。

TL;DR

  • 監視において、エラーの見逃しと誤検知を放っておくと, プロダクションのコードに対してのバグ混入率が増える
  • その結果、サービスの信頼性が落ち、サービス自体の運営が厳しくなる
  • 監視における見逃しと誤検知の問題に対して、どういう対処をすべきかについて解説します

見逃しと誤検知

  • 見逃し = False Negative = 偽陰性
  • 誤検知 = False Positive = 偽陽性

監視におけるFalse Negativeとは

  • 仕様が間違っているものに対して、監視ではokを出してしまっている状態
  • つまり、「エラーを見逃している状態」

緊急地震速報に例えると

  • 大きめの地震が起こっていたのに-> 何か問題が起こった時に
  • 緊急地震速報がならず、地震が来たことに気づかない -> 気付かないので
  • 津波が来ているのに、逃げ遅れる -> 対応できない

False Negativeの例

  • データのインポート処理のロジックをスケジューラーで動かしていた。データがインポートされていると思っていたが、静かにジョブが死んでいた。
  • その結果エラーは通知されておらず、プロダクションのコードに影響が起こっていたことに気づかなかった
  • 結果、顧客の環境で重大なエラーが起こっていた

監視におけるFalse Negativeが多い開発組織では何が起きるか

  • クリティカルなエラーが起こっていても、誰も気づけない
  • その結果プロダクションのコードに重大なエラーが入る
  • その結果顧客が解約する
  • サービスの存続ができなくなる

False Negativeに対する対応方針

  • エラーの握りつぶしを極力止めるようにして、エラーが発生したらちゃんとraiseされるようにする
# NG
def Parent

end

def Child < Parent
   def execute 
   
   # NG 雑に全てのエラーを握りつぶすと、予想外のエラーが通知されない
   rescue StandardError => e
      Rails.logger.debug(e)
   end
end

# GOOD

def Parent

end

def Child < Parent
   def execute 
   
   # OK 想定されるエラーのみrescueして対応する
   # それ以外のエラーはちゃんとraiseされるようにする
   rescue ArgumentError => e
      # 引数間違っていた時の対応処理
   end
end
  • 親クラスで、キャッチできなかったエラーは全部拾って、監視システムに投げられる体制にする(raiseされたエラーが監視システムへ飛ばされる状態を作る
# NG

def Parent

end

def Child < Parent
   def execute 

   # NG 
   # 想定されないエラーが起こった時に、エラーが監視システムに通知されない   
   rescue ArgumentError => e
      # 引数間違っていた時の対応処理
   end
end
# NG

def Parent

end

def Child < Parent
   def execute 

   rescue ArgumentError => e
      # 引数間違っていた時の対応処理

   # NG 
   # 子クラスで実装すると、毎回エラーをraiseする処理作らないといけないので面倒くさい
   rescue StandardError => e
      Sentry.capture_exception(e) if Rails.env.production?
   end
end
# OK

def Parent
   # 親クラスで子クラスの拾いきれなかったエラーはまとめて監視システムへ通知する ※Sentryは監視ツール
   rescue_from StandardError => notify_error_to_sentry(e)

   def notify_error_to_sentry(e)
      Sentry.capture_exception(e) if Rails.env.production?
   end
end

def Child < Parent
   def execute 

   rescue ArgumentError => e
      # 引数間違っていた時の対応処理
   end
end

False Positive(偽陽性)とは

  • 仕様は合っているのに、監視ではNGを出している状態
  • 間違っていない問題に対して、エラーだと認識して誤検知している状態

緊急地震速報に例えると

  • 全く地震が起こってないのに、緊急地震速報が毎日流れているような状態で、いざ大きい地震が起こった時
  • 誤検知だと判断して無視するので 
  • 津波が来ているのに逃げ遅れる

監視におけるFalse Positiveの例

  • 外部サービスにスクレイピングしてCSVを取得するスクリプトで、csvが存在しない場合はcsvをダウンロードしないのだが、その仕様を想定せずSeleniumでdom指定した結果、エラーがraiseされた
  • CSVが存在しないときにダウンロードできないというビジネス的な仕様としては正しいが、エラーがraiseされ続けている状態になる

監視におけるFalse Positiveを放っておくと

  • エラーが毎日通知される
  • その結果、他の重要なエラー通知を見逃す
  • 重要なエラーが出ているのに、気づけないため、プロダクションコードにクリティカルなエラーが混入する

監視におけるFalse Positiveに対する対応方針

  • 既にアラートが出ているエラーに対するエラーハンドリング、もしくは修正を行い、新規のエラーがない状態にする
  • 即時での修正が難しい場合、最低限起票しておいて、対応方針を決めておく

最後に

Railsエンジニアを採用中です!
Wantedlyからカジュアル面談よろしくお願いします!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?