👀概要
この記事ではオブザーバビリティの3本柱とよばれるテレメトリーデータ(ログ/トレース/メトリクス)の用語を解説する試みです。
関連記事
- オブザーバビリティツールをカテゴライズする試み
- OpenTelemetry + Flask + Jaeger で始める、最小構成の分散トレーシング【OpenTelemetryサクッと入門】
- オブザーバビリティの3本柱|ログ・メトリクス・トレース【OpenTelemetryサクッと入門】
- OpenTelemetryを汚さず入れる。Pythonゼロコード実装【OpenTelemetryサクッと入門】
- OpenTelemetry Collector を導入するメリットと構成の勘所【OpenTelemetryサクッと入門】
👨👩👧👦対象者(Who)
- オブザーバビリティツールを検討している方
- OpenTelemetryに興味がある方
📌関連リンク
📝 内容
なぜ メトリクスデータ が必要なのか
分散システムのデバッグの本質
- マイクロサービスでは 1つのユーザー操作に複数サービスが起動します。
- 問題調査で本当に知りたいのは ある1リクエストが、「どこを通り」「どこで遅くなり」「どこで壊れたか」
マイクロサービスを構成する個々のサービスの個々のログではなく“1つの取引(トランザクション)全体”をみるための仕組みが重要です。
Traceとは何か
Trace/Span の 用語の定義
- Trace は 1つの操作に属する単一のイベント(Span)の集合
- Span は 単一のイベント
SpanとTraceの関係は以下の通り
Trace
├─ Span A (Frontend)
│ ├─ Span B (API)
│ │ └─ Span C (DB)
│ └─ Span D (Cache)
Span とは何か
Span は 単一のイベント
- 例:
- HTTP リクエスト
- DB クエリ
- 外部 API 呼び出し
Span(単一のイベント)は以下の情報を持つ
- 開始時刻
- 終了時刻
- 属性(HTTP method、status、service 名など)
- 親子関係(呼び出し元 / 呼び出し先)
「時間付き・構造化ログ + 因果関係」
Span は必ず「開始」と「終了」を持つ。
そのため、タイムライン表示、ガントチャート的可視化 が自然にできる
Tracing は 「Spanを“点”から“因果グラフ”に進化させたもの」
Metrics とは何か
定義
- Metrics = 時間に沿って集計された数値
例
- レイテンシ
- リクエスト数
- エラー率
- CPU / メモリ
集計された数値を参照するため、以下の特徴がある
- ログやトレースより 安定
- ノイズが少ない
- 長期傾向が見える
したがって、「状態監視・アラートの指標として使われる」
メトリクスデータ例
メトリクスデータには以下のようなデータ構造が使われる
http_requests_total{
service="payment",
method="POST",
status="200"
}
トレースエグザンプラー
従来の監視の時
メトリクス視点では「レイテンシが急上昇している」というのがわかるが
トレース視点では「どのリクエストが原因か分からない」という状況に陥っていた。
これらの課題を解決するため、メトリクス上の異常な1点(スパイクなど)から、対応する具体的なトレースを直接辿れるようにする機能がトレースエグザンプラー。
- 具体的な実装 : メトリクスを計算する際の特定サンプル点に、
trace_id/span_idを紐づけます。 - メリット : レイテンシのスパイク点をクリックすることで、該当するトレースが表示することができます。 これにより、遅延したSQL / 外部API / span の特定が高速化されました。
メトリクスとトレースを“点でつなぐ”ための仕組みが、トレースエグザンプラーです。
Logs とは何か
ログとは、システム内で発生した特定のイベントを時系列に記録したデータです。
ログの特徴
- 不変性: 過去に起きた事実をそのまま記録します。
- 普遍性: ほぼすべてのプログラミング言語やフレームワークに標準的なライブラリが存在します。
- 低コストな導入: コード一行で「何が起きたか」を書き出せるため、最も古くから利用されています。
従来のログが抱える課題とOpenTelemetry がもたらす解決策
従来のログは「点」の情報に過ぎませんでした。
- 相関の欠如: 1つのリクエストが複数のマイクロサービスを跨ぐ場合、どのログが同じ一連の処理(トレース)に属するのか判別が困難です。
- 文脈(コンテキスト)の不在: 「支払いに失敗した」というログがあっても、それがどのユーザーで、どのコンテキストで発生したのかを特定するには、ログを1つずつ突き合わせる「職人芸」が必要でした。
OpenTelemetryは、ログを単なる「文字列」から、**「文脈を持つ構造化データ」**へと昇華させようとしています。
ログへの「文脈」の自動付与
OTelを使用すると、以下のメタデータがログに自動的に紐付けられます。これを Log Correlation(ログの相関) と呼びます。
| 項目 | 内容 |
|---|---|
| Trace ID / Span ID | そのログがどのリクエスト(トレース)の、どの工程(スパン)で出たかを示します。 |
| Resource 属性 | 実行されているホスト名、コンテナID、クラウドのリージョンなどの環境情報です。 |
| Service 名 | どのマイクロサービスが出力したログかを識別します。 |
これにより、**「エラーログを見つけた瞬間に、その前後の挙動(トレース)を芋づる式に引き出す」**ことが可能になります。
実装の仕組み:どこで「噛ませる」のか
実装方法についての理解も正確です。既存のアプリケーションコードを大きく書き換えることなく、ログの「出口」でOTelの仕様に変換します。
1. Appender / Handler レベル(SDK)
JavaのLogbackやPythonのloggingライブラリなど、既存のログフレームワークに OTel Log Appender を追加します。これにより、ログがメモリ上でキャプチャされ、自動的にTrace IDなどが注入されます。
2. Collector / Agent レベル
アプリケーションがファイルに書き出したログを、OpenTelemetry Collector が読み取ります。ここで構造化(パース)や属性の付与を行い、最終的な保存先(Backend)へと転送します。
出典元と参考リファレンス:
OpenTelemetry Documentation: Logs | OpenTelemetry
Specification OpenTelemetry Logging SDK Specification
Baggage(バゲッジ)
バゲッジとは、リクエストのライフサイクル全体に付随して運ばれる「軽量なキー・バリュー情報」
トレース・メトリクス・ログを横断的に関連付ける補助情報として使われます。(OpenTelemetry の仕様で定義)
例えば、HTTPヘッダなどを通じて以下のデータをサービス境界をまたいで自動的に伝搬させたとします。
user_id=12345
tenant=premium
experiment=A
この時に
- ログに tenant=premium を自動付与
- メトリクスを experiment=A/B で分解
- 特定ユーザーの遅延だけを追跡
といった横断分析が可能になるのです。
これは、上位レイヤーにのみ存在するデータ(リクエストIDなど)を、後続のレイヤー(マイクロサービスの別APIなど)に伝搬させるときに便利です。
まとめ
これら3つのテレメトリデータは、単体でも強力ですが、OpenTelemetryによって**「相関」**を持つことでその真価を発揮します。
- Metrics で異常を検知し(例:エラー率のスパイク)
- Exemplar を経由して、異常時の具体的な Trace を特定し
- Logs でその瞬間に何が起きたかの詳細を確認する
この一連の流れをシームレスに行える状態こそが、現代の分散システムにおける「運用しやすさ(オブザーバビリティ)」のゴールです。
さらに、Baggage を活用してビジネスコンテキスト(ユーザー属性など)を伝搬させれば、エンジニアリングの枠を超えて「特定の重要顧客で発生している問題」といったビジネス視点の分析も可能になります。
まずは、最も導入ハードルの低い Logs の構造化や、自動計測が可能な Trace からスモールスタートして、システムの「透明度」を上げていきましょう。