TT Lab
はじめる
学ぶ 学習パス コース

ログから原因を見つける

ログがないということも情報だ

TT Labで続きを見る

一言でいうと

ログがなくても、調査が終わるわけではありません。ほかの痕跡で時間を絞り、次の事故にはログが残るようにするところまでが仕事です。

なぜ必要なのか

「昨日の午後に何件か失敗したそうです」という報告を受けて、ログを探します。ところが、保存期間が24時間ですでに消えていたり、ログレベルがWARNで必要な情報が出力されていなかったり、そもそもその区間にログ文がなかったりします。

このとき、「ログがなくて確認不能」で終わらせると、同じことが繰り返されます。

ログではない痕跡

痕跡 何がわかるか 確認方法
ファイルのmtime いつ何が変わったか find /etc -mmin -1440 -type f
DBのタイムスタンプ データが作られた・変わった時刻 created_at、updated_atの分布
プロセスの開始時刻 いつ再起動されたか ps -eo pid,lstart,cmd
システムの起動時刻 サーバーがいつ立ち上がったか uptime -s
ファイルサイズの変化 いつ急増したか バックアップスナップショットの間の比較
パッケージのインストール時刻 何がいつ入ったか /var/log/dpkg.log、rpm -qa --last
シェル履歴 人が何をしたか ~/.bash_history(時刻を設定している場合)
証明書の有効期間 期限切れによる障害の時刻 openssl x509 -noout -dates

データそのものがログです。失敗した注文のcreated_atの分布を分単位で集計すれば、ログがなくても、事故が始まった分(minute)を特定できます。

SELECT date_trunc('minute', created_at) AS m, count(*)
FROM orders WHERE status='FAILED' AND created_at >= now() - interval '2 days'
GROUP BY 1 ORDER BY 1;

この結果で値が跳ねる地点が、事故の時刻です。そして、その時刻をデプロイ記録、設定変更、起動時刻と突き合わせると、候補が1つか2つに絞られます。

ないという事実も証拠

ログが空いている区間は、それ自体が情報です。

「出力されなかった」を「わからない」に翻訳せず、「何が出力されなかったのか」を問えば、範囲が絞られます。

次のために残す

調査の末に原因を見つけたなら、最後の作業は、同じことがまた起きても、今回より早く気づけるようにすることです。

  1. ログ文を追加する: 失敗する経路に、何がなぜ失敗したかを。事後調査で必要だった値(リクエストID、対象、所要時間)も一緒に。
  2. 保存期間を調整する: 24時間は、大半の調査には足りません。せめてエラーログだけでも長く。
  3. 相関ID: リクエストごとにIDを付けて、システムをまたいで追跡できるように。これがないと、複数のサービスのログを時刻だけで合わせることになります。
  4. 指標を1つ: 今回問題だったものを、カウンターやゲージで。次回はグラフで見えます。

この4つを報告書の「再発防止」の項目に書けば、それは形式的な文ではなく、実際に次の調査を数時間短縮します。

事後計装: 今すぐ必要な場合

問題がいま進行中なのにログがないなら、再現している間に観測を付けます。

荒削りですが、何もないよりは圧倒的に優れています。そして、このファイルが、次の会議で唯一の根拠になります。

他人のシステムで初めて観測を付けるとき

FDEとして入った現場には、たいていログがないか、あっても見られません。権限もなく、デプロイも勝手にはできない状態で、最小の変更で最大限を見る順序があります。

1つ目は、すでにあるものを探すことです。新しく付ける前に、そのシステムがすでに残しているものを数えます。Webサーバーのアクセスログ、データベースのスロークエリログ、ロードバランサーの統計、クラウドのフローログ。たいてい有効になっているのに、誰も見ていません。

2つ目は、外から測ることです。コードを直せなくても、外から叩くことはできます。数分間隔で主要なパスを呼び出して、レスポンス時間とステータスコードを残せば、障害がいつ始まったかは、それだけでわかります。原因がわからなくても、時刻がわかることが、調査の半分です。

3つ目は、境界に付けることです。アプリケーションを直せなくても、その前段のプロキシやサイドカーは変更できることが多いです。リクエスト単位で時間とステータスを残すようにすれば、コードを1行も直さずに、リクエストごとの観測が得られます。

4つ目は、そこで初めてコードを直すことです。ここまで来れば、どこを計装すべきかをすでに知っています。最初からコードに手を付けると、見当違いの場所を計装することになり、その変更を元に戻すコストまで払います。

残すものと残さないものを、最初に決めます。他人のシステムであるほど、個人情報が何かを知らないままログを有効にしがちです。リクエスト本文をまるごと残す設定は、有効にする前に、何が入っているかを先に確認します。

報告するときは、数字と一緒に、その数字の出所を書きます。「遅いです」ではなく、「このパスのp95が4.2秒で、ロードバランサー基準の過去7日間の中央値は0.4秒です」と書けば、その場で次の行動が決まります。出所がなければ、その数字から争い直すことになります。

現場での姿

続くラボですること

事故の区間のエラーログが消えた現場を受け取ります。データのcreated_at、アクセスログの空き区間、設定ファイルの更新時刻だけで、事故の時刻を分単位まで絞り、候補を1つにします。

最後に、事後計装ツールを自分で作ります。採点ツールがそれを実際に実行して、時刻と観測値が定期的に残るかを確認します。