オブザーバビリティ入門 - メトリクス・ログ・トレースの使い分け

11分 で読める | 2026.04.10

公式ドキュメント

オブザーバビリティ(可観測性)は、システムが出す情報から内部状態を調べられる性質です。既知の異常を検知するmonitoringだけでなく、事前に用意していなかった問いも調べられる状態を目指します。

メトリクス、ログ、トレースは「3本柱」と呼ばれますが、三種類を保存するだけでは十分ではありません。同じrequestやserviceを共通のcontextで結び、仮説に合うsignalへ移れることが重要です。

メトリクス・トレース・ログを共通コンテキストで結び、トレースとログはトレースIDで直接関連付ける図

三つのsignalが答えやすい問い

signal得意な問い代表例
Metricsいつから、どの程度、どこで広がったかrequest数、error率、latency、queue長
Logs特定時点に何が起き、どんな判断をしたかerror code、状態遷移、構造化event
Traces一つのrequestがどの処理を通り、どこで待ったかservice間のspan、DB・外部API時間

メトリクスは多数の測定を集約するため、全体傾向とalertに向きます。個別requestのbodyを調べるものではありません。

ログはeventの詳細を残せますが、量が多く、自由文だけでは検索しにくくなります。安定したfield名を持つstructured logsを使います。

トレースは一つのrequestの経路をspanの親子関係で表します。分散serviceで待ち時間の場所を探せますが、sampleされていないrequestは残らない場合があります。

共通contextでつなぐ

service AからBを呼ぶ時、trace IDと親span情報を伝播すると、Bのspanを同じtraceへ関連付けられます。logにもtrace_idspan_idを入れると、traceから該当時刻のlogへ移れます。

{
  "timestamp": "2026-04-10T09:31:15Z",
  "level": "error",
  "service": "checkout-api",
  "event": "payment_request_failed",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "span_id": "00f067aa0ba902b7",
  "error_code": "provider_timeout"
}

JSONであるだけではstructured logとは言えません。同じfieldが同じ型と意味を持つschemaが必要です。service名、環境、versionなど共通属性もそろえます。

利用者が送るtrace headerをそのまま信頼すると、衝突やlog汚染につながる場合があります。入口で形式を検証し、信頼境界に合わせて新しいtraceを開始するか判断します。

一つのincidentを調べる流れ

状況を「決済画面が時々遅い」とします。

1. Metricsで範囲を知る

checkout APIのrequest数、error率、latency分布を見ます。平均だけでなくp95やp99を確認し、開始時刻、対象region、versionを絞ります。

09:30から checkout latency p95 が0.8秒 -> 4.2秒
error率は変化なし
version=2026.04.10-2で増加

ここでは原因を断定しません。「一部requestの待ち時間が増えた」という観察です。

2. Tracesで遅い区間を探す

同じ時間帯の遅いtraceを選び、checkout全体、DB、payment providerなどのspanを比較します。payment provider spanだけが長ければ、外部呼び出しや接続待ちを仮説にします。

速いtraceと遅いtraceを一件ずつ比較し、特定regionやpayloadだけかも確認します。一つのtraceを全体傾向だと考えません。

3. Logsで判断と失敗条件を見る

遅いspanのtrace_idでlogを検索し、timeout設定、retry回数、providerのresponse分類を確認します。token、カード情報、request body全体を記録してはいけません。

4. 修正後に同じsignalで確認する

timeoutとretryを修正したなら、latency分布、外部span、timeout logを同じ条件で比較します。error率だけ改善しても、fallbackが誤った成功を返していないか、業務指標も見ます。

Metricsのcardinalityを制御する

metricの属性組み合わせ数をcardinalityと呼びます。user_id、request ID、生のURLのように値が増え続ける属性を付けると、集約状態と保存コストが急増します。

良い候補: method, route template, status class, region
避ける候補: user_id, email, raw URL, trace_id

/users/123/users/456は、/users/{id}というroute templateへ正規化します。個別requestへ移る時はexemplarやtrace linkなど、backendが提供する関連付けを使います。

Logsで秘密情報を残さない

次はlogへ直接書きません。

  • password、access token、cookie、Authorization header
  • 決済情報、個人番号、秘密鍵
  • 必要性のないemail、住所、request body全体

debugのため一時的に増やす場合も、環境、期間、access権、削除方法を決めます。error objectやHTTP clientの自動serializationがheaderを含めることもあるため、出力結果を確認します。

Tracingとsampling

すべてのtraceを保存すると費用が増えます。入口で割合を決めるhead samplingは単純ですが、結果を知る前に捨てるため、まれなerrorを失う可能性があります。収集後にerrorや遅いtraceを優先するtail samplingは、collector側のstateと遅延が増えます。

samplingしてもmetricsによる総数は維持し、error traceを残す方針を決めます。trace内で親子のsampling判断が食い違い、途中のspanだけ欠けないようcontext propagationを確認します。

最小の導入順

  1. service名、環境、versionを全signalへ付ける
  2. request数、error率、latencyのmetricsを持つ
  3. error logを安定したschemaへする
  4. HTTP・DB・外部APIを自動計装し、traceをつなぐ
  5. 一件のincidentを三signalで往復できるか試す
  6. 保存期間、sampling、cardinalityと費用を調整する

OpenTelemetryはsignalの生成・収集・exportを標準化しますが、何を測り、どのfieldを残し、どのalertで行動するかはシステム側で決めます。

よくある誤解

  • 三種類を導入すればobservable:相関、schema、調査手順がなければ分断されたdataです。
  • logを増やせば原因が分かる:問いに不要なlogは費用とnoiseを増やします。
  • 平均latencyが正常なら問題なし:一部利用者の遅さはpercentileで確認します。
  • trace IDをmetric labelにする:cardinalityが増えすぎます。
  • OpenTelemetryが監視backendである:主にtelemetryのAPI、SDK、protocol、collectorを提供するprojectです。

まとめ

Metricsは広がり、logsは出来事、tracesは一requestの経路を調べるsignalです。共通contextで結び、metricsからtrace、traceからlogへ移り、修正後に同じ指標で確認します。cardinality、秘密情報、samplingを設計して初めて、継続して使えるobservabilityになります。

参考リソース

次に読む記事

← 一覧に戻る
PR
PR
PR
PR