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

本番バックエンドAPIキャップストーン

メトリクス・ログ・トレースは別々の問いに答える

TT Labで続きを見る

一言でいうと

メトリクスは全体の傾向とアラートを、構造化ログは1つの出来事のコンテキストを、トレース識別子は境界をまたぐ因果関係を説明します。3つのシグナルは、同じリクエストから出た安全な相関フィールドで結ばれていなければなりません。

なぜログ1行では障害を解決できないのか

error happenedという文字列は、どれくらいの頻度で、どのパスで、どんな状態で失敗したのかを教えてくれません。注文の作成数とHTTPのレイテンシのメトリクスは、変化としきい値を示します。JSONログのevent、route、status、duration_msは、個別のリクエストを検索できるようにします。レスポンスヘッダーとログに同じtrace IDを入れれば、ユーザーが報告したリクエストを正確に見つけられます。サービスが複数あるなら、このIDを次の呼び出しに伝播します。

メトリクス名は、orders_created_total、http_request_duration_secondsのように、単位と累積の意味が表れていなければなりません。ユーザーIDや注文IDをメトリクスのラベルに使うと、カーディナリティが爆発します。そうした一意の値は、必要な場合にログに入れますが、個人情報と機密値のポリシーを適用します。認証ヘッダー、クッキー、パスワード、接続文字列、内部サービスのDNSは、どのシグナルにも記録しません。

現場での検証方法

採点ツールは、サーバーに作成リクエストを送ってレスポンスのtrace IDを取得し、/metricsから2つの主要な指標を読みます。サーバーの終了後、各ログの行をJSONとしてパースして、同じtrace ID、/ordersパス、201ステータス、数値のduration_msが、1つのレコードにあるかを確認します。単にソースにjsonやtrace_idという文字列があるかどうかは、証拠ではありません。import時に出力が生じたり、トークンの原文がログに現れたりしても失敗です。

3つのシグナルを何に使うかを分ける

ログ・メトリクス・トレースをすべて集めなさいという話はよく聞きますが、何を尋ねるときにどれを見るのかを 決めておかないと、3つとも揃っているのに、障害のときに迷います。

質問 見るもの 理由
今、問題があるか メトリクス 値が安く、全体をカバーする。アラートはここにだけかける
どこが遅いか トレース リクエスト1つが通過した区間ごとの時間
なぜそうなったか ログ その瞬間のコンテキスト。最も高いので、最後に見る

アラートは、メトリクスにだけかけます。ログの文字列でアラートをかけると、メッセージを少し変えただけで 静かに鳴らなくなり、その事実を障害のときに知ることになります。

3つのシグナルを、1つの識別子でつなぎます。リクエストごとにトレースIDを作ってログにも入れ、 メトリクスのエグザンプラー(exemplar)としても付けます。そうすれば、「遅いリクエスト1つ」から、そのリクエストのログに すぐに行けます。この接続がないと、時刻でログを漁ることになり、その方式は、トラフィックが 増えた瞬間に役に立たなくなります。

カーディナリティは、メトリクスでだけ問題になります。ユーザーIDをログに入れるのは問題ありませんが、 メトリクスのラベルに入れると、時系列が爆発します。カーディナリティの高い値は、ログとトレースに置き、 メトリクスには、カーディナリティの低いものだけを置きます。

測定は、ユーザー側からもう一度行います。サーバーが200を返していても、ユーザーは失敗している ことがあります。フロントエンドで測る値や、外部で動く合成モニタリングを1つ置けば、 「内部のメトリクスは正常なのに、問い合わせが来る」という状況がなくなります。

残すものを決める基準は、「これでどんな決定をするのか」です。決定を変えない メトリクスは、ダッシュボードを散らかして、コストだけがかかります。ダッシュボードを作るたびに、その画面を見て 取る行動を1行で書いておけば、半分はなくなります。

実務での判断基準

良いオブザーバビリティは、事後のデバッグ用の文をたくさん出力することではなく、運用上の質問を先に決めて、低コストのシグナルを設計することです。成功率、エラー率、レイテンシ、トラフィックをメトリクスで見て、特定の異常をtraceとログで絞り込みます。続くデプロイのレッスンでは、これらのシグナルが正常でも、準備のできていないPodにトラフィックを送らないように、プローブと実行のセキュリティ境界を設計します。