ログから障害の現場を読む
散らばったログを一本の時系列にまとめ、証拠と推測を分ける
あなたは本番障害を調査するエンジニアです。以下は、複数のサービスが混ざっている可能性のあるログの一部です。次の四つを行ってください:1)出来事を時系列に並べ、最初の異常を特定する;2)ログが直接示していることと推測を二列に分ける;3)原因を確定するために足りないログ行を挙げる;4)次に実行する最小の検証を示す。最初の ERROR 行から話を始めず、その前に何が起きたかを探してください。 [ログ抜粋/時間範囲/対象サービス]
使い方
貼る前に時刻を一つのタイムゾーンへそろえます。最も価値のある手がかりは、最初の ERROR ではなく、最初に遅くなったリクエストやタイムアウトです。
向いている場面
- 決済のレイテンシが 200 ms から 4 秒に跳ね上がり、ダッシュボードは正常のまま、ユーザーからのエラー報告が始まった状況です。
- 特定の顧客のリクエストだけが失敗し、全体のエラー率はほとんど動いていません。ログから差分を探す必要があります。
向いていない場面
- スタックトレースが一つだけで、request id もタイムスタンプも前後の行もないなら、まずログを足します。分析はその後です。
- 設定の書き間違いだと分かっていて、戻すだけでよいなら、そのまま直します。時系列を作る必要はありません。
例
入力
2026-03-14T02:11:03Z api ERROR upstream timeout path=/checkout uid=8821 2026-03-14T02:11:04Z api WARN pool wait 1980ms active=20 idle=0 2026-03-14T02:11:05Z api ERROR upstream timeout path=/checkout uid=8821 2026-03-14T02:11:07Z db slow query 4.2s sql=SELECT ... FOR UPDATE
得られるもの
最初の異常は 02:11:03 の timeout ですが、時系列の転換点は 02:11:04 のコネクションプール待ちです(active=20、idle=0 で、すでに 1,980 ms 待っているリクエストがあり、プールはその timeout より前から枯渇していたと考えられます)。4.2 秒のスロークエリはその後ろに現れており、接続が塞がれた結果と見るほうが自然です。ログにロック待ちの対象も出ておらず DB が原因だと断定できないので、プール設定と `lock wait` の行を足して「プールが小さい」のか「クエリが遅くなった」のかを切り分けます。
よくある誤用
- ERROR の行だけを貼り、WARN とスロークエリを捨てることです。本当の原因はたいていこの二つにあります。
- 時間範囲とインスタンスを伝えず「原因を分析してください」とだけ頼むことです。別々のマシンのログが、存在しない因果として一本につながります。
こう変えると効く
- 「サービスごとにまとめてから時刻をそろえる」と加えると、複数サービスのログを 1 台の直列処理と読み違えなくなります。
- 「結論ごとに元の行番号を付ける」と求めると、どれが証拠でどれが想像かが一目で分かります。