OTEP-4673: TraceState: 確率的サンプリング

ステータス: アーカイブ済み

このドキュメントには、古い実験的な「tracestateによる確率的サンプリング」仕様の最終状態が記載されています。 この仕様は、OpenTelemetryの仕様から削除した後も参照できるように、OTEPとして記録されています。

以下に、このドキュメントに加えられた変更点の概要を示します。

  • sdk.md へのリンクについて: 参照は一般的なものでした。というのも、SDK仕様がこのドキュメントを参照するように更新されることはなかったためです。これらのリンクは、将来的にリンク切れが起きないよう、現在の固定リンクに更新されました。
  • tracestate-handling.md へのリンクについて: これらのリンクは、PR#4162 が新しい仕様を追加する前の、このファイルが書かれた当時のバージョンに更新されました。
  • 目次を削除しました。

Overview

確率的サンプリングにより、OpenTelemetryのトレーシング利用者は、ランダム化されたサンプリング手法を使ってスパンの収集コストを下げることができます。 目的は次のとおりです。

  • 既存のW3C trace contextの sampled フラグと互換性がある
  • Span-to-metricsパイプラインを使ってスパンを正確にカウントできる
  • スパンが独立してサンプリングの決定を行う場合でも、トレースが完全になる傾向がある

このドキュメントでは、「r-value」と「p-value」に基づく手法を規定します。 非常に大まかに言うと、r-valueはランダム性の源であり、p-valueはサンプリング確率をエンコードします。 p <= r のとき、コンテキストはサンプリングされます。

重要な点として、r-valueとp-valueをOpenTelemetryの tracestate に含めることで、これら2つの値はコンテキストを通じて自動的に伝播し、すべてのスパンに記録されます。 これにより、トレースの利用者は、あるスパンのp-valueを解釈するだけで、スパンを正しくカウントできるようになります。

効率のため、サポートされるサンプリング確率は2のべき乗に限定されます。 p-valueはサンプリング確率から導出され、2**-p に等しくなります。 したがって、p-valueは符号なし整数を使ってエンコードされます。

たとえば、p-valueが3であれば、サンプリング確率が1/8であることを示します。

W3C trace contextは、TraceIdの128ビットのうち何ビットが真の一様分布ランダムビットであるかを規定していないため、追加のランダム性の源としてr-valueが導入されています。

「r-value」を生成する推奨方法は、62個のランダムビットからなる文字列の先頭にある0の個数を数えることですが、この方法を使うことは必須ではありません。

Definitions

Sampling

サンプリングとは、完全なデータセットの一部だけを収集・分析するための一連の手法です。 「サンプリング」された個々の項目は、収集・カウントされる際に1つ以上のスパンを代表するとみなされます。 各スパンの代表性は、Span-to-Metricsパイプラインでスパンを正確にカウントするために使用されます。

サンプリングの用語では、サンプリング元となる完全なデータの集合を指すために「母集団 (population)」という言葉を使います。 OpenTelemetryのトレーシングにおいて、「母集団」はすべてのスパンを指します。

確率的サンプリングでは、個々のサンプル項目の代表性は一般に既知ですが、OpenTelemetryは「非確率的 (non-probability)」なサンプリング手法も認識しており、その場合は代表性が明示的に定量化されません。

Adjusted count

調整カウント (Adjusted count) は代表性の尺度であり、個々のサンプリングされたスパンによって代表される母集団内のスパンの数です。 Span-to-metricsパイプラインは、各サンプルスパンの調整カウントを、一致するスパンのカウンターに加算することで構築できます。

確率的サンプリングにおいて、調整カウントはサンプリング確率の逆数(つまり数学的な逆数)として定義されます。

非確率的サンプリングにおいて、調整カウントは不明です。

調整カウントがゼロであるという扱いは、確率的サンプリングと非確率的サンプリングの合成をサポートするために定義されています。 確率サンプラーがスパンを選択しなかった場合、調整カウントとしてゼロが割り当てられます。

したがって、調整カウントには意味のある3つのカテゴリーがあります。

調整カウント解釈
不明 (Unknown)調整カウントが不明である。非確率的サンプラーの結果である可能性がある。このカテゴリーの項目はカウントすべきではない
ゼロ (Zero)調整カウントは既知であり、その項目の実効カウントはゼロである
非ゼロ (Non-zero)調整カウントは既知であり、その項目の実効カウントはゼロより大きい

Sampler

サンプラーは、トレーシングクライアントライブラリにおいて、どのスパンを「記録 (record)」および/または「サンプリング (sample)」するかを選択するための、SDKが使用する設定可能なロジックを提供します。 スパンを「記録する」とは、クライアントのメモリ内にその表現を構築することを意味し、これによりエクスポート対象となる資格を得ます。 スパンを「サンプリングする」とは、W3Cの sampled フラグを設定し、スパンを記録し、スパンが終了したときにそれをエクスポートすることを意味します。

OpenTelemetryは、ライブなスパンのプロセス内での可観測性(たとえばzページ)のために、「記録」されるが「サンプリング」されないスパンをサポートします。

Sampler インターフェースおよびOpenTelemetryが定義する組み込みのサンプラーは、スパンをサンプリングするかどうかを即座に決定し、子コンテキストはその決定を即座に伝播します。

Parent-based sampler

コンテキストからのW3Cの sampled フラグに基づいてサンプリングの決定を行うサンプラーは、Parentベースのサンプリングを使用しているといいます。

Probability sampler

確率サンプラーとは、その決定のそれぞれについて、そのスパンが選択される確率を即座に把握しているサンプラーです。

サンプリング確率は、1以下かつ0より大きい数として定義されます(つまり 0 < probability <= 1)。 確率0のケースは、特殊な非確率的なケースとして扱われます。

Consistent probability sampler

一貫性のある確率サンプラーとは、トレース内の各スパンで独立したサンプリングの決定をサポートしながら、トレース全体にわたる特定の最小確率でトレースが完全になることを維持するサンプラーです。

一貫性のある確率的サンプリングでは、あるトレース内の任意のスパンについて、より小さいサンプリング確率を持つサンプラーがそのスパンをサンプリングのために選択した場合、より大きい確率で設定されたサンプラーによってもそのスパンが選択されることが要求されます。

Trace completeness

トレースは、そのトレースに属するすべてのスパンが収集されたときに完全であるといいます。 少なくとも1つのスパンが収集されているものの、すべてのスパンが収集されていない場合、そのトレースは不完全とみなされます。

トレースの不完全性は、意図的に(たとえばサンプリング設定を通じて)生じる場合もあれば、偶発的に(たとえば収集エラーを通じて)生じる場合もあります。 OpenTelemetryのトレースデータモデルは、不完全性についての一方向のテストをサポートします。 ルート以外の任意のスパンについて、そのスパンの親スパンが収集されていなければ、そのトレースは確実に不完全です。

サンプリング設定の結果として生じる(つまり意図的な)不完全なトレースは、部分トレースとして知られています。 部分トレースの中でも重要な部分集合は、完全なサブトレースでもあるものです。 完全なサブトレースは、あるスパンにおいて、そのすべての子孫スパンが収集されているときに定義されます。

不完全性のテストは一方向であるため、どのサンプリング設定が不完全なトレースにつながる可能性があるかを知ることが重要です。 完全なトレースおよび完全なサブトレースに自然につながるサンプリング設定については、以下で議論します

Non-probability sampler

非確率的サンプラーとは、偶然ではなく、任意のロジックと内部状態に基づいて決定を行うサンプラーです。 非確率的サンプラーによってサンプリングされたスパンの調整カウントは不明です。

Always-on consistent probability sampler

Always-onサンプラーは、確率1の一貫性のある確率サンプラーの別名です。

Always-off sampler

Always-offサンプラーは、スパンを完全に無効化する効果を持ち、事実上そのスパンを母集団から除外します。 これは、ゼロパーセント確率のサンプラーではなく非確率的サンプラーとして定義されます。 なぜなら、そのスパンは事実上代表されないからです。

Consistent Probability sampling

OpenTelemetryが採用する一貫性のあるサンプリング方式は、「p-value」と「r-value」と呼ばれる2つの値をコンテキストを通じて伝播します。

両方のフィールドは、tracestate仕様の規則に従って、ot ベンダータグの下でOpenTelemetryの tracestate を介して伝播されます。 両方のフィールドは、最大6ビットの情報を必要とする符号なし10進整数として表現されます。

このサンプリング方式は、固定された63個の異なる確率値の集合から項目を選択します。 サポートされる確率の集合には、1から2の-62乗までの2の整数べき乗が含まれます。 ゼロ確率および2の-62乗より小さい確率は、単位確率(つまり100%)が「ConsistentAlwaysOn」サンプラーの特殊なケースを表すのと同様に、「ConsistentAlwaysOff」サンプラーの特殊なケースとして扱われます。

R-valueは、63通りの可能性のうち、あるトレースについて一貫してサンプリングを決定するのはどれかをエンコードします。 具体的には、r-valueは、対応するp-valueの観点から、あるトレースをサンプリングすると決定する最小の確率を指定します。 たとえば、r-value 0を持つトレースは100%サンプリング用に設定されたスパンをサンプリングし、r-value 1は50%または100%サンプリング用に設定されたスパンをサンプリングし、以下同様に、r-value 62まで続きます。 r-value 62では、一貫性のある確率サンプラーは、サポートされるすべての確率(つまり2の-62乗以上)において「サンプリングする」と決定します。

P-valueは、子コンテキスト(つまり tracestate の利用者)と、Span-to-metricsパイプラインで使用するために記録するサンプルスパンの利用者のための調整カウントをエンコードします。 特別なp-value 63は、調整カウントがゼロであることを意味するよう定義されており、非確率的サンプラーの合成規則を定義する助けとなります。

traceparent に含まれる sampled トレースフラグと、tracestate に含まれるr-valueおよびp-valueとを結びつける不変条件が規定されます。

Conformance

OpenTelemetryの tracestate データの利用者は、そのデータを解釈する前に、確率的サンプリングのフィールドを検証することが期待されます。 これは、ここで規定される2つのサンプラーだけでなく、スパンデータの利用者にも当てはまり、スパンの調整カウントを解釈する前に tracestate を検証することが期待されます。

p-valueとr-valueのフィールドを含むOpenTelemetryの tracestate を生成する側は、ConsistentProbabilityBased サンプラーに対して述べられている振る舞い上の要件を満たし、統計的に妥当な結果を保証する必要があります。 この仕様にはテストスイートが含まれており、利用者やOpenTelemetryの tracestate の利用者は、Span-to-metricsパイプラインにおける正確性を確認できます。

Completeness guarantee

この仕様は、2のべき乗のサンプリング確率に対する一貫性のあるサンプリングを規定します。 サンプラーが2のべき乗でないサンプリング確率で設定された場合、サンプラーは最も近い2つのべき乗の間で確率的に選択します。

トレースのルートで単一の一貫性のある確率サンプラーが使用され、他のすべてのスパンがParentベースのサンプラーを使用する場合、結果として得られるトレースは常に完全になります(収集エラーは無視します)。 この性質は、2のべき乗でないサンプリング確率であっても成立します。

同じトレース内で複数の一貫性のある確率サンプラーが使用される場合、一般に、トレースの完全性は、トレース全体における最小のサンプリング確率以上となる最小の2のべき乗において保証されます。

Context invariants

W3Cの traceparent(バージョン0)には、TraceId、SpanId、トレースフラグという3つの情報フィールドが含まれます。 sampled トレースフラグは、コンテキストをサンプリングする意図を伝えるものとしてW3Cによって定義されています。

Sampler API は、sampled フラグと tracestate を設定する役割を担います。

P-valueとr-valueは、識別子 pr を使って、ベンダータグ ot の下でOpenTelemetryの tracestate に設定されます。 P-valueは、[0, 63] の範囲(つまり64個の有効な値がある)で有効な符号なし整数です。 R-valueは、[0, 62] の範囲(つまり63個の有効な値がある)で有効な符号なし整数です。 P-valueとr-valueは独立した設定であり、それぞれ他方が存在しなくても意味を持って設定できます。

Sampled flag

確率的サンプリングは、一貫性のある意思決定を可能にし、サンプリングされたスパンの調整カウントを記録するために、追加の情報を使用します。 両方の値が定義されていて指定された範囲内にある場合、r-valueとp-valueと sampled トレースフラグの間の不変条件は、((p <= r) == sampled) OR (sampled AND (p == 63)) == TRUE であると述べています。

sampledpr の間の不変条件は、pr の両方が存在する場合にのみ適用されます。 不変条件に違反する場合、sampled フラグが優先され、調整カウントが不明であることを知らせるために tracestate から p が解除されます。

Requirement: Inconsistent p-values are unset

サンプラーは、tracestate を使ってサンプリングの決定を行ったり調整カウントを解釈したりする前に、sampledpr の値の間の不変条件に違反している場合、p を解除すべきです(SHOULD)。

P-value

調整カウントがゼロであることは、特別なp-value 63で表されます。 それ以外の場合、p-valueはサンプリング確率の底2の対数の負の値に設定されます。

p-value親の確率調整カウント
011
11/22
21/44
N2**-N2**N
612**-612**61
622**-622**62
6300
Requirement: Out-of-range p-values are unset

利用者は、符号なし10進数の値が63より大きい場合、サンプリングの決定を行ったり調整カウントを解釈したりする前に、tracestate から p を解除すべきです(SHOULD)。

R-value

R-valueは、一貫性のある確率的サンプリングをサポートするために、トレースのルートにあるサンプラーによって tracestate に設定されます。 この値が省略されている、または存在しない場合、トレース内の子スパンは一貫性のある確率的サンプリングに参加できません。

R-valueは、次のように、あるトレースのスパンについてどのサンプリング確率がサンプリングする、またはしないと決定するかを決定します。

r-value示唆されるサンプリング確率
01
11/2 and above
21/4 and above
31/8 and above
0 <= r <= 612**-r and above
592**-59 and above
602**-60 and above
612**-61 and above
622**-62 and above

これらの確率は、準拠するSampler実装が正しい調整カウントを持つスパンを記録することを保証するために規定されています。 r-valueを生成する推奨方法は、62個のランダムビットからなる文字列の先頭にある0の個数を数えることですが、この方法を使うことは必須ではありません。

Requirement: Out-of-range r-values unset both p and r

サンプラーは、tracestate を使ってサンプリングの決定を行う前に、r の符号なし10進数の値が62より大きい場合、rp の両方を tracestate から解除すべきです(SHOULD)。

Requirement: R-value is generated with the correct probabilities

サンプラーは、62個のランダムビットからなる文字列の先頭にある0の個数を数えることで生成される値と同等の確率で各値を生成する、ランダム化された方式を使ってr-valueを生成しなければなりません(MUST)。

Examples: Context invariants

Example: Probability sampled context

次のヘッダーを持つトレースコンテキストを考えます。

traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
tracestate: ot=r:3;p:2

この例における traceparent の内容は、W3Cの仕様 から引用したものであり、以下のbase64エンコードされたフィールド値を持ちます。

base16(version) = 00
base16(trace-id) = 4bf92f3577b34da6a3ce929d0e0e4736
base16(parent-id) = 00f067aa0ba902b7
base16(trace-flags) = 01  // (i.e., sampled)

tracestate ヘッダーには、10進数でエンコードされたp-valueとr-valueを含むOpenTelemetryの文字列 r:3;p:2 が含まれます。

base10(r) = 3
base10(p) = 2

ここで、r-value 3は、12.5%(つまり8分の1)以上の確率で設定された一貫性のある確率サンプラーがこのトレースをサンプリングすることを示しています。 p-value 2は、sampled フラグを設定した親が25%(つまり4分の1)でサンプリングするよう設定されていたことを示しています。 p <= r が真であり sampled フラグが設定されているため、このトレースコンテキストは一貫性があります。

Example: Probability unsampled

この例は、r-valueのみが設定された、サンプリングされていないコンテキストです。

traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00
tracestate: ot=r:3

r-valueを持つことで、子コンテキストにおける一貫性のある確率的サンプリングをサポートします。 p-valueは設定されておらず、これはサンプリングされていないコンテキストと整合しています。

Samplers

ParentConsistentProbabilityBased sampler

ParentConsistentProbabilityBased サンプラーは、ParentBased サンプラー のオプションの代替として意図されています。 このサンプラーは、まず tracestate を検証し、その後W3Cの traceparentにおける sampled フラグを尊重する必要があります。

Requirement: ParentConsistentProbabilityBased API

ParentConsistentProbabilityBased サンプラーのコンストラクターは、単一のSampler引数を取るべきです(SHOULD)。 これは、ParentConsistentProbabilityBased サンプラーがルートスパンに対して呼び出された場合に使用するサンプラーです。

Requirement: ParentConsistentProbabilityBased does not modify valid tracestate

ParentConsistentProbabilityBased サンプラーは、有効な tracestate を変更してはなりません(MUST NOT)。

Requirement: ParentConsistentProbabilityBased calls the configured root sampler for root spans

ParentConsistentProbabilityBased サンプラーは、有効な親トレースコンテキストが存在しない場合、設定されたルートサンプラーに委譲しなければなりません(MUST)。

Requirement: ParentConsistentProbabilityBased respects the sampled flag for non-root spans

ParentConsistentProbabilityBased サンプラーは、W3Cの traceparentヘッダーにおける sampled フラグの値に従って、そのスパンをサンプリングするかどうかを決定しなければなりません(MUST)。

ConsistentProbabilityBased sampler

ConsistentProbabilityBased サンプラーは、TraceIdRatioBased サンプラー のオプションの代替として意図されています。 ルートサンプラーとして使用される場合、ConsistentProbabilityBased サンプラーは有効な tracestate を生成する必要があります。 ルート以外のコンテキストで使用される場合、受信した tracestate を検証し、送信するコンテキストに対して有効な tracestate を生成する必要があります。

ConsistentProbabilityBased サンプラーは、正確な2のべき乗ではない確率をサポートする必要があります。 そのためには、実装は最も近い2つのべき乗の間で確率的に選択する必要があります。 たとえば、5%サンプリングは、60%の確率で1/16サンプリングを選択し、40%の確率で1/32サンプリングを選択することで達成できます。

Requirement: TraceIdRatioBased API compatibility

ConsistentProbabilityBased サンプラーは、各OpenTelemetry SDKに組み込まれている TraceIdRatioBased サンプラーと同じコンストラクターシグネチャを持たなければなりません(MUST)。

Requirement: ConsistentProbabilityBased sampler sets r for root span

ConsistentProbabilityBased サンプラーは、ルートのサンプリング決定を行う際に r を設定しなければなりません(MUST)。

Requirement: ConsistentProbabilityBased sampler un-sets p when not sampled

ConsistentProbabilityBased サンプラーは、サンプリングしないと決定した場合、tracestate から p を解除しなければなりません(MUST)。

Requirement: ConsistentProbabilityBased sampler sets p when sampled

ConsistentProbabilityBased サンプラーは、設定されたサンプリング確率に従ってサンプリングすると決定した場合、p を設定しなければなりません(MUST)。

Requirement: ConsistentProbabilityBased sampler records unbiased adjusted counts

ゼロでない確率を持つ ConsistentProbabilityBased サンプラーは、tracestate から解釈される調整カウントが、母集団内の代表スパン数の不偏推定値となるように p を設定しなければなりません(MUST)。

Requirement: ConsistentProbabilityBased sampler sets r for non-root span

入力の traceコンテキストに r が設定されておらず、かつそのスパンがルートスパンでない場合、ConsistentProbabilityBased は、あたかもルートスパンであるかのように r を設定し、潜在的に一貫性のないトレースが生成されていることを利用者に警告すべきです(SHOULD)。

Requirement: ConsistentProbabilityBased sampler decides not to sample for probabilities less than 2**-62

設定されたサンプリング確率が区間 [0, 2**-62) 内にある場合、サンプラーはサンプリングしないと決定しなければなりません(MUST)。

Examples: Consistent probability samplers

Example: Setting R-value for a root span

新しいルートスパンが、一貫性のある確率サンプラーによって25%でサンプリングされます。 新しいr-valueを生成する必要があります(適切な方法については付録を参照)。 この例では、1.5625%の確率で発生し、サンプリングすることを示すr-value 5が使用されます。

tracestate: ot=r:5;p:2

p-value 2はr-value 5以下であるため、このスパンはサンプリングされます。 r-value 1が25%でサンプリングしないことを示す tracestate の例を次に示します。

tracestate: ot=r:1

p-value 2(25%サンプリングに対応)がr-value 1より大きいため、このスパンはサンプリングされません。

Example: Handling inconsistent P-value

一貫性のある確率サンプラーまたはParentベースの一貫性のある確率サンプラーが、サンプリングされたコンテキストを受信したものの、p-valueが無効である場合を考えます。 たとえば、

tracestate: ot=r:4;p:73

tracestate はそのp-valueが取り除かれます。 r-valueは保持され、サンプラーは以下を受信したかのように振る舞うべきです。

tracestate: ot=r:4

一貫性のある確率サンプラーは、受信したr-valueを使って独自の(一貫性のある)決定を行います。

Parentベースの一貫性のある確率サンプラーは、この場合 sampled フラグに従います。 コンテキストがサンプリングされている場合、結果として得られるスパンはp-valueを持たないr-valueを持つことになり、これは調整カウントが不明であることを示します。

Example: Handling corrupt R-value

ルート以外のスパンが次を受信します。

tracestate: ot=r:100;p:10

ここでr-valueは有効範囲外です。 不変条件に従い、検証時にr-valueとp-valueが取り除かれます。 この場合、サンプラーは tracestate を受信していないかのように振る舞います。

この場合、Parentベースの一貫性のある確率サンプラーは、sampled フラグに基づいてサンプリングするかしないかを決定します。 コンテキストがサンプリングされている場合、記録されるスパンはp-valueを持たないr-valueを持つことになり、これは調整カウントが不明であることを示します。

一貫性のある確率サンプラーは、新しいr-valueを生成し、破損した可能性のある一貫性のないr-valueについて利用者に警告しながら、新しいサンプリングの決定を行います。

Composition rules

複数のサンプラーがコンテキストをサンプリングする決定に関与する場合、それらの決定は合成規則を使って組み合わせることができます。 すべての場合において、組み合わされたサンプリングの決定は、各サンプラーの決定の論理和です(つまり、合成対象のサンプラーのうち少なくとも1つがサンプリングを決定すればサンプリングします)。

2つの一貫性のある確率サンプラーの決定からp-valueを組み合わせるには、確率がより大きい方のサンプラーが効力を持ちます。 出力されるp-valueは、両者の p の値のうち最小値になります。

一貫性のある確率サンプラーの決定と非確率的サンプラーの決定を組み合わせるには、p-value 63を使って調整カウントがゼロであることを示します。 確率サンプラーがサンプリングすると決定した場合、そのp-valueが効力を持ちます。 非確率的サンプラーがサンプリングする一方で確率サンプラーがサンプリングしないと決定した場合、調整カウントがゼロであることを示すp-value 63が効力を持ちます。

List of requirements

Requirement: Combining multiple sampling decisions using logical or

複数のサンプラーが合成によって組み合わされる場合、組み合わされたサンプラーのうち少なくとも1つがサンプリングを決定すれば、サンプリングの決定はサンプリングすることでなければなりません(MUST)。

Requirement: Combine multiple consistent probability samplers using the minimum p-value

複数の一貫性のある確率サンプラーについてサンプラーの決定を組み合わせ、少なくとも1つがサンプリングすると決定した場合、tracestate には「サンプリングする」と決定した p の値のうち最小のものを設定しなければなりません(MUST)。

Requirement: Unset p when multiple consistent probability samplers decide not to sample

複数の一貫性のある確率サンプラーについてサンプラーの決定を組み合わせ、いずれもサンプリングしないと決定した場合、tracestate においてp-valueを解除しなければなりません(MUST)。

Requirement: Use probability sampler p-value when its decision to sample is combined with non-probability samplers

一貫性のある確率サンプラーと非確率的サンプラーについてサンプラーの決定を組み合わせ、確率サンプラーがサンプリングすると決定した場合、非確率的サンプラーの決定にかかわらず、そのp-valueを tracestate に設定しなければなりません(MUST)。

Requirement: Use p-value 63 when a probability sampler decision not to sample is combined with a non-probability sampler decision to sample

一貫性のある確率サンプラーと非確率的サンプラーについてサンプラーの決定を組み合わせ、確率サンプラーがサンプリングしないと決定した一方で非確率的サンプラーがサンプリングする場合、p-value 63を tracestate に設定しなければなりません(MUST)。

Examples: Composition

Example: Probability and non-probability sampler in a root context

新しいルートコンテキストにおいて、一貫性のある確率サンプラーが sampled フラグを設定しないと決定し、6.5%(つまり16分の1)以上の確率でトレースが一貫してサンプリングされることを示す r:4 を追加します。

この確率サンプラーの決定は、コンテキストをサンプリングすると決定する非確率的サンプラーと合成されます。 確率サンプラーがサンプリングしていないにもかかわらず sampled を設定するには、調整カウントがゼロであることを示す p:63 の設定が必要です。

結果として得られるコンテキストは次のとおりです。

traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
tracestate: ot=r:4;p:63
Example: Two consistent probability samplers

ルートであるかどうかにかかわらず、複数の一貫性のある確率サンプラーが、あるコンテキストをサンプリングすると決定した場合、最小のp-valueがtracestateに出力されます。

ルートコンテキストの場合、2つのサンプラーのうち最初のものが r:15 と自身のp-value p:10(つまり調整カウント1024)を生成します。 2つの確率サンプラーのうち2番目のものは、より小さい調整カウント p:8(つまり調整カウント256)を出力します。

結果として得られるコンテキストは、より小さい方のp-valueを採用します。

traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
tracestate: ot=r:15;p:8

Producer and consumer recommendations

Trace producer: completeness

完全性の保証 で述べたように、同じトレース内で複数の一貫性のある確率サンプラーを設定すると、トレースが不完全になる可能性があります。 不完全なトレースの生成を避ける1つの方法は、ルートスパン以外ではParentベースのサンプラーを使用することです。

トレースの不完全性については単純なテストがありますが、これは一方向のテストであり、子スパンが収集されていないことを検出できません。 不完全なトレースの生成を避ける1つの方法は、ルート以外のスパンに対して2のべき乗ではないサンプリング確率を設定しないことです。 なぜなら、2のべき乗でないサンプリング確率については完全性が保証されないからです。

Recommendation: use non-descending power-of-two probabilities

トレースのルートからリーフに至るまでのサンプリング確率の並びが、非減少の2のべき乗で構成されている場合、完全なサブトレースが生成されます。 完全なサブトレースが確実に生成されるようにするには、子のサンプラーは、親スパンのサンプリング確率以上の2のべき乗の確率で設定されるべきです(SHOULD)。

Trace producer: correctness

調整カウントの情報を伝えるためにtracestateを使用することは、トレースの参加者間の信頼に基づいています。 利用者は、親のサンプリング決定に対応する調整カウントが信頼できない場合には、Span-to-metricsパイプラインを使用しないことが推奨されます。

ConsistentProbabilityBased および ParentConsistentProbabilityBased サンプラーは、スパンやその他の固定属性に基づいてサンプラーの選択を条件付けるために、他のサンプラーの委譲先として使用できます。 しかし、調整カウントが信頼できるものであるためには、ルート以外のサンプラーの選択を、親の sampled トレースフラグやOpenTelemetryの tracestate のr-valueおよびp-valueに基づいて条件付けることはできません。 なぜなら、そうした決定は誤った調整カウントにつながるからです。

たとえば、組み込みのParentBased サンプラー は、親コンテキストがリモートか非リモートか、サンプリングされているかいないかに基づいて、委譲先のサンプラーを設定することをサポートしています。 ParentBased サンプラーが、サンプリングされていないコンテキストに対してのみ ConsistentProbabilityBased サンプラーに委譲する場合、結果として得られるSpan-to-metricsパイプラインは(おそらく)スパンを過剰にカウントすることになります。

Recommendation: sampler delegation

ルート以外のスパンについて、合成サンプラーは、親の sampled フラグやOpenTelemetryの tracestate に基づいて委譲先のサンプラーの選択を条件付けるべきではありません(SHOULD NOT)。

Trace producer: interoperability with ParentBased sampler

OpenTelemetryに組み込みの ParentBased サンプラーは、委譲先のサンプラーがその選択を決定した決定を変更しない限り、ConsistentProbabilityBased サンプラーと相互運用可能です。 たとえば、決定がサンプリングされる方向に変わらない限り、サンプリングされていないスパンに対して代替の ParentBased サンプラー委譲先を設定しても安全です。

ParentBased サンプラーは sampled トレースフラグを尊重し、OpenTelemetryのSDKは Span データにtracestateを含めるため、システム全体で TraceIDRatioBased サンプラーを準拠する ConsistentProbabilityBased サンプラーに置き換えるだけで、システムを確率的サンプリングにアップグレードできることを意味します。

Trace producer: interoperability with TraceIDRatioBased sampler

TraceIDRatioBased の仕様 には、トレース全体でサンプラーの決定を一貫させる方法を規定していないため、ルート以外のスパンには使用しないという推奨事項が含まれています。 ルートスパンにおける TraceIDRatioBased サンプラーは、完全性の観点では ConsistentParentProbabilityBased サンプラーと相互運用可能ですが、結果として得られるスパンの調整カウントは不明になります。

TraceIDRatioBased サンプラーがルート以外のスパンに設定される場合、不正なOpenTelemetryのtracestateが生成されるいくつかのケースが生じます。 たとえば、ルート(R)が ConsistentProbabilityBased サンプラーを持ち、ルートの子(P)が TraceIDRatioBased サンプラーを持ち、孫(C)が ParentBased サンプラーを持つ、3つのスパンからなるトレースを考えます。 TraceIDRatioBased サンプラーはOpenTelemetryのtracestateを更新せずに中間の sampled フラグを変更するため、次のケースが生じます。

  1. TraceIDRatioBased がPの決定を変更しない場合、トレースは完全であり、すべてのスパンの調整カウントは正しくなります。
  2. TraceIDRatioBased がPの決定を「いいえ」から「はい」に変更する場合、利用者はPとCを含む(確実に)不完全なトレースを観測します。両方のスパンは無効なOpenTelemetryのtracestateを持ち、この場合、調整カウントが不明になります。
  3. TraceIDRatioBased がサンプリングの決定を「はい」から「いいえ」に変更する場合、利用者は正しい調整カウントを持つ単一のスパンからなるトレースを観測します。利用者は、Rにサンプリングされていない子孫が2つあることを判断できません。

これらのケースが示すように、利用者は、ルート以外のスパンに TraceIDRatioBased サンプラーを使用すると、不完全性と不明な調整カウントが生じることを予期できますが、これは当初規定されていた警告に反しています。

Trace consumer

トレースの利用者は、不完全性についての単純な一方向のテストを適用することが期待されます。 ルート以外のスパンが独立したサンプリング確率で設定されている場合、トレースは検出できない形で完全になることがあります。 一方向のテストであるため、完全なトレースを保証したい利用者は、システム全体における最小のサンプリング確率を知っていることが期待されます。

偶発的なデータ損失を無視すると、あるトレースのすべてのスパンが一貫性のある確率サンプラーでサンプリングされ、かつそのトレースのr-valueが、トレース全体における最小のサンプリング確率以上の値に対応する最小の2のべき乗より大きい場合、そのトレースは完全になります。

ConsistentProbabilityBased サンプラーには、ルート以外のスパンで r が未設定の場合にそれを設定するという要件があるため、トレースの利用者はトレースのr-valueの一貫性を確認することが推奨されます。 単一のトレースに複数の異なる r の値が含まれる場合、それはそのトレースがルートで確率的サンプリング用に正しくサンプリングされなかったことを意味します。 このシナリオでは各スパンの調整カウントは正しいものの、完全なトレースを検出することが不可能になる場合があります。

Recommendation: Recognize inconsistent r-values

単一のトレースに、r について複数の異なる値を持つ tracestate の値を持つスパンが含まれる場合、利用者はそのトレースが一貫性なくサンプリングされたと認識すべきです(SHOULD)。

Appendix: Statistical test requirements

このセクションでは、サンプリングの決定が不偏であるという要件への基本的な準拠を保証するために実装できるテストを規定します。

このテスト仕様の目標は、実装がシンプルであり、成功のために高度な統計スキルやライブラリを必要としないことです。

このテストは、乱数生成器の性能を評価することを意図したものではありません。 このテストは、基盤となるRNGが十分な品質を持つことを前提とし、サンプラーが高い統計的信頼度で期待される比率を生成することを確認します。

この種のテストの課題の1つは、確率的なテストは時折例外的な結果を生成することが予想される点です。 これをランダムな挙動に対する厳密なテストにするために、以下のアプローチを取ります。

  • あらかじめ決められた20個のランダムシードのリストを生成する
  • 有意水準(5%)と試行回数(20)に固定値を使用する
  • 母集団サイズとして100,000個のスパンを使用する
  • 各試行について、母集団をシミュレートし、カイ二乗検定統計量を計算する
  • 20試行のうちちょうど1回だけカイ二乗有意性検定が失敗するような、順序付けられたリスト内の最初のシード値を特定する

このテストを作成するには、あらかじめ決められたリストのシード値を順番に使って上記の手順を実行し、ちょうど1回失敗するシード値が見つかるまで続けます。 これはかなり頻繁に起こると予想され、利用可能な20個のシードのうち少なくとも1回は発生することが要求されます。 ちょうど1回のカイ二乗検定失敗を示す最初のシードのインデックスを計算した後、それをテストに記録します。 継続的インテグレーションでのテストのためには、あらかじめ決められたシードインデックスを使ってテストを再実行するだけで十分です。

規定されたとおり、カイ二乗検定は、サンプリング確率が正確な2のべき乗であるかどうかに応じて、1自由度または2自由度を持ちます。

Test procedure: non-powers of two

この場合、カイ二乗検定には2つの自由度があります。 次の表はテストパラメーターをまとめたものです。

テストケースサンプリング確率サンプリング時の下側・上側p-valueExpectlowerExpectupperExpectunsampled
10.9000000, 1800001000010000
20.6000000, 1200004000040000
30.3300001, 2160001700067000
40.1300002, 310001200087000
50.1000003, 47500250090000
60.0500004, 53750125095000
70.0170005, 6275147598300
80.0100006, 7437.5562.599000
90.0050007, 8218.75281.2599500
100.0029008, 9189.375100.62599710
110.0010009, 104.687595.312599900
120.00050010, 112.3437547.6562599950

このカイ二乗を計算する式は次のとおりです。

ChiSquared = math.Pow(sampled_lowerP - expect_lowerP, 2) / expect_lowerP +
             math.Pow(sampled_upperP - expect_upperP, 2) / expect_upperP +
             math.Pow(100000 - sampled_lowerP - sampled_upperP - expect_unsampled, 2) / expect_unsampled

このカイ二乗値は、有意水準5%で2自由度のカイ二乗分布の値である0.102587と比較されます。 上記の表の各確率について、このテストは、0.102587未満のカイ二乗値をちょうど1つ生成するシードを示すことが要求されます。

Requirement: Pass 12 non-power-of-two statistical tests

20試行、各100,000スパンのテストにおいて、カイ二乗検定統計量が20回中ちょうど1回だけ0.102587を下回るような乱数生成器のシードを示さなければなりません(MUST)。

Test procedure: exact powers of two

この場合、カイ二乗検定には1つの自由度があります。 次の表はテストパラメーターをまとめたものです。

テストケースサンプリング確率サンプリング時のp-valueExpectsampledExpectunsampled
130x1p-01 (0.500000)15000050000
140x1p-04 (0.062500)4625093750
150x1p-07 (0.007812)7781.2599218.75

このカイ二乗を計算する式は次のとおりです。

ChiSquared = math.Pow(sampled - expect_sampled, 2) / expect_sampled +
             math.Pow(100000 - sampled - expect_unsampled, 2) / expect_unsampled

このカイ二乗値は、有意水準5%で1自由度のカイ二乗分布の値である0.003932と比較されます。 上記の表の各確率について、このテストは、0.003932未満のカイ二乗値をちょうど1つ生成するシードを示すことが要求されます。

Requirement: Pass 3 power-of-two statistical tests

20試行、各100,000スパンのテストにおいて、カイ二乗検定統計量が20回中ちょうど1回だけ0.003932を下回るような乱数生成器のシードを示さなければなりません(MUST)。

Test implementation

このテストの推奨される構造は、15個の確率値、期待されるp-value、カイ二乗統計量が1自由度か2自由度か、そしてあらかじめ決められたシードのリストへのインデックスを列挙した表を使用します。

    for _, test := range []testCase{
        // Non-powers of two
        {0.90000, 1, twoDegrees, 3},
        {0.60000, 1, twoDegrees, 2},
        {0.33000, 2, twoDegrees, 2},
        {0.13000, 3, twoDegrees, 1},
        {0.10000, 4, twoDegrees, 0},
        {0.05000, 5, twoDegrees, 0},
        {0.01700, 6, twoDegrees, 2},
        {0.01000, 7, twoDegrees, 2},
        {0.00500, 8, twoDegrees, 2},
        {0.00290, 9, twoDegrees, 4},
        {0.00100, 10, twoDegrees, 6},
        {0.00050, 11, twoDegrees, 0},

        // Powers of two
        {0x1p-1, 1, oneDegree, 0},
        {0x1p-4, 4, oneDegree, 0},
        {0x1p-7, 7, oneDegree, 1},
    } {

上記の例のシードインデックスは、正しい分布であるように見えることに注意してください。 5個の0、2個の1、5個の2、1個の3、1個の4は、ちょうど1回の失敗が起きる例を見つけるのが比較的容易であることを示しています。 確率0.001(この場合シードインデックス6)は、外れ値が存在することを思い出させてくれます。 この分布についてのさらなる有意性検定は推奨されません。

Appendix

Methods for generating R-values

r-valueを生成するために使用する方法は、実装に最適化の自由度を持たせるために規定されていません。 一般的に、TraceIdが62ビットのランダムなビット部分文字列を含むことがわかっている場合、r-valueは、TraceIdの62個のランダムビットから、次の方法で直接導出できます。

  1. 先頭のゼロを数える
  2. 先頭の1を数える
  3. 末尾のゼロを数える
  4. 末尾の1を数える
import (
    "math/rand"
    "math/bits"
)

func nextRValueLeading() int {
    x := uint64(rand.Int63()) // 63 least-significant bits are random
    y := x << 1 | 0x3         // 62 most-significant bits are random
    return bits.LeadingZeros64(y)
}

TraceIdに不明または不十分なランダム性しか含まれない場合、別のアプローチとして、最初のtrueまたはfalseの値が出るまでランダムビットを生成する方法があります。

func nextRValueGenerated() int {
    for r := 0; r < 62; r++ {
        if rand.Bool() == true {
            return r
        }
    }
    return 62
}

次の表に示すr-valueを生成する方式であれば、どのようなものでも準拠しているとみなされます。

r-valuer-valueの確率
01/2
11/4
21/8
31/16
0 <= r <= 612**-(r+1)
592**-60
602**-61
612**-62
622**-62