Skip to content

Commit 41f9405

Browse files
adriancoleAloisReitbauer
authored andcommitted
Reorganizes content to reflect decisions made since last workshop (#72)
* Reorganizes content to reflect decisions made since last workshop The following is an "all-in-one" change to capture the essence of changes described since the February workshop. Notably, this includes: * lowercase concatenation naming convention (ex `traceparent`) * applied description of the multiple trace states As the two headers are tightly coupled, this places them in the same document. This is done as one change as there is pressure for folks to do implementations and so far very few changes have actually taken place. By spiking a review to integrate feedback, we are more likely to have interoperable implementations without accidentally implementing old versions of the standard. Please take this practical concern into consideration when reviewing. Fixes #57 * Weaves in feedback
1 parent 1b9d3f7 commit 41f9405

File tree

8 files changed

+264
-194
lines changed

8 files changed

+264
-194
lines changed

trace_context/HTTP_HEADER_FORMAT.md

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
# Trace Context HTTP Header Format
2+
3+
This document describes the binding of the [trace context](README.md) to `traceparent`
4+
and `tracestate` http headers.
5+
6+
## Relationship between the headers
7+
8+
The `traceparent` header represents the incoming request in a tracing system in
9+
a common format. The `tracestate` header includes the parent in a potentially
10+
vendor-specific format.
11+
12+
For example, a client traced in the congo system adds the following headers
13+
to an outbound http request.
14+
```
15+
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
16+
tracestate: congo=BleGNlZWRzIHRohbCBwbGVhc3VyZS4=
17+
```
18+
19+
If the receiving server is traced in the `rojo` tracing system, it carries
20+
the over the state it received and adds a new entry with the position in
21+
its trace.
22+
```
23+
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
24+
tracestate: rojo=00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01,congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4=
25+
```
26+
27+
You'll notice that the `rojo` system reuses the value of `traceparent` in its
28+
entry in `tracestate`. This means it is a generic tracing system. Otherwise,
29+
`tracestate` entries are opaque.
30+
31+
If the receiving server of the above is `congo` again, it continues from its
32+
last position, overwriting its entry with one representing the new parent.
33+
34+
```
35+
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b9c7c989f97918e1-01
36+
tracestate: congo=Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWF=,rojo=00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
37+
```
38+
39+
Notice when `congo` wrote its `traceparent` entry, it reuses the last trace ID
40+
which helps in consistency for those doing correlation. However, the value of
41+
its entry `tracestate` is opaque and different. This is ok.
42+
43+
Finally, you'll see `tracestate` retains an entry for `rojo` exactly as it was,
44+
except pushed to the right. The left-most position lets the next server know
45+
which tracing system corresponds with `traceparent`. In this case, since
46+
`congo` wrote `traceparent`, its `tracestate` entry should be left-most.
47+
48+
*See [rationale document](HTTP_HEADER_FORMAT_RATIONALE.md) for details of decisions made for this format.*
49+
50+
# Trace-Parent Field
51+
52+
## Header name
53+
54+
`traceparent`
55+
56+
## Field value
57+
58+
```
59+
base16(<version>)-<version_format>
60+
```
61+
62+
The value will be US-ASCII encoded (which is UTF-8 compliant). Character `-` is
63+
used as a delimiter between fields.
64+
65+
### Version
66+
67+
Is a 1-byte representing a 8-bit unsigned integer. Version 255 reserved.
68+
69+
### Version = 0
70+
71+
#### Format
72+
73+
```
74+
base16(<trace-id>)-base16(<span-id>)[-base16(<trace-options>)]
75+
```
76+
77+
`trace-id` and `span-id` are required. The `trace-options` is optional. Character `-`
78+
is used as a delimiter between fields.
79+
80+
#### Trace-id
81+
82+
Is the ID of the whole trace forest. It is represented as a 16-bytes array, e.g.,
83+
`4bf92f3577b34da6a3ce929d0e0e4736`. All bytes 0 is considered invalid.
84+
85+
Implementation may decide to completely ignore the traceparent if the trace-id is invalid.
86+
87+
#### Span-id
88+
89+
Is the ID of the caller span (parent). It is represented as a 8-bytes array, e.g.,
90+
`00f067aa0ba902b7`. All bytes 0 is considered invalid.
91+
92+
Implementation may decide to completely ignore the traceparent if the span-id is invalid.
93+
94+
#### Trace-options
95+
96+
Controls tracing options such as sampling, trace level etc. It is a 1-byte representing a 8-bit
97+
unsigned integer. The flags are recommendations given by the caller rather than strict rules to
98+
follow for 3 reasons:
99+
100+
1. Trust and abuse.
101+
2. Bug in caller
102+
3. Different load between caller service and callee service might force callee to down sample.
103+
104+
##### Bits behavior definition (01234567):
105+
* The least significant bit (the 7th bit) provides recommendation whether the request should be
106+
traced or not (`1` recommends the request should be traced, `0` means the caller does not
107+
make a decision to trace and the decision might be deferred). When `trace-options` is missing
108+
the default value for this bit is `0`
109+
* The behavior of other bits is currently undefined.
110+
111+
#### Examples of HTTP headers
112+
113+
*Valid sampled traceparent:*
114+
115+
```
116+
Value = 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
117+
base16(<Version>) = 00
118+
base16(<TraceId>) = 4bf92f3577b34da6a3ce929d0e0e4736
119+
base16(<SpanId>) = 00f067aa0ba902b7
120+
base16(<TraceOptions>) = 01 // sampled
121+
```
122+
123+
*Valid not-sampled traceparent:*
124+
125+
```
126+
Value = 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00
127+
base16(<Version>) = 00
128+
base16(<TraceId>) = 4bf92f3577b34da6a3ce929d0e0e4736
129+
base16(<SpanId>) = 00f067aa0ba902b7
130+
base16(<TraceOptions>) = 00 // not-sampled
131+
```
132+
133+
# Trace-State Field
134+
135+
## Header name
136+
137+
`tracestate`
138+
139+
## Header value
140+
141+
`vendorName1=opaqueValue1,vendorName2=opaqueValue2`
142+
143+
The value a concatenation of trace graph name-state pairs. Only one entry per
144+
name is allowed because the entry represents that last position in the trace.
145+
Hence implementors must overwrite their entry upon reentry to their tracing
146+
system.
147+
148+
For example, if tracing system name is `congo`, and a trace started in their
149+
system, went through a system named `rojo` and later returned to `congo`, the
150+
`tracestate` value would not be:
151+
152+
`congo=congosFirstPosition,rojo=rojosFirstPosition,congo=congosSecondPosition`
153+
154+
Rather, the entry would be rewritten to only include the most recent position:
155+
`congo=congosSecondPosition,rojo=rojosFirstPosition`
156+
157+
**Limits:**
158+
Maximum length of a combined header MUST be less than 512 bytes.
159+
160+
## Name format
161+
162+
Name starts with the beginning of the string or separator `,` and ends with the
163+
equal sign `=`. The contents of the name are any url encoded string that does
164+
not contain an equal sign `=`. Names should intuitively identify a the tracing
165+
system even if multiple systems per vendor are present.
166+
167+
## Value format
168+
169+
Value starts after equal sign and ends with a separator `,` or end of string.
170+
In the case of a generic tracing system, it contains the same data as the most
171+
recent `traceparent` value. Other systems may have different formatting, such
172+
as Base64 encoded opaque values.
173+
174+
# Examples of HTTP headers
175+
176+
Single tracing system (generic format):
177+
178+
```
179+
tracestate: rojo=00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
180+
```
181+
182+
Multiple tracing systems (with different formatting):
183+
184+
```
185+
tracestate: rojo=00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01,congo=lZWRzIHRoNhcm5hbCBwbGVhc3VyZS4=
186+
```
187+
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Trace Context HTTP Header Format Rationale
2+
3+
This document provides rationale for the decisions made, mapping the
4+
`Trace-Parent` and `Trace-State` fields to HTTP headers.
5+
6+
## Lowercase Concatenated header names
7+
While HTTP headers are conventionally delimited by hyphens, the trace context
8+
header names are not. Rather, they are lowercase concatenated "traceparent" and
9+
"tracestate" respectively. The departure from convention is due to practical
10+
concerns of propagation. Trace context is unlike typical http headers, which
11+
are point-to-point and do not propagate through other systems like messaging.
12+
Different systems have different constraints. For example, some cannot read
13+
case insensitively, and others forbid the hyphen character. Even if we could
14+
suggest not using the same format for such systems, we know many systems transparently
15+
copy http headers into fields. This class of concerns only exist when we choose
16+
to support mixed case with hyphens. By choosing not to, we open trace context
17+
integration beyond http at the cost of a conventional distraction.
18+
19+
## `tracestate`
20+
21+
- The names should be human readable, but values opaque. Cryptic name can
22+
interfere with identification of the tracing system responsible for an entry.
23+
- Multiple entries permitted, but not across multiple headers. Order identifies which entry is associated with the `traceparent`. Arbitrary non-tracing system entries is a non use case.
24+
- The typical name will be a single word in latin and the value will be a
25+
copy of the `traceparent` format or an opaque string.
26+
27+
### Size limits
28+
29+
Header should be small so providers can satisfy the requirement to pass the value all the time.
30+
31+
512 bytes looks like a reasonable compromise.
32+
33+
TODO: put more thoughts into it
34+
35+
### Not trimming spaces
36+
37+
The `tracestate` header is not meant to be edited by hand, and the values
38+
are opaque. Thus, optimizations such as trimming spaces before and
39+
after the comma, equal sign, etc are not handled by this specification.
40+
41+
### Case sensitivity of names
42+
43+
There are few considerations why the names should be case sensitive:
44+
- some keys may be a url query string parameters which are case sensitive
45+
- forcing lower case will decrease readability of the names written in camel case
46+
47+
### String encoding of names
48+
49+
Url encoding is low-overhead way to encode unicode characters for non-latin characters in the
50+
values. Url encoding keeps a single words in latin unchanged and easy readable.

trace_context/README.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Trace Context
2+
3+
The trace context positions an incoming request in potentially multiple trace
4+
graphs. For example, an incoming request might have information about its
5+
gateway in one service, and information from its direct upstream in another.
6+
7+
Two propagation fields carry the common and vendor-specific properties that
8+
make up the trace context.
9+
10+
* `traceparent` describes the position of the incoming request in its trace graph in a portable, fixed-length format. Its design focuses on fast parsing.
11+
12+
* `tracestate` maps all graphs the incoming parent is a part of in potentially vendor-specific formats. For example, if a request crosses tracing systems, there will be one entry in `tracestate` for each system.
13+
14+
Notably, the `tracestate` field is unreliant on data in the `traceparent`.
15+
16+
## Relationship to `Correlation-Context`
17+
18+
The trace context fields are separate from to the `Correlation-Context`, and
19+
carry ONLY properties defined by tracing systems, not user-defined properties.
20+
This way, cloud vendors and libraries may guarantee trace context transmission
21+
even if it cannot transmit large user-defined properties.
22+
23+
## HTTP Format
24+
The HTTP header format is defined [here](HTTP_HEADER_FORMAT.md) and the rationale is defined [here](HTTP_HEADER_FORMAT_RATIONALE.md).
25+
26+
## Binary Format
27+
TODO: add link here

trace_parent/HTTP_HEADER_FORMAT.md

Lines changed: 0 additions & 89 deletions
This file was deleted.

trace_parent/README.md

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)