|
| 1 | +# Binary format |
| 2 | + |
| 3 | +Binary format document describes how to encode each field - `traceparent` and |
| 4 | +`tracestate`. The binary format should be used to encode the values of these |
| 5 | +fields. This specification does not specify how these fields should be stored |
| 6 | +and sent as a part of a binary payload. The basic implementation may serialize |
| 7 | +those as size of the field followed by the value. |
| 8 | + |
| 9 | +Specification operates with bytes - unsigned 8-bit integer values |
| 10 | +representing values from `0` to `255`. Byte representation as a set of |
| 11 | +bits (big or little endian) MUST be defined by underlying platform and |
| 12 | +out of scope of this specification. |
| 13 | + |
| 14 | +## `Traceparent` binary format |
| 15 | + |
| 16 | +The field `traceparent` encodes the version of the protocol and fields |
| 17 | +`trace-id`, `parent-id` and `trace-flags`. Each field starts with the one byte |
| 18 | +field identifier with the field value following immediately after it. Field |
| 19 | +identifiers are used as markers for additional verification of the value |
| 20 | +consistency and may be used in future for the versioning of the `traceparent` |
| 21 | +field. |
| 22 | + |
| 23 | +``` abnf |
| 24 | +traceparent = version version_format |
| 25 | +version = 1BYTE ; version is 0 in the current spec |
| 26 | +version_format = "{ 0x0 }" trace-id "{ 0x1 }" parent-id "{ 0x2 }" trace-flags |
| 27 | +trace-id = 16BYTES |
| 28 | +parent-id = 8BYTES |
| 29 | +trace-flags = 1BYTE ; only the least significant bit is used |
| 30 | +``` |
| 31 | + |
| 32 | +Unknown field identifier (anything beyond `0`, `1` and `2`) should be treated as |
| 33 | +invalid `traceparent`. All zeroes in `trace-id` and `parent-id` invalidates the |
| 34 | +`traceparent` as well. |
| 35 | + |
| 36 | +## Serialization of `traceparent` |
| 37 | + |
| 38 | +Implementation MUST serialize fields into the field ordering sequence. |
| 39 | +In other words, `trace-id` field should be serialized first, `parent-id` |
| 40 | +second and `trace-flags` - third. |
| 41 | + |
| 42 | +Field identifiers should be treated as unsigned byte numbers and should be |
| 43 | +encoded in big-endian bit order. |
| 44 | + |
| 45 | +Fields `trace-id` and `parent-id` are defined as a byte arrays, NOT a |
| 46 | +long numbers. First element of an array MUST be copied first. When array is |
| 47 | +represented as a memory block of 16 bytes - serialization of `trace-id` |
| 48 | +would be identical to `memcpy` method call on that memory block. This |
| 49 | +may be a concern for implementations casting these fields to integers - |
| 50 | +protocol is NOT defining whether those byte arrays are ordered as big |
| 51 | +endian or little endian and have a sign bit. |
| 52 | + |
| 53 | +If padding of the field is required (`traceparent` needs to be serialized into |
| 54 | +the bigger buffer) - any number of bytes can be appended to the end of the |
| 55 | +serialized value. |
| 56 | + |
| 57 | +## `traceparent` example |
| 58 | + |
| 59 | +``` js |
| 60 | +{0, |
| 61 | + 0, 75, 249, 47, 53, 119, 179, 77, 166, 163, 206, 146, 157, 0, 14, 71, 54, |
| 62 | + 1, 52, 240, 103, 170, 11, 169, 2, 183, |
| 63 | + 2, 1} |
| 64 | +``` |
| 65 | + |
| 66 | +This corresponds to: |
| 67 | + |
| 68 | +- `trace-id` is |
| 69 | + `{75, 249, 47, 53, 119, 179, 77, 166, 163, 206, 146, 157, 0, 14, 71, 54}` or |
| 70 | + `4bf92f3577b34da6a3ce929d000e4736`. |
| 71 | +- `parent-id` is `{52, 240, 103, 170, 11, 169, 2, 183}` or `34f067aa0ba902b7`. |
| 72 | +- `trace-flags` is `1` with the meaning `recorded` is true. |
| 73 | + |
| 74 | +## `tracestate` binary format |
| 75 | + |
| 76 | +List of up to 32 name-value pairs. Each list member starts with the 1 byte field |
| 77 | +identifier `0`. The format of list member is a single byte key length followed |
| 78 | +by the key value and single byte value length followed by the encoded |
| 79 | +value. Note, single byte length field allows keys and values up to 256 |
| 80 | +bytes long. This limit is defined by [trace |
| 81 | +context](https://w3c.github.io/trace-context/#header-value) |
| 82 | +specification. Strings are transmitted in ASCII encoding. |
| 83 | + |
| 84 | +``` abnf |
| 85 | +tracestate = list-member 0*31( list-member ) |
| 86 | +list-member = "0" key-len key value-len value |
| 87 | +key-len = 1BYTE ; length of the key string |
| 88 | +value-len = 1BYTE ; length of the value string |
| 89 | +``` |
| 90 | + |
| 91 | +Zero length key (`key-len == 0`) indicates the end of the `tracestate`. So when |
| 92 | +`tracestate` should be serialized into the buffer that is longer than it |
| 93 | +requires - `{ 0, 0 }` (field id `0` and key-len `0`) will indicate the end of |
| 94 | +the `tracestate`. |
| 95 | + |
| 96 | +## `tracestate` example |
| 97 | + |
| 98 | +``` js |
| 99 | +{ 0, 3, 102, 111, 111, 16, 51, 52, 102, 48, 54, 55, 97, 97, 48, 98, 97, 57, 48, 50, 98, 55, |
| 100 | + 0, 3, 98, 97, 114, 4, 48, 46, 50, 53, } |
| 101 | + |
| 102 | +``` |
| 103 | + |
| 104 | +This corresponds to 2 tracestate entries: |
| 105 | + |
| 106 | +`foo=34f067aa0ba902b7,bar=0.25` |
0 commit comments