トレーシングSDK
この記事は英語の原文を日本語に翻訳したものです。原文: https://opentelemetry.io/docs/specs/otel/trace/sdk/
翻訳元: open-telemetry/opentelemetry-specification v1.60.0(コミット 29ae8c7)
ステータス: 特記のない限りStable
TracerProvider
Tracerの作成
Tracerインスタンスの作成は、TracerProviderを通じてのみ可能であるべきです(SHOULD)(APIを参照)。
TracerProviderはTracerAPIの取得をMUST実装するものとします。
ユーザーが提供した入力は、作成されたTracer上に保存されるInstrumentationScopeインスタンスを作成するためにMUST使われるものとします。
ステータス: Development - TracerProviderは、設定されたTracerConfiguratorを使って関連するTracerConfigをMUST計算するものとし、そのTracerConfigに準拠して振る舞うTracerをMUST作成するものとします。
設定
設定(すなわちSpanProcessor、IdGenerator、SpanLimits、Sampler、そして(Development)TracerConfigurator)は、TracerProviderによってMUST所有されるものとします。設定は、適切であればTracerProviderの作成時に適用してもかまいません(MAY)。
TracerProviderは、設定を更新するメソッドを提供してもかまいません(MAY)。設定が更新された場合(例えばSpanProcessorを追加する場合)、更新された設定は既に返却済みのすべてのTracerにもMUST適用されるものとします(すなわち、Tracerが設定変更の前後どちらにTracerProviderから取得されたかは問題にならないようにMUSTするものとします)。注: 実装としては、Tracerインスタンスが自身のTracerProviderへの参照を持ち、この参照を通じてのみ設定にアクセスする形が考えられます。
TracerConfigurator
ステータス: Development
TracerConfiguratorは、TracerのTracerConfigを計算する関数です。
この関数は以下のパラメータをMUST受け付けるものとします。
tracer_scope:TracerのInstrumentationScope。
この関数は、関連するTracerConfig、またはデフォルトのTracerConfigを使うべきことを示す何らかのシグナルをMUST返すものとします。このシグナルは、言語にとってイディオマティックな形に応じて、nil、null、空、あるいはデフォルトのTracerConfigのインスタンスでもかまいません(MAY)。
この関数は、Tracerが最初に作成されたときに呼び出され、また(更新がサポートされている場合)TracerProviderのTracerConfiguratorが更新された際には、未終了のすべてのTracerに対して呼び出されます。したがって、この関数が速やかに値を返すことが重要です。
TracerConfiguratorは、柔軟性を最大化するため関数としてモデル化されています。しかし、実装は一般的な使用例に対応するため、簡略な記法やヘルパー関数を提供してもかまいません(MAY)。
- 名前で1つ以上のTracerを選択する(完全一致またはパターンマッチング)。
- 1つ以上の特定のTracerを無効化する。
- すべてのTracerを無効化し、1つ以上の特定のTracerを選択的に有効化する。
Shutdown
このメソッドは、プロバイダーが必要なクリーンアップを行うための手段を提供します。
Shutdownは、TracerProviderインスタンスごとに一度だけMUST呼び出されるものとします。Shutdownの呼び出し後、Tracerを取得しようとする以後の試みは許可されません。SDKは、可能であればこれらの呼び出しに対して有効なno-opのTracerをSHOULD返すものとします。
Shutdownは、呼び出し元に成功・失敗・タイムアウトのいずれであったかを知らせる手段をSHOULD提供するものとします。
Shutdownは、ある程度のタイムアウト内に完了または中断すべきです(SHOULD)。Shutdownは、ブロッキングAPIとして実装しても、コールバックやイベントを通じて呼び出し元に通知する非同期APIとして実装してもかまいません。OpenTelemetryクライアントの実装者は、シャットダウンのタイムアウトを設定可能にするかどうかを決めてかまいません。
Shutdownは、少なくともすべての内部プロセッサー内でShutdownを呼び出すことによってMUST実装されるものとします。
ForceFlush
このメソッドは、プロバイダーがすべての内部プロセッサーについて、まだエクスポートされていないすべてのspanを直ちにエクスポートするための手段を提供します。
ForceFlushは、呼び出し元に成功・失敗・タイムアウトのいずれであったかを知らせる手段をSHOULD提供するものとします。
ForceFlushは、ある程度のタイムアウト内に完了または中断すべきです(SHOULD)。ForceFlushは、ブロッキングAPIとして実装しても、コールバックやイベントを通じて呼び出し元に通知する非同期APIとして実装してもかまいません。OpenTelemetryクライアントの実装者は、フラッシュのタイムアウトを設定可能にするかどうかを決めてかまいません。
ForceFlushは、登録済みのすべてのSpanProcessorに対してForceFlushをMUST呼び出すものとします。
Tracer
ステータス: Development - Tracerは、Tracerの作成時に計算されたTracerConfigに従ってMUST振る舞うものとします。TracerProviderがTracerConfiguratorの更新をサポートする場合、更新時にTracerは新しいTracerConfigに従って振る舞うようMUST更新されるものとします。
TracerConfig
ステータス: Development
TracerConfigは、Tracerの振る舞いに関する様々な設定可能な側面を定義します。これは以下のパラメータから構成されます。
enabled: そのTracerが有効かどうかを示すブール値。明示的に設定されない場合、
enabledパラメータのデフォルトはtrueであるべきです(SHOULD)(すなわち、Tracerはデフォルトで有効になっています)。Tracerが無効化されている場合、それはno-opのTracerと同等にMUST振る舞うものとします。enabledの値は、TracerがEnabledかどうかを解決するためにMUST使われるものとします。enabledがfalseの場合、Enabledはfalseを返します。enabledがtrueの場合、Enabledはtrueを返します。
実装は、これらのパラメータへの変更がEnabledの呼び出し元に即座に反映されることを保証する必要はありません。しかし、変更は最終的にはMUST反映されるものとします。
Enabled
Enabledは、以下のいずれかに該当する場合にfalseをMUST返すものとします。
- 登録済みの
SpanProcessorが存在しない場合。 - ステータス: Development -
Tracerが無効化されている場合(TracerConfig.enabledがfalse)。
それ以外の場合、trueをSHOULD返すものとします。追加の最適化や機能をサポートするためにfalseを返してもかまいません(MAY)。
追加のSpanインターフェース
Spanのインターフェースに関するAPIレベルの定義は、spanへの書き込み専用のアクセスのみを定義しています。これは、計装やアプリケーションがアプリケーションロジックのためにspanに保存されたデータを使うことを意図していないという点で好ましい設計です。しかし、SDKは最終的にどこかの箇所でそのデータを読み戻す必要があります。そのため、SDKの仕様書はSpanに類するパラメータに対して考えられる要件の集合を定義します。
Readable span: これを引数として受け取る関数は、SpanのAPI仕様に列挙されている、そのspanに追加されたすべての情報にMUSTアクセスできるものとします。注: 以下では、明確さのためいくつかの特定のプロパティを取り上げますが、必須プロパティの完全な一覧についてはSpan APIの仕様が正式なものです。
これを引数として受け取る関数は、そのspanに(暗黙的に)関連付けられた
InstrumentationScope([1.10.0以降])とResourceの情報にMUSTアクセスできるものとします。後方互換性のため、InstrumentationScopeと同じ名前・バージョンの値を持つInstrumentationLibrary([1.10.0で非推奨])にもMUSTアクセスできるものとします。これを引数として受け取る関数は、そのSpanが終了しているかどうかを確実にMUST判定できるものとします(一部の言語では、終了タイムスタンプが
nullであることによってこれを実装しているかもしれず、他の言語では明示的なhasEndedブール値を持つかもしれません)。エクスポーターの仕様に記述されている通り、収集の上限によって破棄された属性・イベント・リンクの数は、エクスポーターが報告できるようMUST利用可能であるものとします。
APIの仕様で定義されているspanのプロパティの正式な集合に対する例外として、実装はSpanの親Contextの全体を公開(および保存)しなくてもかまいません(MAY)が、少なくとも親の完全なSpanContextはMUST公開するものとします。
これを引数として受け取る関数は、そのSpanを変更できない場合があります。
注: これは典型的には、新しいインターフェースや(イミュータブルな)値型として実装されます。言語によっては、SpanProcessorはエクスポーターとは異なるreadable span型を持つことがあります(例えば
SpanData型がイミュータブルなスナップショットを含み、ReadableSpanインターフェースはSpanインターフェースが操作する同じ基盤データ構造から直接情報を読み取る場合があります)。Read/write span: これを引数として受け取る関数は、Spanインターフェースに関するAPIレベルの定義で定義されている完全なspan APIと、それに加えて(readable spanと同様に)そのspanに追加されたすべての情報を取得できる能力の両方にアクセスできなければなりません。
これを引数として呼び出される関数は、spanを作成するAPIがユーザーへ返した(あるいは返すことになる)のと同じ
Spanインスタンスおよび型を、何らかの形で取得できることがMUST可能であるものとします(例えば、そのSpanはそうした関数に渡されるパラメータの1つでもよく、あるいはゲッターを提供してもかまいません)。
サンプリング
サンプリングとは、OpenTelemetryがバックエンドへ収集・送信するトレースのサンプル数を減らすことで、ノイズとオーバーヘッドを抑える仕組みです。
サンプリングは、トレース収集の異なる段階で実装される場合があります。最も早い段階のサンプリングは、実際にトレースが作成される前に行われることがあり、最も遅い段階のサンプリングは、プロセス外にあるCollector上で行われることがあります。
OpenTelemetry APIには、データ収集を担う2つのプロパティがあります。
SpanのIsRecordingフィールド。これがfalseの場合、現在のSpanはすべてのトレースデータ(属性、イベント、ステータスなど)を破棄します。ユーザーはこのプロパティを使って、コストの高いトレースデータの収集を避けられるかどうかを判断できます。SpanProcessorは、このフィールドがtrueに設定されたspanのみをMUST受け取るものとします。一方でSpanExporterは、Sampledフラグも設定されていない限りそれらを受け取るべきではありません(SHOULD NOT)。SpanContext上のTraceFlagsにあるSampledフラグ。このフラグはSpanContextを通じて子Spanへ伝搬します。詳細はW3C Trace Context仕様を参照してください。このフラグは、そのSpanがsampled(サンプリング済み)であり、エクスポートされることを示します。SpanExporterは、Sampledフラグがtrueに設定されたspanをMUST受け取るものとし、設定されていないspanはSHOULD NOT受け取るものとします。
SampledFlag == falseかつIsRecording == trueというフラグの組み合わせは、現在のSpanはデータを記録するものの、その子Spanはおそらく記録しないことを意味します。
SampledFlag == trueかつIsRecording == falseというフラグの組み合わせは、分散トレースに欠落を生む可能性があるため、OpenTelemetry SDKはこの組み合わせをMUST NOT許容するものとします。
記録とサンプリングの反応表
以下の表は、IsRecordingとSampledフラグの各組み合わせについて期待される挙動をまとめたものです。
IsRecording | Sampledフラグ | SpanProcessorはspanを受け取るか? | SpanExporterはspanを受け取るか? |
|---|---|---|---|
| true | true | true | true |
| true | false | true | false |
| false | true | 許容されない | 許容されない |
| false | false | false | false |
SDKは、Samplerインターフェースと、組み込みSamplerの集合を定義し、Samplerを各[TracerProvider]に関連付けます。
SDKによるSpan作成
Spanの作成を求められたとき、SDKは以下を順番に行っているかのようにMUST動作するものとします。
- 有効な親トレースIDが存在する場合はそれを使います。存在しない場合は新しいトレースIDを生成します(注: これは
ShouldSampleの呼び出しより前に行う必要があります。ShouldSampleは入力として有効なトレースIDを想定するためです)。 SamplerのShouldSampleメソッドに問い合わせます。- サンプリング判断とは独立に、その
Spanに対して新しいspan IDを生成します。これは、Spanが非記録のインスタンスであっても、他のコンポーネント(ログや例外処理など)が一意なspan IDに依拠できるようにするためです。 ShouldSampleが返した判断に応じてspanを作成します。IsRecordingとSampledをSpanにどう設定するかについては、以下のShouldSampleの返り値に関する説明を、SpanProcessorにそのSpanを渡すかどうかについては、上の表を参照してください。非記録のspanは、SDKがインストールされていない場合にSpanが作成されるときと同じ機構、あるいはSpanContextのSpanへのラッピングに記述された方法で実装してもかまいません(MAY)。
Spanフラグ
SpanおよびSpan LinkのOTLP表現には、Span Flagsと呼ばれる32ビットのフィールドが含まれます。
Span Flagsフィールドのビット0〜7(下位8ビット)は、W3C Trace Context Level 2 Candidate Recommendationで規定されているTrace Contextフラグの8ビットのために予約されています。 認識されるフラグの一覧を参照してください。
Sampler
Samplerインターフェースを使うと、ユーザーは、Spanが作成される直前に一般的に利用可能な情報に基づいてサンプリング結果SamplingResultを返すカスタムサンプラーを作成できます。
ShouldSample
これから作成されるSpanに対するサンプリングのDecisionを返します。
必須の引数:
- 親
Spanを持つContext。このSpanのSpanContextは、ルートspanを示すために無効であることがあります。 - 作成される
SpanのTraceId。親SpanContextが有効なTraceIdを含む場合、それらはMUST常に一致するものとします。 - 作成される
Spanの名前。 - 作成される
SpanのSpanKind。 - 作成される
Spanの初期のAttributesの集合。 - 作成される
Spanに関連付けられるリンクのコレクション。これはバッチ処理に対して典型的に有用です。Spans間のリンクを参照してください。
注: 実装は、すべてまたは複数の引数を単一のオブジェクトに「まとめて」もかまいません。
返り値:
これはSamplingResultと呼ばれる出力を生成し、以下を含みます。
- サンプリングの
Decision。以下の列挙値のいずれかです。DROP-IsRecordingはfalseになり、そのSpanは記録されず、すべてのイベントと属性が破棄されます。RECORD_ONLY-IsRecordingはtrueになりますが、SampledフラグはMUST NOT設定されるものとします。RECORD_AND_SAMPLE-IsRecordingはtrueになり、SampledフラグはMUST設定されるものとします。
Spanにも追加されるspan属性の集合。返されるオブジェクトはイミュータブルでなければなりません(複数回の呼び出しが異なるイミュータブルなオブジェクトを返すことがあります)。- 新しい
SpanContextを通じてそのSpanに関連付けられるTracestate。サンプラーがここで空のTracestateを返した場合、Tracestateはクリアされるため、変更を意図していないサンプラーは通常、渡されたTracestateをそのままSHOULD返すものとします。
GetDescription
サンプラーの名前、または設定を含む短い説明を返します。これはデバッグページやログに表示されることがあります。例: "TraceIdRatioBased{0.000100}"。
説明は、例えばサンプラーが動的な設定をサポートしていたり、パラメータを別の方法で調整したりする場合には、時間とともに変化してもかまいません(MAY)。呼び出し元は、返された値をキャッシュすべきではありません(SHOULD NOT)。
組み込みSampler
OpenTelemetryは、選択可能な複数の組み込みサンプラーをサポートしています。デフォルトのサンプラーはParentBased(root=AlwaysOn)です。
AlwaysOn
- 常に
RECORD_AND_SAMPLEを返します。 - 説明は
AlwaysOnSamplerでなければなりません(MUST)。
AlwaysOff
- 常に
DROPを返します。 - 説明は
AlwaysOffSamplerでなければなりません(MUST)。
TraceIdRatioBased
ステータス: Stable
TraceIdRatioBasedサンプラーは、コンポーザブルなProbabilitySamplerを優先する形で非推奨になっています。このコンポーネントは、1.0のトレース仕様書における「TODO」に対応するために段階的に廃止されています。OpenTelemetry SDKの実装者は、少なくとも2027年1月1日までは、既存のTraceIdRatioBasedサンプラーの振る舞いを削除・変更してはなりません(SHALL NOT)。その時点で、SDKの実装者は、TraceIdRatioBasedの設定を同等の設定を持つProbabilitySamplerへ黒子で置き換えることが推奨されます。
TraceIdRatioBasedは、親のSampledFlagをMUST無視するものとします。親のSampledFlagを尊重するには、以下で指定するParentBasedサンプラーのデリゲートとしてTraceIdRatioBasedを使うべきです。- 説明は、
RATIOをSamplerインスタンスのトレースサンプリング比率を表す小数値に置き換えた"TraceIdRatioBased{RATIO}"という形式の文字列をMUST返すものとします。数値の精度は実装言語の標準に従うべきであり(SHOULD)、Samplerが異なる比率を持つことを識別できるよう十分に高くあるべきです(SHOULD)。例えば、10,000スパンにつき1つというサンプリング比率を持つTraceIdRatioBased Samplerは、説明として"TraceIdRatioBased{0.000100}"を返すことができます(COULD)。
TraceIdRatioBasedサンプラーアルゴリズムの要件
ステータス: Stable
- サンプリングアルゴリズムは決定的でなければなりません(MUST)。与えられた
TraceIdによって識別されるトレースは、言語や時間などに関わらずサンプリングされるかされないかが決まります。これを実現するため、実装はサンプリング判断を計算する際にTraceIdの決定的なハッシュをMUST使うものとします。これを保証することで、任意の子Spanに対してサンプラーを実行しても同じ判断が得られます。 - あるサンプリング確率を持つ
TraceIdRatioBasedサンプラーは、それより低いサンプリング確率を持つ任意のTraceIdRatioBasedサンプラーがサンプリングするすべてのトレースもMUSTサンプリングするものとします。これは、バックエンドシステムがフロントエンドシステムよりも高いサンプリング確率で動作させたい場合に重要です。この方法により、フロントエンドのすべてのトレースは依然としてサンプリングされ、追加のトレースはバックエンドでのみサンプリングされます。
TraceIdRatioBasedサンプラーの互換性に関する警告
ステータス: Development
警告: 正確なアルゴリズムは一度も規定されたことがありません。このサンプラーは、他のいかなるSDKとも互換性を持つように定義されていないため、不安定であると見なされます。設定と作成のAPIのみが安定しています。異なる言語のSDK、あるいは同じ言語のSDKの異なるバージョンでも、同じ入力に対して一貫しない結果を生成することがあるため、このサンプラーアルゴリズムはルートspanに対してのみ(ParentBasedと組み合わせて)使うことが推奨されます。
このサンプラーが空でない親のspanコンテキストを観測した場合、つまりルートサンプラーとして使われていない場合、SDKは以下のような警告を発するべきです(SHOULD)。
WARNING: The TraceIdRatioBased sampler is operating as a child sampler;
the behavior is subject to change. Please upgrade this SDK configuration
to use ProbabilitySampler.
このような場面では、このサンプラーはthまたはrvサブキーを持つOpenTelemetryのtracestate(ot=...)をTracestate内で検査することによってProbabilitySamplerの使用を検出することもでき、その場合警告はより直接的なものになってもかまいません(MAY)。
WARNING: The TraceIdRatioBased sampler is operating as a child sampler
and a parent is using ProbabilitySampler. Please upgrade this SDK configuration
to use ProbabilitySampler.
ProbabilitySampler
ステータス: Development
ProbabilitySamplerは、W3C Trace Context Level 2 Candidate Recommendationで規定されたランダム性の機能を使って、単純な比率ベースの確率的サンプリングを実装します。OpenTelemetryは、56ビットのランダム性を規定するW3C Trace Context Level 2に従い、56ビットのランダム性を使って一貫した確率サンプリングの判断を行う方法を規定しています。
ProbabilitySamplerサンプラーは、親のSampledFlagをMUST無視するものとします。親のSampledFlagを尊重する方法については、以下で指定するParentBasedサンプラーを参照してください。
これは非コンポーザブルな形式の確率サンプラーであることに注意してください。ProbabilitySamplerはSDKのSampler APIを直接実装しますが、ComposableProbabilityはCompositeSamplerで使うためのコンポーザブルな形式です。
ProbabilitySamplerサンプラーの設定
ProbabilitySamplerサンプラーは通常、サンプリング比率を表現するために32ビットまたは64ビットの浮動小数点数を使って設定されます。有効な最小サンプリング比率は2^-56で、有効な最大サンプリング比率は1.0です。入力されたサンプリング比率から棄却しきい値の値が計算されます。可変精度でサンプリング比率をしきい値に変換する詳細については、一貫した確率サンプラーの要件を参照してください。
ProbabilitySamplerサンプラーアルゴリズム
サンプリングしきい値Tとランダム性の値R(典型的には、トレースIDの右端7バイト)を持つContextで設定されたSamplerに対してShouldSample()が呼び出されると、R >= Tという式を使ってRECORD_AND_SAMPLEまたはDROPのいずれを返すかを判断します。
- ランダム性の値(R)が棄却しきい値(T)以上である場合、すなわち(R >= T)である場合は
RECORD_AND_SAMPLEを返し、そうでない場合はDROPを返します。 - (R >= T)である場合、OpenTelemetry TraceStateの
thサブキーで規定されている通り、OpenTelemetryのTraceStateは棄却しきい値の値(T)を表すキーバリューth:Tを含むよう変更されるべきです(SHOULD)。
ProbabilitySamplerの互換性に関する警告
ProbabilitySamplerがTraceIDのランダム性に基づいて非ルートSpanの判断を下す場合、そのTraceIDが実際にはこの仕様書を認識していない古いSDKによって生成されたものである可能性があります。Trace randomフラグは、この2つのケースを区別できるようにします。このフラグは、TraceIDがランダムであることをProbabilitySampler Samplerが確認できるようにする情報を伝えますが、これにはそのコンテキストを扱ったすべてのTrace SDKがW3C Trace Context Level 2をサポートしていることが必要です。
ProbabilitySampler Samplerが、Trace randomフラグが設定されていないときにTraceIDのランダム性を使って非ルートSpanの判断を下す場合、SDKはそのログに互換性に関する警告文をSHOULD発行するものとします。この互換性の警告の例を示します。
WARNING: The ProbabilitySampler sampler is presuming TraceIDs are random
and expects the Trace random flag to be set in confirmation. Please
upgrade your caller(s) to use W3C Trace Context Level 2.
ParentBased
- これはサンプラーデコレーターです。
ParentBasedは以下のケースを区別する助けになります。- 親がない(ルートspan)。
SampledFlagが設定されているリモートの親(SpanContext.IsRemote() == true)。SampledFlagが設定されていないリモートの親(SpanContext.IsRemote() == true)。SampledFlagが設定されているローカルの親(SpanContext.IsRemote() == false)。SampledFlagが設定されていないローカルの親(SpanContext.IsRemote() == false)。
必須パラメータ:
root(Sampler)- 親を持たないspan(ルートspan)に対して呼び出されるSampler。
任意パラメータ:
remoteParentSampled(Sampler)(デフォルト: AlwaysOn)remoteParentNotSampled(Sampler)(デフォルト: AlwaysOff)localParentSampled(Sampler)(デフォルト: AlwaysOn)localParentNotSampled(Sampler)(デフォルト: AlwaysOff)
| 親 | parent.isRemote() | parent.IsSampled() | 呼び出されるサンプラー |
|---|---|---|---|
| 存在しない | n/a | n/a | root() |
| 存在する | true | true | remoteParentSampled() |
| 存在する | true | false | remoteParentNotSampled() |
| 存在する | false | true | localParentSampled() |
| 存在する | false | false | localParentNotSampled() |
JaegerRemoteSampler
Jaeger remote samplerは、SDKのサンプリング設定をリモートから制御できるようにします。サンプリング設定はバックエンドから定期的に読み込まれ(Remote Sampling APIを参照)、そこでは運用担当者が設定ファイルを通じて管理することも、自動的に計算させることもできます(Adaptive Samplingを参照)。remote samplerが取得したサンプリング設定は、サービス全体に対して単一のサンプリング方式(例えばTraceIdRatioBased)を使うよう指示することも、エンドポイント(span名)ごとに異なる方式を使うよう指示することもできます。例えば、/productエンドポイントは10%、/adminエンドポイントは100%でサンプリングし、/metricsエンドポイントは決してサンプリングしない、といった指定です。
完全なprotobufの定義はjaegertracing/jaeger-idl/api_v2/sampling.protoにあります。
サンプラーを作成する際、以下の設定プロパティが利用可能であるべきです。
- endpoint - Jaeger CollectorやOpenTelemetry Collectorなど、Remote Sampling APIを実装するサービスのアドレス。
- polling interval - リモートから設定を取得するポーリング間隔。
- initial sampler - 最初の設定が取得される前に使われる初期サンプラー。
AlwaysRecord
AlwaysRecordは、通常であれば破棄されるspanも含め、すべてのspanがSpanProcessorに渡されることを保証するサンプラーデコレーターです。これは、ラップされたサンプラーからのDROP判断をRECORD_ONLY判断へ変換することで実現されており、プロセッサーはエクスポーターへ送信することなくすべてのspanを見られるようになります。これは典型的には、正確なspanからメトリクスへの処理を可能にするために使われます。
ラップされたルートサンプラーからの判断に基づいて、AlwaysRecordは以下のようにMUST振る舞うものとします。
| ルートサンプラーの判断 | AlwaysRecordの判断 |
|---|---|
DROP | RECORD_ONLY |
RECORD_ONLY | RECORD_ONLY |
RECORD_AND_SAMPLE | RECORD_AND_SAMPLE |
必須パラメータ:
root(Sampler)- ラップされるサンプラー。AlwaysRecordが変更する元のサンプル・破棄の判断を提供します。
CompositeSampler
ステータス: Development
CompositeSamplerは標準のSamplerインターフェースを実装しますが、その判断を行うために複数のサンプラーの合成を使います。
CompositeSamplerはComposableSamplerを入力として受け取り、最終的なサンプリング判断を助けるデリゲートとして使います。Consistent Probability Samplingの基本についてはTraceStateにおける確率サンプリングを参照してください。
ShouldSampleの呼び出しに応じて最終的なSamplingResultを構築する処理は、以下の手順から構成されます。
- サンプラーはデリゲート(以下のComposableSamplerを参照)に対して
GetSamplingIntentを呼び出します。 - 受け取ったTHRESHOLD値が
nullである場合、サンプリング判断はDROPになります。それ以外の場合、 - サンプラーは受け取った
adjusted_count_reliableを確認し、trueである場合はランダム性の値(R)に記述された通りTraceStateまたはTraceIdからランダム性の値Rを導出し、falseである場合は新しいランダムな56ビットの数値を16進エンコードして新しいランダム性の値Rを生成します。 - サンプラーは、受け取ったTHRESHOLD値とランダム性の値Rを(実装によって辞書式順序またはその他の方法で)比較し、判断アルゴリズムに記述された通り最終的なサンプリングの
Decisionを導出します。 - サンプラーは、親の
Tracestateと最終的なサンプリングのDecisionを渡して受け取ったtrace_state_provider関数を呼び出し、そのSpanに関連付ける新しいTracestateを取得します。 - サンプリング判断が肯定的な場合、
- サンプラーは受け取った
attributes_provider関数を呼び出し、Spanに追加するAttributesの集合を決定します。 adjusted_count_reliableがtrueである場合、受け取ったTHRESHOLDに従ってTracestateのotキーのth値を変更します。返された値がfalseだった場合は、Tracestateのotキーからth値を削除します。
- サンプラーは受け取った
- サンプリング判断が否定的な場合、
Tracestateのotキーからth値を削除します。
ComposableSampler
ComposableSamplerは、CompositeSamplerによって使われる特化されたインターフェースです。これは、複数のサンプラーが協調してサンプリング判断を行えるようにするGetSamplingIntentという新しいメソッドを定義することで、コンポーザブルなアプローチをサンプリングにもたらします。
GetSamplingIntent
Spanをサンプリングすることに関するサンプラーの意向を示す、実際に最終判断を下すことなくSamplingIntent構造体を返します。
必須の引数:
traceIdを除く、元のSampler APIのすべてのパラメータが含まれます。- 親コンテキスト、しきい値、着信のtrace state、trace flagの情報は、ComposableSamplerがこの情報を得るためにContextを繰り返し調べる必要がないよう、事前に計算されている場合があります(MAY)。
注: ComposableSamplerは、デリゲートのGetSamplingIntentメソッドに渡されたパラメータを変更してはなりません(MUST NOT)。それらは読み取り専用の状態と見なされます。
返り値:
このメソッドは、以下の要素を持つSamplingIntent構造体を返します。
threshold- サンプリングしきい値。しきい値が低いほどサンプリングされる可能性が高くなります。adjusted_count_reliable- Spanからメトリクスへの推定のためにそのしきい値を信頼できる形で使えるかどうかを示すブール値。attributes_provider- サンプリングされた場合にspanに追加される属性の任意のプロバイダー。trace_state_provider- 変更されたTraceStateの任意のプロバイダー。
trace_state_providerが複雑さの大きな要因になりうることに注意してください。ComposableSamplerは、OpenTelemetryのTraceState(すなわちTraceStateのotサブキー)をMUST NOT変更するものとします。呼び出し元のCompositeSamplerは、上述の通り送信するTraceStateのしきい値をSHOULD更新するものとします。明示的なランダム性の値は変更してはなりません(MUST)。
組み込みComposableSampler
ComposableAlwaysOn
- すべてのspanをサンプリングするしきい値(threshold = 0)を持つ
SamplingIntentを常に返します。 adjusted_count_reliableをtrueに設定します。- 属性を追加しません。
ComposableAlwaysOff
- すべてのspanが破棄されるべきことを示す、しきい値を持たない
SamplingIntentを常に返します。 adjusted_count_reliableをfalseに設定します。- 属性を追加しません。
ComposableProbability
- 設定されたサンプリング比率によって決まるしきい値を持つ
SamplingIntentを返します。 adjusted_count_reliableをtrueに設定します。- 属性を追加しません。
必須パラメータ:
ratio- サンプリングの望ましい確率を表す、2^-56から1.0(両端を含む)までの値。
比率の値が0の場合、非確率的であると見なされます。この0のケースでは、代わりにComposableAlwaysOffインスタンスをSHOULD返すものとします。
トップレベルのProbabilitySamplerはComposite(ComposableProbability(ratio))という設定を使って実装できることに注意してください。
ComposableParentThreshold
- 親コンテキストを持たないspanについては、ルートサンプラーに委譲します。
- 親コンテキストを持つspanについては、親のサンプリング判断を伝える
SamplingIntentを返します。 - 利用可能であれば親のしきい値を返します。そうでなく親のsampledフラグが設定されている場合はthreshold=0を返します。そうでなく親のsampledフラグが設定されていない場合、しきい値は返されません。
adjusted_count_reliableを親の信頼性に一致させて設定します。これは、親がしきい値を持っていた場合にtrueになります。- 属性を追加しません。
必須パラメータ:
root- 親コンテキストを持たないspanをサンプリングするためのデリゲート。
ComposableRuleBased
- 述語に基づく一連のルールを評価し、最初に一致したサンプラーからの
SamplingIntentを返します。 - いずれのルールも一致しない場合、サンプリングしない意向を返します。
必須パラメータ:
rules- (Predicate, ComposableSampler)のペアのリスト。Predicateはそのルールが適用されるかどうかを評価する関数です。
ComposableAnnotating
- サンプリング判断を別のサンプラーに委譲しますが、サンプリングされたspanに属性を追加します。
- デリゲートのしきい値と追加の属性を組み合わせた
SamplingIntentを返します。
必須パラメータ:
attributes- サンプリングされたspanに追加する属性。delegate- 実際のサンプリング判断を行う基盤となるサンプラー。
設定例:
複合サンプラーの設定を作成する例です。
// Create a rule-based sampler for root spans
rootSampler = ComposableRuleBased([
(isHealthCheck, ComposableAlwaysOff),
(isCheckout, ComposableAlwaysOn),
(isAnything, ComposableTraceIDRatio(0.1))
])
// Create a parent-based sampler for child spans
finalSampler = ComposableParentThreshold(rootSampler)
この例は以下のような設定を作成します。
- ヘルスチェックのエンドポイントは決してサンプリングされません。
- checkoutのエンドポイントは常にサンプリングされます。
- その他のルートspanは10%でサンプリングされます。
- 子spanは親のサンプリング判断に従います。
サンプリングの要件
ステータス: Development
W3C Trace Context Level 2 Candidate Recommendationには、統計的な目的のためにTraceIDが56ビットのランダムな値を含むことを示すRandom trace flagが含まれています。このフラグは、TraceIDの最下位(「右端」)7バイト、すなわち56ビットがランダムであることを示します。
このRandomフラグは、そのフラグを認識しないTrace Context Level 1の実装を通じては伝搬しないことに注意してください。このフラグが1の場合、それは意味を持つと見なされます。このフラグが0の場合、TraceIDがランダムでないことが原因であることもあれば、Trace Context Level 1のpropagatorが使われたことが原因であることもあります。このような状況やその他のTraceIDが十分なランダム性を欠く状況でサンプリングを可能にするため、OpenTelemetryはW3C TraceStateフィールド内にエンコードされる任意の明示的なランダム性の値を定義しています。
本仕様書は、TraceIDのランダム性または明示的なランダム性のいずれかを使うことを推奨しており、これによりW3C Trace Contextの伝搬を使う際にサンプラーが常に十分なランダム性を持つことが保証されます。
TraceIDのランダム性
ルートspanのコンテキストについて、SDKはTraceIDの値を生成する際にW3C Trace Context Level 2 Candidate RecommendationのTraceIDランダム性要件をSHOULD実装するものとします。
Randomトレースフラグ
ルートspanのコンテキストについて、SDKはW3C Trace Context Level 2のランダム性要件を満たすTraceIDを生成する際、trace flagsのRandomフラグをSHOULD設定するものとします。
明示的なランダム性
明示的なランダム性とは、APIの利用者とSDKの実装者がトレースのランダム性を制御できるようにする仕組みです。以下の推奨事項は、上述のTraceIDランダム性に関する推奨を無視したTrace SDKに適用されます。これには2つの部分があります。
明示的なランダム性を上書きしない
APIの利用者はルートspanの初期TraceStateを制御するため、OpenTelemetry TraceStateのrvサブキーを定義することで、そのトレースの明示的なランダム性を提供できます。SDKとSamplerは、OpenTelemetry TraceStateの値における明示的なランダム性をMUST NOT上書きするものとします。
ルートサンプラーは非ランダムなTraceIDに対して明示的なランダム性を設定する
SDKがW3C Trace Context Level 2のランダム性要件を満たさないTraceIDを生成した場合(未設定のtrace randomフラグによって示されます)、かつOpenTelemetry TraceStateのrvサブキーがまだ設定されていない場合、Root samplerには明示的なランダム性の値を挿入する機会があります。
Root Samplerは、明示的なランダム性の値がまだ設定されていない場合に、OpenTelemetry TraceStateの値へ明示的なランダム性の値を挿入してもかまいません(MAY)。
例えば、以下は非ランダムな識別子と明示的なランダム性の値を持つW3C Trace Contextです。
traceparent: 00-ffffffffffffffffffffffffffffffff-ffffffffffffffff-00
tracestate: ot=rv:7479cfb506891d
TraceIDのランダム性の推定
すべてのspanのコンテキストについて、OpenTelemetryのサンプラーは、OpenTelemetry TraceStateのrvサブキーに明示的なランダム性の値が存在しない限り、TraceIDがW3C Trace Context Level 2のランダム性要件を満たしているとSHOULD推定するものとします。
IdGeneratorのランダム性
SDKがIdGenerator拡張ポイントを使う場合、SDKは新しいIDが生成される際にRandomフラグを設定するかどうかをその拡張が決定できるようSHOULD許容するものとします。
Spanの上限
Spanの属性は、属性の上限に関する共通のルールにMUST従うものとします。
SDKのSpanは、設定された上限を超えて各コレクションの要素数を増やすことになるリンクやイベントを破棄してもかまいません(MAY)。
SDKが上記の上限を実装する場合、Javaの例のように個々の上限をユーザーが設定できるようにすることで、TracerProviderへの設定を通じてこれらの上限を変更する方法をMUST提供するものとします。
設定オプションの名前はEventCountLimitとLinkCountLimitであるべきです(SHOULD)。これらのオプションはクラスにまとめてもかまいません(MAY)。その場合、そのクラスはSpanLimitsとSHOULD呼ばれるものとします。実装は、AttributePerEventCountLimitやAttributePerLinkCountLimitのような追加の設定を提供してもかまいません(MAY)。
public final class SpanLimits {
SpanLimits(int attributeCountLimit, int linkCountLimit, int eventCountLimit);
public int getAttributeCountLimit();
public int getAttributeCountPerEventLimit();
public int getAttributeCountPerLinkLimit();
public int getEventCountLimit();
public int getLinkCountLimit();
}
設定可能なパラメータ:
- 属性に適用可能なすべての共通オプション
EventCountLimit(デフォルト=128) - 許容されるspanイベント数の最大値。LinkCountLimit(デフォルト=128) - 許容されるspanリンク数の最大値。AttributePerEventCountLimit(デフォルト=128) - spanイベントごとに許容される属性数の最大値。AttributePerLinkCountLimit(デフォルト=128) - spanリンクごとに許容される属性数の最大値。
属性、イベント、またはリンクがこのような上限によって破棄されたことをユーザーに示すメッセージが、SDKのログにSHOULD出力されるものとします。過剰なログ出力を防ぐため、このメッセージはspanごとに最大一度だけMUST出力されるものとします(すなわち、破棄された属性・イベント・リンクごとではありません)。
IDジェネレーター
SDKはデフォルトでTraceIdとSpanIdの両方をランダムにMUST生成するものとします。
SDKは、TraceIdとSpanIdの両方についてIDの生成方法をカスタマイズする仕組みをMUST提供するものとします。
SDKは、以下のJavaの例のようなインターフェース(このインターフェースの名前はIdGeneratorでもかまいません(MAY)。メソッドの名前はSpanContextと一致していなければなりません(MUST))のカスタム実装を許容することで、この機能を提供してもかまいません(MAY)。これは、SpanIdを生成するためのメソッドとTraceIdを生成するためのメソッドの、2つの拡張ポイントを提供します。
public interface IdGenerator {
byte[] generateSpanIdBytes();
byte[] generateTraceIdBytes();
}
AWS X-RayのトレースID生成器のようなベンダー固有のプロトコルを実装する追加のIdGeneratorは、OpenTelemetryのコアパッケージの一部としてMUST NOT保守・配布されるものとします。
IdGeneratorのランダム性
ステータス: Development
IdGeneratorのカスタム実装は、生成されるすべてのTraceIDの値がW3C Trace Context Level 2のランダム性要件を満たす場合、関連するTraceコンテキストでTraceのrandomフラグが設定されるよう、適切に自身を識別すべきです(SHOULD)。これはIdGenerator実装の静的なプロパティであると想定され、例えばマーカーインターフェースを拡張するといった言語機能を使って推論できます。
SpanProcessor
SpanProcessorは、span開始・終了メソッドの呼び出しに対してフックできるようにするインターフェースです。span processorは、IsRecordingがtrueである場合のみ呼び出されます。
組み込みのSpanProcessorは、spanのバッチ処理とエクスポート可能な表現への変換を担い、バッチをエクスポーターに渡します。
SpanProcessorはSDKのTracerProvider上に直接登録でき、登録された順序と同じ順序で呼び出されます。
TracerProviderに登録された各プロセッサーは、span processorと任意のエクスポーターから構成されるパイプラインの起点です。SDKは、各パイプラインを個別のエクスポーターで終端させることをMUST許容するものとします。
SDKは、ユーザーがカスタムプロセッサーを実装・設定することをMUST許容するものとします。
以下の図は、SpanProcessorとSDK内の他のコンポーネントとの関係を示しています。
+-----+--------------+ +-------------------------+ +----------------+
| | | | | | |
| | | | Batching Span Processor | | SpanExporter |
| | +---> Simple Span Processor +---> (OTLPExporter) |
| | | | | | |
| SDK | Span.start() | +-------------------------+ +----------------+
| | Span.end() |
| | |
| | |
| | |
| | |
+-----+--------------+
インターフェース定義
SpanProcessorインターフェースは以下のメソッドをMUST宣言するものとします。
SpanProcessorインターフェースは以下のメソッドをSHOULD宣言するものとします。
- OnEndingメソッド。
OnStart
OnStartは、spanが開始されたときに呼び出されます。このメソッドは、そのspanを開始したスレッド上で同期的に呼び出されるため、ブロックしたり例外をスローしたりすべきではありません。複数のSpanProcessorが登録されている場合、それらのOnStartコールバックは登録された順序で呼び出されます。
パラメータ:
span- 開始されたspanに対するread/write span object。このspanオブジェクトへの参照を保持でき、そのspanへの更新はそこに反映されるべきです(SHOULD)。例えば、これはバックグラウンドスレッドからすべてのアクティブなspanに関する情報を定期的に評価・出力するSpanProcessorを作成する際に有用です。parentContext- SDKが決定した、そのspanの親Context(明示的に渡されたContext、現在のContext、または明示的に要求された場合の空のContext)。
戻り値: Void
OnEnding
ステータス: Development
OnEndingは、spanのEnd()操作の中で呼び出されます。終了タイムスタンプはMUST計算済みでなければなりません(OnEndingメソッドの処理時間はspanの継続時間には含まれません)。OnEndingが呼び出されている間、Spanオブジェクトは依然としてMUST可変であるものとします(すなわち、SetAttribute、AddLink、AddEventを呼び出せます)。このメソッドはSpan.End() APIの中で同期的にMUST呼び出されるものとし、したがってブロックしたり例外をスローしたりすべきではありません。複数のSpanProcessorが登録されている場合、それらのOnEndingコールバックは登録された順序で呼び出されます。SDKは、最初のSpanProcessorのOnEndingを呼び出す前に、そのspanが他のいかなるスレッドによっても変更され得なくなっていることをMUST保証するものとします。それ以降、変更は呼び出されたOnEndingコールバックの内部からのみ同期的に許可されます。登録されたすべてのSpanProcessorのOnEndingコールバックは、いずれのSpanProcessorのOnEndコールバックが呼び出されるより前に実行されます。
パラメータ:
span- まさに終了しようとしているspanに対するread/write span object。
戻り値: Void
OnEnd(Span)
OnEndは、spanが終了した後(すなわち終了タイムスタンプが既に設定された後)に呼び出されます。このメソッドはSpan.End() APIの中で同期的にMUST呼び出されるものとし、したがってブロックしたり例外をスローしたりすべきではありません。
パラメータ:
Span- 終了したspanに対するreadable span object。注: 渡されたSpanが技術的には書き込み可能であっても、この時点では既に終了しているため、それを変更することは許可されません。
戻り値: Void
Shutdown()
プロセッサーをシャットダウンします。SDKがシャットダウンされる際に呼び出されます。これはプロセッサーが必要なクリーンアップを行う機会です。
Shutdownは、SpanProcessorインスタンスごとに一度だけSHOULD呼び出されるものとします。Shutdownの呼び出し後、OnStart・OnEnd・ForceFlushへの以後の呼び出しは許可されません。SDKは可能であればこれらの呼び出しを穏やかにSHOULD無視するものとします。
Shutdownは、呼び出し元に成功・失敗・タイムアウトのいずれであったかを知らせる手段をSHOULD提供するものとします。
ShutdownはForceFlushの効果をMUST含むものとします。
Shutdownは、ある程度のタイムアウト内に完了または中断すべきです(SHOULD)。Shutdownは、ブロッキングAPIとして実装しても、コールバックやイベントを通じて呼び出し元に通知する非同期APIとして実装してもかまいません。OpenTelemetryクライアントの実装者は、シャットダウンのタイムアウトを設定可能にするかどうかを決めてかまいません。
ForceFlush()
これは、ForceFlushの呼び出しより前にSpanProcessorが既にイベントを受け取っていたSpanに関連するすべてのタスクが、できる限り早く、望ましくはこのメソッドから戻る前に完了しているべきことを示すヒントです(SHOULD)。
特に、SpanProcessorに関連付けられたエクスポーターがある場合、まだ完了していないすべてのspanについてエクスポーターのExportを呼び出し、その後ForceFlushをそのエクスポーターに対して呼び出そうとSHOULD試みるものとします。組み込みのSpanProcessorはこれをMUST行うものとします。タイムアウトが指定されている場合(下記参照)、SpanProcessorはこの目標を達成するため、すべての呼び出しを完了させることよりもタイムアウトを守ることをMUST優先するものとします。この目標を達成するために、一部または全部のExportやForceFlushの呼び出しをスキップまたは中断してもかまいません(MAY)。
ForceFlushは、呼び出し元に成功・失敗・タイムアウトのいずれであったかを知らせる手段をSHOULD提供するものとします。
ForceFlushは、プロセスを中断させてから完了したspanをエクスポートする前にプロセスを停止させてしまう可能性のある一部のFaaSプロバイダーを使う場合など、絶対に必要な場合に限りSHOULD呼び出されるものとします。
ForceFlushは、ある程度のタイムアウト内に完了または中断すべきです(SHOULD)。ForceFlushは、ブロッキングAPIとして実装しても、コールバックやイベントを通じて呼び出し元に通知する非同期APIとして実装してもかまいません。OpenTelemetryクライアントの実装者は、フラッシュのタイムアウトを設定可能にするかどうかを決めてかまいません。
組み込みSpanProcessor
標準のOpenTelemetry SDKは、以下に記述するシンプルなプロセッサーとバッチプロセッサーの両方をMUST実装するものとします。その他の一般的な処理シナリオは、まずOpenTelemetry Collectorでプロセス外で実装することを検討すべきです。
シンプルなSpanProcessor
これは、終了したspanを渡し、終了したspanをそのままエクスポートに適した表現に変換して設定済みのSpanExporterへ渡すSpanProcessorの実装です。
このプロセッサーは、SpanExporterのExportへの呼び出しが並行して呼び出されないよう、それらの呼び出しをMUST同期するものとします。
設定可能なパラメータ:
exporter- spanが送られるエクスポーター。
バッチ処理を行うSpanProcessor
これは、終了したspanのバッチを作成し、そのエクスポートに適した表現を設定済みのSpanExporterへ渡すSpanProcessorの実装です。
このプロセッサーは、SpanExporterのExportへの呼び出しが並行して呼び出されないよう、それらの呼び出しをMUST同期するものとします。
このプロセッサーは、以下のいずれかが起こり、かつ直前のexport呼び出しが既に返っている場合にバッチをSHOULDエクスポートするものとします。
- プロセッサーが構築されてから、または最初のspanがそのspan processorに受け取られてから
scheduledDelayMillisが経過したとき。 - 直前のexportタイマーが終了してから、または直前のexportが完了してから、あるいは直前のexportタイマーの終了後もしくは直前のバッチの完了後に最初のspanがキューに追加されてから
scheduledDelayMillisが経過したとき。 - キューに
maxExportBatchSize個以上のspanが含まれているとき。 ForceFlushが呼び出されたとき。
exportが発生した時点でキューが空である場合、プロセッサーは空のバッチをエクスポートしても、エクスポートをスキップして直ちに完了したものとみなしてもかまいません(MAY)。
設定可能なパラメータ:
exporter- spanが送られるエクスポーター。maxQueueSize- 最大のキューサイズ。このサイズに達すると、spanは破棄されます。デフォルト値は2048です。scheduledDelayMillis- 連続する2回のexportの間の最大の遅延間隔(ミリ秒)。デフォルト値は5000です。exportTimeoutMillis- exportがキャンセルされるまでに実行できる時間。デフォルト値は30000です。maxExportBatchSize- 1回のexportあたりの最大バッチサイズ。maxQueueSize以下でなければなりません。キューがmaxExportBatchSizeに達すると、scheduledDelayMillisミリ秒が経過していなくてもバッチがエクスポートされます。デフォルト値は512です。
SpanExporter
SpanExporterは、OpenTelemetry SDKにプラグインしてテレメトリーデータの送信をサポートするために、プロトコル固有のエクスポーターが実装しなければならないインターフェースを定義します。
このインターフェースの目的は、プロトコルに依存するテレメトリーエクスポーターの実装の負担を最小化することです。プロトコルエクスポーターは、主にシンプルなテレメトリーデータのエンコーダーおよび送信者であることが期待されます。
各実装は、SDKがそのエクスポーターに要求する並行性の特性をMUST文書化するものとします。
インターフェース定義
エクスポーターは、Export、Shutdown、ForceFlushの3つの機能をMUSTサポートするものとします。強く型付けされた言語では、通常シグナルごとに個別のExporterインターフェース(SpanExporterなど)が存在します。
Export(batch)
readable spanのバッチをエクスポートします。この機能を実装するプロトコルエクスポーターは、典型的にはデータをシリアライズして宛先へ送信することが期待されます。
Export()は、同じエクスポーターインスタンスに対する他のExport呼び出しと並行して呼び出されるべきではありません。
実装によっては、exportの結果は、Export()の呼び出しの戻り値としてではなく、非同期タスクの完了を伝えるための言語固有の方法でプロセッサーへ返されることがあります。つまり、あるエクスポーターのインスタンスのExport()が並行して呼び出されるべきでないとしても、それはエクスポートというタスク自体を並行に行えないことを意味しません。これをどのように行うかは本仕様書の範囲外です。
Export()は無期限にブロックしてはならず(MUST NOT)、それを超えるとエラー結果(Failure)でタイムアウトしなければならない、妥当な上限が存在しなければなりません(MUST)。
並行リクエストとリトライロジックはエクスポーターの責務です。必要となるロジックはspanの送信先となる特定のプロトコルとバックエンドに大きく依存する可能性が高いため、デフォルトSDKのSpan Processorはリトライロジックを実装すべきではありません(SHOULD NOT)。例えば、OpenTelemetry Protocol(OTLP)仕様書は、並行リクエストの送信とリクエストの再試行の両方についてロジックを定義しています。
パラメータ:
batch - readable spanのバッチ。バッチの正確なデータ型は言語固有であり、典型的には何らかのリストです。例えばJavaのspanでは典型的にはCollection<SpanData>になります。
戻り値: ExportResult:
Export()の戻り値は実装固有です。その言語にとってイディオマティックな方法で、ExporterはプロセッサーにExportResultを送信しなければなりません(MUST)。ExportResultはSuccessまたはFailureのいずれかの値を持ちます。
Success- バッチが正常にエクスポートされました。プロトコルエクスポーターの場合、これは典型的にはデータがワイヤー上で送信され、宛先サーバーに配送されたことを意味します。Failure- エクスポートが失敗しました。バッチは破棄されなければなりません。例えば、これはバッチに不正なデータが含まれていてシリアライズできない場合に発生することがあります。
例えば、Javaでは、Export()の戻り値は完了時にExportResultオブジェクトを返すFutureになります。一方Erlangでは、Exporterは特定のspanのバッチに対するExportResultを含むメッセージをプロセッサーへ送信します。
Shutdown()
エクスポーターをシャットダウンします。SDKがシャットダウンされる際に呼び出されます。これはエクスポーターが必要なクリーンアップを行う機会です。
ShutdownはExporterインスタンスごとに一度だけ呼び出されるべきです。Shutdownの呼び出し後、Exportへの以後の呼び出しは許可されず、Failure結果を返すべきです。
Shutdownは(例えばデータをフラッシュしようとして宛先が利用できない場合など)無期限にブロックすべきではありません。OpenTelemetryクライアントの実装者は、シャットダウンのタイムアウトを設定可能にするかどうかを決めてかまいません。
ForceFlush()
これは、ForceFlushの呼び出しより前にエクスポーターが受け取っていたSpanのエクスポートが、できる限り早く、望ましくはこのメソッドから戻る前に完了しているべきことを示すヒントです(SHOULD)。
ForceFlushは、呼び出し元に成功・失敗・タイムアウトのいずれであったかを知らせる手段をSHOULD提供するものとします。
ForceFlushは、プロセスを中断させてから完了したspanをエクスポートする前にプロセスを停止させてしまう可能性のある一部のFaaSプロバイダーを使う場合など、絶対に必要な場合に限りSHOULD呼び出されるものとします。
ForceFlushは、ある程度のタイムアウト内に完了または中断すべきです(SHOULD)。ForceFlushは、ブロッキングAPIとして実装しても、コールバックやイベントを通じて呼び出し元に通知する非同期APIとして実装してもかまいません。OpenTelemetryクライアントの実装者は、フラッシュのタイムアウトを設定可能にするかどうかを決めてかまいません。
言語ごとの特化
上記で示した汎用的なインターフェース定義に基づき、ライブラリの実装者は特定の言語に対する正確なインターフェースを定義しなければなりません。
実装者は、プロトコルエクスポーターによるワイヤーフォーマットへの高速なシリアライズに適し、メモリマネージャへの負荷を最小化する、効率的なデータ構造をインターフェースの境界で使うことが推奨されます。後者は典型的には、急速に生成され短命なテレメトリーデータ構造を、その言語固有のメモリマネージャにとって扱いやすい形に最適化する方法を理解している必要があります。一般的な推奨は、割り当ての回数を最小化し、可能であればアロケーションアリーナを使うことで、テレメトリーデータの生成率が高い状況で割り当て・解放・回収の操作が爆発的に増えることを避けることです。
例
以下は、特定の言語におけるExporterインターフェースがどのようなものになりうるかの例です。これらの例はあくまで説明のためのものです。OpenTelemetryクライアントの実装者は、その設計がExporterという概念の精神に忠実であれば、これらの例から自由に外れてかまいません。
GoにおけるSpanExporterインターフェース
type SpanExporter interface {
Export(batch []ExportableSpan) ExportResult
Shutdown()
}
type ExportResult struct {
Code ExportResultCode
WrappedError error
}
type ExportResultCode int
const (
Success ExportResultCode = iota
Failure
)
JavaにおけるSpanExporterインターフェース
public interface SpanExporter {
public enum ResultCode {
Success, Failure
}
ResultCode export(Collection<ExportableSpan> batch);
void shutdown();
}
並行性の要件
並行実行をサポートする言語について、Tracing SDKは特定の保証と安全性を提供します。
TracerProvider - Tracerの作成、ForceFlush、Shutdownは並行して呼び出されて安全でなければなりません(MUST)。
Sampler - ShouldSampleとGetDescriptionは並行して呼び出されて安全でなければなりません(MUST)。
SpanProcessor - すべてのメソッドは並行して呼び出されて安全でなければなりません(MUST)。
SpanExporter - ForceFlushとShutdownは並行して呼び出されて安全でなければなりません(MUST)。
セルフオブザーバビリティ
ステータス: Development
Tracing SDKはSDKのセルフオブザーバビリティをSHOULDサポートするものとします。