|
| 1 | +# TraceState Handling |
| 2 | + |
| 3 | +**Status**: [Experimental](../document-status.md) |
| 4 | + |
| 5 | +In alignment to the [TraceContext](https://www.w3.org/TR/trace-context/) specification, this section uses the |
| 6 | +Augmented Backus-Naur Form (ABNF) notation of [RFC5234](https://www.w3.org/TR/trace-context/#bib-rfc5234), |
| 7 | +including the DIGIT rule in that document. |
| 8 | + |
| 9 | +When setting [TraceState](api.md#tracestate) values that are part of the OTel ecosystem, |
| 10 | +they MUST all be contained in a single entry using the `ot` key, with the value being |
| 11 | +a semicolon separated list of key-value pairs such as: |
| 12 | + |
| 13 | +* `ot=p:8;r:64` |
| 14 | +* `ot=foo:bar;k1:13` |
| 15 | + |
| 16 | +The [TraceContext](https://www.w3.org/TR/trace-context/) specification defines support for multiple "tenants" each to use their own `tracestate` entry by prefixing `tenant@` to tenant-specific values in a mixed tracing environment. OpenTelemetry recognizes this syntax but does not specify an interpretation for multi-tenant `tracestate`. |
| 17 | +The list can be formally defined as: |
| 18 | + |
| 19 | +``` |
| 20 | +list = list-member *( ";" list-member ) |
| 21 | +list-member = key ":" value |
| 22 | +``` |
| 23 | + |
| 24 | +The complete list length MUST NOT exceed 256 characters, as defined by the |
| 25 | +[TraceState value section](https://www.w3.org/TR/trace-context/#value), |
| 26 | +and the used keys MUST be unique. |
| 27 | + |
| 28 | +Instrumentation libraries and clients MUST NOT use this entry, and they MUST |
| 29 | +instead use their own entry. |
| 30 | + |
| 31 | +## Key |
| 32 | + |
| 33 | +The key is an identifier that describes an OTel concern. |
| 34 | +Simple examples are `p`, `ts`, or `s1`. |
| 35 | + |
| 36 | +The key can be formally defined as: |
| 37 | + |
| 38 | +``` |
| 39 | +key = lcalpha *(lcalpha / DIGIT ) |
| 40 | +lcalpha = %x61-7A ; a-z |
| 41 | +``` |
| 42 | + |
| 43 | +Specific keys used by OTel concerns MUST be defined as part as the Specification, |
| 44 | +and hence it is forbidden to use to use any key that has not been defined in |
| 45 | +the Specification itself. |
| 46 | + |
| 47 | +## Value |
| 48 | + |
| 49 | +The value is an opaque string. Although it has no maximum allowed length, |
| 50 | +it is recommended to use short values, as the **entire** list of key-values |
| 51 | +MUST NOT exceed 256 characters. |
| 52 | + |
| 53 | +The value can be formally defined as: |
| 54 | + |
| 55 | +``` |
| 56 | +value = *(chr) |
| 57 | +chr = ucalpha / lcalpha / DIGIT / "." / "_" / "-" |
| 58 | +ucalpha = %x41-5A ; A-Z |
| 59 | +lcalpha = %x61-7A ; a-z |
| 60 | +``` |
| 61 | + |
| 62 | +## Setting values |
| 63 | + |
| 64 | +Set values MUST be either updated or added to the `ot` entry in `TraceState`, |
| 65 | +in order to preserve existing values belonging to other OTel concerns. For example, |
| 66 | +if a given concern K wants to set `k1:13`: |
| 67 | + |
| 68 | +* `ot=p:8;r:64` will become `ot=p:8;r:64;k1:13`. |
| 69 | +* `ot=p:8;k1:7;r:64` will become `ot=p8;r:64;k1:13`. Preserving the order is not required. |
| 70 | + |
| 71 | +If setting a value ends up making the entire `ot` entry exceed the 256 characters limit, |
| 72 | +SDKs are advised to abort the operation and signal the user about the error, e.g. |
| 73 | + |
| 74 | +```go |
| 75 | +traceState, ok := SetTraceStateValue(traceState, value) |
| 76 | +if ok { |
| 77 | + // Successfully set the specified value, traceState was updated. |
| 78 | +} else { |
| 79 | + // traceState was not updated. |
| 80 | +} |
| 81 | +``` |
0 commit comments