Skip to content

Commit 8155988

Browse files
authored
Randomness requirements following W3C Trace Context level 2 (#4162)
1 parent a8ded1a commit 8155988

File tree

6 files changed

+160
-15
lines changed

6 files changed

+160
-15
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ release.
1111

1212
### Traces
1313

14+
- Define randomness value requirements for W3C Trace Context Level 2.
15+
([#4162](https://github.com/open-telemetry/opentelemetry-specification/pull/4162))
1416
- Deprecate `exception.escaped` attribute, add link to in-development semantic-conventions
1517
on how to record errors across signals.
1618
([#4368](https://github.com/open-telemetry/opentelemetry-specification/pull/4368))

spec-compliance-matrix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ formats is required. Implementing more than one format is optional.
8787
| [Built-in `SpanProcessor`s implement `ForceFlush` spec](specification/trace/sdk.md#forceflush-1) | | | + | | + | + | + | + | + | + | + | |
8888
| [Attribute Limits](specification/common/README.md#attribute-limits) | X | | + | | + | + | + | + | | | | |
8989
| Fetch InstrumentationScope from ReadableSpan | | | + | | + | | | + | | | | |
90+
| [Support W3C Trace Context Level 2 randomness](specification/trace/sdk.md#traceid-randomness) | X | | | | | | | | | | | |
9091

9192
## Baggage
9293

specification/context/api-propagators.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
* [Get Global Propagator](#get-global-propagator)
3333
* [Set Global Propagator](#set-global-propagator)
3434
- [Propagators Distribution](#propagators-distribution)
35+
* [W3C Trace Context Requirements](#w3c-trace-context-requirements)
3536
* [B3 Requirements](#b3-requirements)
3637
+ [B3 Extract](#b3-extract)
3738
+ [B3 Inject](#b3-inject)
@@ -377,6 +378,17 @@ Additional `Propagator`s implementing vendor-specific protocols such as AWS
377378
X-Ray trace header protocol MUST NOT be maintained or distributed as part of
378379
the Core OpenTelemetry repositories.
379380

381+
### W3C Trace Context Requirements
382+
383+
A W3C Trace Context propagator MUST parse and validate the `traceparent` and `tracestate` HTTP headers as specified in [W3C Trace Context Level 2](https://www.w3.org/TR/trace-context-2/). A W3C Trace Context propagator MUST propagate a valid `traceparent` value using the same header. A W3C Trace Context propagator MUST propagate a valid `tracestate` unless the value is empty, in which case the `tracestate` header may be omitted.
384+
385+
When injecting and extracting trace context to or from a carrier, the following fields from the `SpanContext` are propagated.
386+
387+
- TraceID (16 bytes)
388+
- SpanID (8 bytes)
389+
- TraceFlags (8 bits)
390+
- TraceState (string, unless empty)
391+
380392
### B3 Requirements
381393

382394
B3 has both single and multi-header encodings. It also has semantics that do not

specification/trace/api.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -233,16 +233,17 @@ non-zero byte.
233233
`SpanId` A valid span identifier is an 8-byte array with at least one non-zero
234234
byte.
235235

236-
`TraceFlags` contain details about the trace. Unlike TraceState values,
237-
TraceFlags are present in all traces. The current version of the specification
238-
only supports a single flag called [sampled](https://www.w3.org/TR/trace-context/#sampled-flag).
239-
240-
`TraceState` carries vendor-specific trace identification data, represented as a list
241-
of key-value pairs. TraceState allows multiple tracing
242-
systems to participate in the same trace. It is fully described in the [W3C Trace Context
243-
specification](https://www.w3.org/TR/trace-context/#tracestate-header). For
244-
specific OTel values in `TraceState`, see the [TraceState Handling](tracestate-handling.md)
245-
document.
236+
`TraceFlags` contain details about the trace.
237+
Unlike TraceState values, TraceFlags are present in all traces.
238+
The current version of the specification supports two flags:
239+
240+
- [Sampled](https://www.w3.org/TR/trace-context-2/#sampled-flag)
241+
- [Random](https://www.w3.org/TR/trace-context-2/#random-trace-id-flag)
242+
243+
`TraceState` carries tracing-system-specific trace identification data, represented as a list of key-value pairs.
244+
TraceState allows multiple tracing systems to participate in the same trace.
245+
It is fully described in the [W3C Trace Context specification](https://www.w3.org/TR/trace-context-2/#tracestate-header).
246+
For specific OpenTelemetry values in `TraceState`, see the [TraceState Handling](tracestate-handling.md) document.
246247

247248
`IsRemote`, a boolean indicating whether the SpanContext was received from somewhere
248249
else or locally generated, see [IsRemote](#isremote).

specification/trace/sdk.md

Lines changed: 106 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ linkTitle: SDK
2323
- [Sampling](#sampling)
2424
* [Recording Sampled reaction table](#recording-sampled-reaction-table)
2525
* [SDK Span creation](#sdk-span-creation)
26+
+ [Span flags](#span-flags)
2627
* [Sampler](#sampler)
2728
+ [ShouldSample](#shouldsample)
2829
+ [GetDescription](#getdescription)
@@ -33,8 +34,17 @@ linkTitle: SDK
3334
- [Requirements for `TraceIdRatioBased` sampler algorithm](#requirements-for-traceidratiobased-sampler-algorithm)
3435
+ [ParentBased](#parentbased)
3536
+ [JaegerRemoteSampler](#jaegerremotesampler)
37+
* [Sampling Requirements](#sampling-requirements)
38+
+ [TraceID randomness](#traceid-randomness)
39+
+ [Random trace flag](#random-trace-flag)
40+
+ [Explicit trace randomness](#explicit-trace-randomness)
41+
- [Do not overwrite explicit trace randomness](#do-not-overwrite-explicit-trace-randomness)
42+
- [Root samplers set explicit trace randomness for non-random TraceIDs](#root-samplers-set-explicit-trace-randomness-for-non-random-traceids)
43+
+ [Presumption of TraceID randomness](#presumption-of-traceid-randomness)
44+
+ [IdGenerator randomness](#idgenerator-randomness)
3645
- [Span Limits](#span-limits)
3746
- [Id Generators](#id-generators)
47+
* [IdGenerator randomness](#idgenerator-randomness-1)
3848
- [Span processor](#span-processor)
3949
* [Interface definition](#interface-definition)
4050
+ [OnStart](#onstart)
@@ -263,7 +273,7 @@ The OpenTelemetry API has two properties responsible for the data collection:
263273
receive them unless the `Sampled` flag was also set.
264274
* `Sampled` flag in `TraceFlags` on `SpanContext`. This flag is propagated via
265275
the `SpanContext` to child Spans. For more details see the [W3C Trace Context
266-
specification](https://www.w3.org/TR/trace-context/#sampled-flag). This flag indicates that the `Span` has been
276+
specification][W3CCONTEXTSAMPLEDFLAG]. This flag indicates that the `Span` has been
267277
`sampled` and will be exported. [Span Exporters](#span-exporter) MUST
268278
receive those spans which have `Sampled` flag set to true and they SHOULD NOT receive the ones
269279
that do not.
@@ -298,10 +308,7 @@ When asked to create a Span, the SDK MUST act as if doing the following in order
298308
1. If there is a valid parent trace ID, use it. Otherwise generate a new trace ID
299309
(note: this must be done before calling `ShouldSample`, because it expects
300310
a valid trace ID as input).
301-
2. Query the `Sampler`'s [`ShouldSample`](#shouldsample) method
302-
(Note that the [built-in `ParentBasedSampler`](#parentbased) can be used to
303-
use the sampling decision of the parent,
304-
translating a set SampledFlag to RECORD and an unset one to DROP).
311+
2. Query the `Sampler`'s [`ShouldSample`](#shouldsample) method.
305312
3. Generate a new span ID for the `Span`, independently of the sampling decision.
306313
This is done so other components (such as logs or exception handling) can rely on
307314
a unique span ID, even if the `Span` is a non-recording instance.
@@ -314,6 +321,14 @@ When asked to create a Span, the SDK MUST act as if doing the following in order
314321
`Span` is created without an SDK installed or as described in
315322
[wrapping a SpanContext in a Span](api.md#wrapping-a-spancontext-in-a-span).
316323

324+
#### Span flags
325+
326+
The OTLP representation for Span and Span Link includes a 32-bit field declared as Span Flags.
327+
328+
Bits 0-7 (8 least significant bits) of the Span Flags field are reserved for the 8 bits of Trace Context flags,
329+
specified in the [W3C Trace Context Level 2][W3CCONTEXTMAIN] Candidate Recommendation.
330+
[See the list of recognized flags](./api.md#spancontext).
331+
317332
### Sampler
318333

319334
`Sampler` interface allows users to create custom samplers which will return a
@@ -464,6 +479,80 @@ The following configuration properties should be available when creating the sam
464479
[jaeger-remote-sampling-api]: https://www.jaegertracing.io/docs/1.41/apis/#remote-sampling-configuration-stable
465480
[jaeger-adaptive-sampling]: https://www.jaegertracing.io/docs/1.41/sampling/#adaptive-sampling
466481

482+
### Sampling Requirements
483+
484+
**Status**: [Development](../document-status.md)
485+
486+
The [W3C Trace Context Level 2][W3CCONTEXTMAIN] Candidate Recommendation includes [a Random trace flag][W3CCONTEXTRANDOMFLAG] for indicating that the TraceID contains 56 random bits, specified for statistical purposes.
487+
This flag indicates that [the least-significant ("rightmost") 7 bytes or 56 bits of the TraceID are random][W3CCONTEXTTRACEID].
488+
489+
Note the Random flag does not propagate through [Trace Context Level 1][W3CCONTEXTLEVEL1] implementations, which do not recognize the flag.
490+
When this flag is 1, it is considered meaningful. When this flag is 0, it may be due to a non-random TraceID or because a Trace Context Level 1 propagator was used.
491+
To enable sampling in this and other situations where TraceIDs lack sufficient randomness,
492+
OpenTelemetry defines an optional [explicit randomness value][OTELRVALUE] encoded in the [W3C TraceState field][W3CCONTEXTTRACESTATE].
493+
494+
This specification recommends the use of either TraceID randomness or explicit trace randomness,
495+
which ensures that samplers always have sufficient randomness when using W3C Trace Context propagation.
496+
497+
[W3CCONTEXTMAIN]: https://www.w3.org/TR/trace-context-2
498+
[W3CCONTEXTLEVEL1]: https://www.w3.org/TR/trace-context
499+
[W3CCONTEXTTRACEID]: https://www.w3.org/TR/trace-context-2/#randomness-of-trace-id
500+
[W3CCONTEXTTRACESTATE]: https://www.w3.org/TR/trace-context-2/#tracestate-header
501+
[W3CCONTEXTSAMPLEDFLAG]: https://www.w3.org/TR/trace-context-2/#sampled-flag
502+
[W3CCONTEXTRANDOMFLAG]: https://www.w3.org/TR/trace-context-2/#random-trace-id-flag
503+
[OTELRVALUE]: ./tracestate-handling.md#explicit-randomness-value-rv
504+
505+
#### TraceID randomness
506+
507+
For root span contexts, the SDK SHOULD implement the TraceID randomness requirements of the [W3C Trace Context Level 2][W3CCONTEXTTRACEID] Candidate Recommendation when generating TraceID values.
508+
509+
#### Random trace flag
510+
511+
For root span contexts, the SDK SHOULD set the `Random` flag in the trace flags when it generates TraceIDs that meet the [W3C Trace Context Level 2 randomness requirements][W3CCONTEXTTRACEID].
512+
513+
#### Explicit trace randomness
514+
515+
Explicit trace randomness is a mechanism that enables API users and
516+
SDK authors to control trace randomness. The following recommendation
517+
applies to Trace SDKs that have disregarded the recommendation on
518+
TraceID randomness, above. It has two parts.
519+
520+
##### Do not overwrite explicit trace randomness
521+
522+
API users control the initial TraceState of a root span, so they can
523+
provide explicit trace randomness for a trace by defining the [`rv`
524+
sub-key of the OpenTelemetry TraceState][OTELRVALUE]. SDKs and Samplers
525+
MUST NOT overwrite explicit trace randomness in an OpenTelemetry TraceState
526+
value.
527+
528+
##### Root samplers set explicit trace randomness for non-random TraceIDs
529+
530+
When the SDK has generated a TraceID that does not meet the [W3C Trace
531+
Context Level 2 randomness requirements][W3CCONTEXTTRACEID], indicated
532+
by an unset trace random flag, and when the the [`rv` sub-key of the
533+
OpenTelemetry TraceState][OTELRVALUE] is not already set, the Root
534+
sampler has the opportunity to insert explicit trace randomness.
535+
536+
Root Samplers MAY insert an explicit trace randomness value into the
537+
OpenTelemetry TraceState value in cases where an explicit trace
538+
randomness value is not already set.
539+
540+
For example, here's a W3C Trace Context with non-random identifiers and an
541+
explicit randomness value:
542+
543+
```
544+
traceparent: 00-ffffffffffffffffffffffffffffffff-ffffffffffffffff-00
545+
tracestate: ot=rv:7479cfb506891d
546+
```
547+
548+
#### Presumption of TraceID randomness
549+
550+
For all span contexts, OpenTelemetry samplers SHOULD presume that TraceIDs meet the W3C Trace Context Level 2 randomness requirements, unless an explicit randomness value is present in the [`rv` sub-key of the OpenTelemetry TraceState][OTELRVALUE].
551+
552+
#### IdGenerator randomness
553+
554+
If the SDK uses an `IdGenerator` extension point, the SDK SHOULD allow the extension to determine whether the Random flag is set when new IDs are generated.
555+
467556
## Span Limits
468557

469558
Span attributes MUST adhere to the [common rules of attribute limits](../common/README.md#attribute-limits).
@@ -532,6 +621,18 @@ Additional `IdGenerator` implementing vendor-specific protocols such as AWS
532621
X-Ray trace id generator MUST NOT be maintained or distributed as part of the
533622
Core OpenTelemetry repositories.
534623

624+
### IdGenerator randomness
625+
626+
**Status**: [Development](../document-status.md)
627+
628+
Custom implementations of the `IdGenerator` SHOULD identify themselves
629+
appropriately when all generated TraceID values meet the [W3C Trace
630+
Context Level 2 randomness requirements][W3CCONTEXTTRACEID], so that
631+
the Trace `random` flag will be set in the associated Trace contexts.
632+
This is presumed to be a static property of the `IdGenerator`
633+
implementation which can be inferred using language features, for
634+
example by extending a marker interface.
635+
535636
## Span processor
536637

537638
Span processor is an interface which allows hooks for span start and end method

specification/trace/tracestate-handling.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,3 +83,31 @@ if ok {
8383
// traceState was not updated.
8484
}
8585
```
86+
87+
## Pre-defined OpenTelemetry sub-keys
88+
89+
The following values have been defined by OpenTelemetry.
90+
91+
### Explicit randomness value `rv`
92+
93+
The OpenTelemetry TraceState `rv` sub-key defines an alternative source of randomness called the _explicit randomness value_.
94+
Values of `rv` MUST be exactly 14 lower-case hexadecimal digits:
95+
96+
```
97+
hexdigit = DIGIT ; a-f
98+
```
99+
100+
The explicit randomness value is meant to be used instead of extracting randomness from TraceIDs, therefore it contains the same number of bits as W3C Trace Context Level 2 recommends for TraceIDs.
101+
102+
Lowercase hexadecimal digits are specified to enable direct lexicographical comparison between a sampling thresohld and either the TraceID (as it appears in the `traceparent` header) or the explicit randomness value (as it appears in the `tracestate` header).
103+
104+
Explicit randomness values are meant to propagate through [span contexts](../context/README.md) unmodified.
105+
Explicit randomness values SHOULD NOT be erased from the OpenTelemetry TraceState or modified once associated with a new TraceID, so that sampling decisions made using the explicit randomness value are consistent across signals.
106+
107+
For example, here is a W3C TraceState value including an OpenTelemetry explicit randomness value:
108+
109+
```
110+
tracestate: ot=rv:6e6d1a75832a2f
111+
```
112+
113+
This corresponds with the explicit randomness value, an unsigned integer value, of 0x6e6d1a75832a2f. This randomness value is meant to be used instead of the least-significant 56 bits of the TraceID. In this example, the 56-bit fraction (i.e., 0x6e6d1a75832a2f / 0x100000000000000 = 43.1%) supports making a consistent positive sampling decision at probabilities ranging from 56.9% through 100% (i.e., rejection thresohld values 0x6e6d1a75832a2f through 0), the same as for a hexadecimal TraceID ending in 6e6d1a75832a2f without explicit randomness value.

0 commit comments

Comments
 (0)