LoginSignup
4
1

W3C Trace Contextについて

Last updated at Posted at 2023-12-16

本記事はOpenTelemetry Advent Calendar 2023の16日目の記事になります。
昨日は@munisystemさんのOpen Agent Management Protocol (OpAMP) についてでした。

本記事ではW3C Trace Contextの内容を要約しています。
また、本記事を読む前にOpenTelemetry Advent Calendar 2023 3日目の@sumirenさんによるOpenTelemetry 分散トレーシングのシステムアーキテクチャを読んでいただくと理解が深まると思います。

OpenTelemetryとの関係性

OpenTelemetryのContext Propagationは複数のフォーマットをサポートしていますが、デフォルトで使用されるフォーマットがW3C Trace Contextになります。つまり標準ではW3C Trace Contextの形式でHTTPヘッダーを挿入し、トレース情報を伝播していきます。

W3C Trace Contextとは

W3C Trace Contextは、分散システムにおけるトレース情報の伝播を標準化するための仕様です。HTTPヘッダーと値の形式を定義し、それによって分散トレーシングを可能にします。具体的には、各サービス間でコンテキスト情報を送信し、変更する方法を標準化しています。その名の通り、World Wide Web Consortium (W3C)によって標準されています。

このコンテキスト情報は、分散システム内の個々のリクエストを一意に識別し、プロバイダ固有のコンテキスト情報を追加し、伝播する手段を定義します。これにより、異なるトレーシングベンダーによって収集されたトレースを相互に関連付けることが可能になります。

トレースコンテキストのHTTPヘッダーフォーマット

分散トレースにおけるコンテキストとして、traceparenttracestateの2つを定義しています。

traceparentは、そのトレースにおけるリクエストの位置を移植可能な固定長フォーマットで記述します。その設計は高速な解析に重点を置いています。すべてのトレースツールは、 tracestate のベンダ固有の情報のみに依存する場合でも、 traceparent を適切に設定しなければなりません。
tracestateは、名前と値のペアのセットで表されるベンダー固有のデータで traceparent を拡張します。tracestate に情報を格納することはオプションです。

最低限、traceparenttracestateヘッダーを伝搬し、トレースが壊れないことを保証しなければなりません。この動作はトレースの転送とも呼ばれます。
さらに、トレースはtraceparentヘッダーとtracestateヘッダーの関連部分を修正することで、トレースに参加することもできます。これはトレースへの参加とも呼ばれます。
トレースツールは、監視しているコンポーネントへの個々のリクエストごとに、この動作を変更することができます。

ヘッダー間の関係性

traceparentヘッダーは、トレースシステムの受信リクエストを、すべてのベンダが理解できる共通のフォーマットで表します。以下は traceparentヘッダーの例です。

traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01

tracestateヘッダーは、ベンダ固有の形式である可能性のある親を含みます:

tracestate: congo=t61rcWkgMzE

例えば、あるシステムのクライアントとサーバーが異なるトレーシング・ベンダーを使用しているとします: CongoとRojoです。Congo システムでトレースされたクライアントは、送信HTTP リクエストに以下のヘッダーを追加します。

traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
tracestate: congo=t61rcWkgMzE

Rojoトレースシステムでトレースされた受信サーバーは、受信したtracestateを引き継ぎ、左側に新しいエントリを追加します。

traceparent: 00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01
tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE

Rojoのシステムはtracestateのエントリにtraceparentの値を再利用しています。これは、一般的なトレースシステムであることを意味します(独自の情報は渡されません)。そうでない場合、tracestateのエントリは不透明で、ベンダ固有である可能性があります。
次の受信サーバーがCongoを使用する場合、Rojoからのtracestateを引き継ぎ、前のエントリの左に親の新しいエントリを追加します。
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01
tracestate: congo=ucfJifl5GOE,rojo=00f067aa0ba902b7
注: ucfJifl5GOE は、Base64 エンコードされた親 ID b9c7c989f97918e1 です。

Congoがそのtraceparentエントリーを書いたとき、それがエンコードされていないことに注意する必要があります。しかしtracestateの値はエンコードされており、traceparentとは異なります。これは問題ありません。

最後に、tracestateはRojoのエントリを、右にプッシュされている以外は、そのまま保持していることがわかります。一番左の位置は、次のサーバーにどのトレースシステムがtraceparentに対応するかを知らせます。この場合、Congoがtraceparentを書いたので、そのtracestateのエントリは一番左になるはずです。

Traceparent ヘッダー

traceparent HTTPヘッダーフィールドはトレースシステムで受信リクエストを識別し、以下の4つのフィールドから構成されています。

  • version
  • trace-id
  • parent-id
  • trace-flags

Tracestateヘッダー

tracestate HTTP ヘッダーの主な目的は、異なる分散トレースシステム間で追加のベンダ固有のトレース識別情報を提供することであり、traceparentフィールドのコンパニオンヘッダーです。また、複数の分散トレースグラフにおけるリクエストの位置についての情報も伝えます。

トレースコンテキストの処理モデル

この処理モデルは、トレースコンテキストヘッダーを修正して転送するベンダーの動作を記述します。このモデルがどのように動作するかは、traceparentヘッダーを受信するかどうかに依存します。

トレースペアレントの受信なし

traceparentヘッダーを受け取らない場合:

  1. ベンダは受信リクエストにtraceparentヘッダーとtracestateヘッダーがないかチェックします。
  2. traceparentヘッダーが受け取られないので、ベンダーは現在のリクエストを表す新しいtrace-idparent-idを作成します。
  3. traceparentヘッダーを伴わずにtracestateヘッダーを受け取る場合、それは無効なので破棄されなければならない。
  4. ベンダーは新しいtracestateヘッダーを生成し、新しいkey/valueペアを追加すべきである。
  5. ベンダーは発信リクエストにtraceparentヘッダーとtracestateヘッダーを設定します。

トレースペアレントの受信

traceparentヘッダーを受信した場合:

  1. traceparentヘッダーを受け取った場合: ベンダーは受信リクエストにtraceparentヘッダーとtracestateヘッダーがあるかどうかチェックします。
  2. traceparentヘッダーが存在するので、ベンダーはtraceparentヘッダーの バージョンの解析を試みます。
    1. バージョンが解析できない場合、ベンダは新しいtraceparentヘッダーを作成し、tracestateを削除します。
    2. バージョン番号がトレーサがサポートするバージョンより高い場合、ベンダーはこの仕様で定義されたフォーマット (00) を使用してtrace-idparent-idを解析します。ベンダーは、この仕様のこのバージョンでサポートされているtrace-flags値のみを解析し、その他の値はすべて無視します。解析に失敗した場合、ベンダーは新しいtraceparentヘッダーを作成し、tracestateを削除します。ベンダーは発信リクエストに対して、すべての解析されていない / 未知のtrace-flagsを0に設定します。
    3. ベンダーがバージョン番号をサポートしている場合、trace-idparent-idを検証します。trace-idparent-idtrace-flagsのいずれかが無効な場合、ベンダーは新しいtraceparentヘッダーを作成し、tracestateを削除します。
  3. ベンダーはtracestateヘッダーを検証してもよい。tracestateヘッダーを解析できない場合、ベンダーはヘッダー全体を破棄してもよい。無効なtracestateエントリも破棄してもよい。
  4. 各送信リクエストに対して、ベンダーは以下の手順を実行します:
    1. ベンダーはtraceparentヘッダーを修正しなければならない:
      • parent-id更新parent-idプロパティの値を、現在の操作のIDを表す値に設定しなければならない。
      • sampled更新sampledの値は、呼び出し元の記録動作を反映します。trace-flagssampledフラグの値は、トレースデータが記録される可能性が高い場合は1に、そうでない場合は0に設定してもよい。このフラグを設定することは、トレースが記録されることを保証するものではありませんが、エンドツーエンドで記録されるトレースの可能性を高めます。
    2. ベンダーは tracestate ヘッダーを修正してもよい:
      • キーバリューの更新: キーの値を更新する: 任意のキーの値を更新することができます。変更されたキーはリストの先頭(左)に移動しなければならない。
      • 新しいキーとバリューのペアの追加: 新しいキーと値のペアは、リストの先頭(左)に追加されなければなりません。
      • キーと値のペアの削除: どのkey/valueペアも削除してもよい。ベンダーは、自分で生成していないキーを削除すべきではない。キーと値のペアを削除すると、他のシステムとの相関が壊れてしまうかもしれません。
    3. ベンダーは発信リクエストにtraceparentヘッダーとtracestateヘッダーを設定します。

まとめ

さらに細かい詳細はぜひW3C Trace Contextをご確認ください。また、W3C Editor's DraftとしてTrace Context Level 3が議論されています。気になる方はこちらもチェックしてみてください。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1