Managed Service for OpenTelemetry は、OpenTracing データモデルを使用して、マイクロサービスアーキテクチャ向けの分散トレーシングを提供します。このトピックでは、トレース、スパン、データモデル、およびデータレポート方法について説明します。
OpenTracing は OpenTelemetry の前身です。Managed Service for OpenTelemetry は、ここで説明する OpenTracing データモデルをサポートしています。OpenTelemetry 標準については、OpenTelemetry ドキュメントをご参照ください。
基本概念
| 概念 | 説明 |
|---|---|
| 分散トレーシング | 分散システム内の複数のサービスを介してリクエストが流れるのを追跡するためのメソッドです。 |
| トレース | 分散システムにおけるトランザクションまたはプロセスのエンドツーエンドの記録です。トレースは、スパンで構成される有向非循環グラフ (DAG) です。 |
| スパン | トレース内の名前付きで時間指定された作業単位です。 |
| SpanContext | スパン (トレース ID、スパン ID) を識別し、プロセス境界を越えてバゲージ項目を伝達するメタデータです。 |
| リファレンス | 2 つのスパン間の因果関係です。OpenTracing は、ChildOf と FollowsFrom の 2 種類を定義しています。 |
| Tracer | スパンを作成し、サービス間でコンテキストを伝播するためのインターフェースです。 |
分散トレーシングが重要な理由
最新のアプリケーションは、開発者がアジャイル開発や継続的インテグレーションなどのメソッドを採用するマイクロサービスアーキテクチャを使用しています。システムアーキテクチャは、スタンドアロンの大規模ソフトウェアからマイクロサービスベースのアーキテクチャへと進化しており、単一のリクエストが多数のサービスを横断する可能性があります。これらのサービスは、異なる言語で記述され、異なるチームによって保守され、複数のサーバーにデプロイされている場合があります。1 つのサービスで障害が発生すると、多数のアプリケーションで例外が発生する可能性があり、エンドツーエンドの可視性なしに根本原因を特定することは非現実的です。
分散トレーシングシステムは、リモートメソッド呼び出しの実行プロセスと時間消費を含む、各リクエストの完全な実行パスとタイミングを記録します。この可視性は、システムの問題のトラブルシューティングとシステムパフォーマンスの最適化に不可欠です。
トレース
トレースは、分散システムにおけるトランザクションまたはプロセスの実行プロセスを表します。OpenTracing 標準では、トレースは複数のスパンで構成される有向非循環グラフ (DAG) です。各スパンは、トレース内で継続的に実行される名前付きで時間指定されたセグメントを表します。
たとえば、クライアントリクエストは、ターゲットリソースに到達して応答を返す前に、ロードバランサー、認証サービス、および課金サービスを通過する場合があります。

トレーシングシステムは通常、これをタイムラインとして表示します。各行はスパンを表し、横軸は時間を表します。

スパン
スパンは、トレース内の単一の作業単位を表します。各スパンには、次のデータが含まれます。
| フィールド | 説明 |
|---|---|
| 操作名 | 実行された作業の人間が判読できるラベル (スパン名とも呼ばれます)。 |
| 開始タイムスタンプ | 操作が開始された時刻。 |
| 終了タイムスタンプ | 操作が完了したとき。 |
| タグ | スパンにアノテーションを付けるキーと値のペア。キーは文字列です。値は文字列、ブール値、または数値にすることができます。 |
| ログ | スパンのライフタイム中にイベントを記録するタイムスタンプ付きキーと値のペア。キーは文字列です。値は任意の型にすることができます。 |
| SpanContext | スパンを識別し、プロセス境界を越えて伝播するためのメタデータです。SpanContext をご参照ください。 |
| リファレンス | 親子関係またはシーケンシャルな関係を確立する他のスパンへのリンク。ゼロまたは複数の関連スパンが含まれる場合があります。 |
スパン間の関係
OpenTracing は、スパン間の 2 種類のリファレンスを定義しています。
ChildOf: 親子関係。たとえば、スパン C はスパン A の子ノードです。
FollowsFrom: シーケンシャルな関係。たとえば、スパン G はスパン F の後に呼び出されます。
次の図は、単一のトレース内の 8 つのスパンとその関係を示しています。
Causal relationships among spans in a single trace
[Span A] <-- root span
|
+------+------+
| |
[Span B] [Span C] (ChildOf: Span C is a child of Span A)
| |
[Span D] +---+-------+
| |
[Span E] [Span F] >>> [Span G] >>> [Span H]
^
|
(FollowsFrom: Span G follows Span F)同じトレースをタイムラインとして表示したものです。
Time relationships among spans in a single trace
--|-------|-------|-------|-------|-------|-------|-------|-> time
[Span A..........................................................]
[Span B...................................................]
[Span D................................................]
[Span C...............................................]
[Span E.......] [Span F..] [Span G..] [Span H..]SpanContext
SpanContext は、スパンを識別し、プロセス境界を越えて伝播するために必要なメタデータを伝達します。これには以下が含まれます。
トレース ID: トレース全体の一意の識別子。
スパン ID: 個々のスパンの一意の識別子。
バゲージ項目: サービス境界を越えてトレースとともに伝達されるキーと値のペア。これらのキーと値のペアは、プロセス境界を越えても送信される必要があります。
Tracer インターフェース
Tracer は、スパンを作成し、サービス間でコンテキストを伝播するためのエントリポイントです。スパンを作成するための StartSpan メソッド、コンテキストを抽出するための Extract メソッド、およびコンテキストを注入するための Inject メソッドを提供します。
スパンの作成
StartSpan メソッドを使用して、新しいスパンを作成および開始します。このメソッドは、指定された操作名とオプションを持つスパンを返します。
// Method signature:
// StartSpan(operationName string, opts ...StartSpanOption) Span
// Create a root span (no parent).
sp := tracer.StartSpan("GetFeed")
// Create a child span.
sp := tracer.StartSpan(
"GetFeed",
opentracing.ChildOf(parentSpan.Context()),
)サービス間でのコンテキストの伝播
サービス間でトレースコンテキストを渡すために、Tracer は 2 つの補完的なメソッドを提供します。
Inject: SpanContext (トレース ID、スパン ID、およびバゲージ項目を含む) を、別のサービスにリクエストを送信する前に、キャリア (HTTP ヘッダーなど) にシリアル化します。
// Method signature: // Inject(sm SpanContext, format interface{}, carrier interface{}) error carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) err := tracer.Inject( span.Context(), opentracing.HTTPHeaders, carrier, )Extract: 別のサービスからリクエストを受信したときに、キャリアから SpanContext (トレース ID、スパン ID、およびバゲージ項目を含む) を逆シリアル化します。
// Method signature: // Extract(format interface{}, carrier interface{}) (SpanContext, error) carrier := opentracing.HTTPHeadersCarrier(httpReq.Header) clientContext, err := tracer.Extract( opentracing.HTTPHeaders, carrier, )
Inject と Extract は連携して、プロセスおよびネットワーク境界を越えたエンドツーエンドのトレーシングを可能にします。
データレポート
Managed Service for OpenTelemetry は、トレースデータをレポートするための 2 つのメソッドをサポートしています。
直接レポート
アプリケーションは、ミドルウェアなしでトレースデータをトレーシングバックエンドに直接送信します。

エージェントを介したレポート
アプリケーションは、トレースデータをローカルエージェント (Jaeger Agent など) に送信し、ローカルエージェントがデータをトレーシングバックエンドに転送します。
