W3C Trace Context Specification

repository·main·Indexed 19 days ago

https://github.com/w3c/trace-context

A standardized format for propagating distributed tracing context across heterogeneous systems to enable interoperable observability. The specification defines the use of two HTTP headers: 'traceparent' for a portable, fixed-length correlation format and 'tracestate' for vendor-specific extensibility. It outlines compliance levels for forwarding and participating in traces, as well as guidelines for header formatting, mutation, and versioning.

Tokens
8.3K
Snippets
7
Records
44
Agent score
64%

What's inside W3C Trace Context

  1. What is the Trace Context Specification?

    main

    The Trace Context Specification defines a standardized format for propagating distributed tracing context across different systems. This allows various tracing and diagnostics products to operate together interoperably.

    • Trace Context v1 is a W3C Recommendation.
    • The current development for the next version of the specification takes place in this repository.
    • For technical justifications regarding specific design decisions, refer to the Rationale document.
  2. What is trace context and why is it used?

    main

    Trace context is a standardized format for exchanging distributed tracing data across multiple software components. It enables interoperability in multi-vendor environments by providing a shared unique identifier for traces and requests. This allows different tracing tools to correlate data, prevents traces from breaking when crossing vendor boundaries, and provides a standard for intermediaries and cloud platforms to support.

    Key benefits include:

    • Correlation: Linking trace data from different providers using a shared identifier.
    • Propagation: Ensuring vendor-specific metadata is forwarded correctly.
    • Standardization: Providing a predictable format for hardware, platforms, and service providers.
  3. Use the Random Trace ID flag in Trace Context metrics

    main

    The random-trace-id flag is the second least significant bit of the trace-flags field. It allows participants to determine if a trace-id was generated according to specification.

    Rules for Participants:

    • Continuing an upstream trace: If you use the trace-id from an incoming traceparent header, you MUST set the random-trace-id flag to the same value found in that header.
    • Continuing a downstream trace: If you use a trace-id from a received trace-context server timing metric, you MUST set the random-trace-id flag to the same value found in that metric.
    • Starting/Restarting a trace: If you generate a new trace-id, follow the standard requirements for the random-trace-id flag defined in the traceparent specification.
  4. Avoid PII in traceparent and tracestate headers

    main

    Tracing vendors MUST NOT use the traceparent or tracestate fields to store personally identifiable information (PII) or any other sensitive data. The sole purpose of these fields is to enable trace correlation across distributed systems.

    To ensure privacy when generating traceparent IDs:

    • Use a random number generator that does not expose PII.
    • Ensure the generator does not rely on any PII as input or seed state.
    • If necessary, services may choose to restart (regenerate) the traceparent field to eliminate correlation risks, though vendors SHOULD aim to minimize restarts to maintain interoperability.
  5. Understand the Trace Context HTTP header format

    main

    Trace context uses two specific HTTP headers for propagation: traceparent and tracestate.

    Unlike conventional HTTP headers that use hyphens as delimiters, these headers use lowercase concatenated names. This design choice ensures better compatibility with diverse systems (like messaging queues) that may have constraints regarding case sensitivity or the use of hyphens.

    Key requirements:

    • All parts of the traceparent header are required (it does not support optional fields like trace-flags or trace-id-only versions).
    • tracestate is used for vendor-specific interoperability and extensibility.
  6. Understand the relationship between traceparent and tracestate headers

    main

    The Trace Context specification uses two primary HTTP headers to propagate distributed tracing context: traceparent and tracestate.

    • traceparent: A standardized, vendor-neutral header that represents the incoming request in a common format understood by all tracing systems. It is the primary mechanism for correlation.
    • tracestate: A header used to carry vendor-specific information. It allows different tracing systems (e.g., Congo and Rojo) to coexist in a single trace by passing proprietary metadata alongside the standard traceparent.

    Propagation Pattern: When a service receives these headers, it must carry them forward to outbound requests. If a service uses a specific tracing vendor, it should add its own entry to the tracestate header at the left-most position. This ensures the next receiver knows which system corresponds with the current traceparent context.

    # Example of a client using Congo tracing system
    traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
    tracestate: congo=t61rcWkgMzE
    
    # Example of a receiving server using Rojo tracing system
    # It carries over the existing tracestate and adds its own entry to the left
    traceparent: 00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01
    tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE
  7. Prevent Denial of Service (DoS) via tracing overhead

    main

    If a service with a public API naively continues any trace where the sampled flag is set, attackers can cause Denial of Service by:

    • Overwhelming the application with tracing overhead.
    • Forging trace-id collisions to make monitoring data unusable.
    • Increasing costs by inflating tracing data sent to SaaS vendors.

    Mitigation strategies for tracing vendors and platforms include:

    • Implementing different tracing behaviors for authenticated vs. unauthenticated requests.
    • Using rate limiters for data recording to protect against malicious or poorly authored callers.
  8. Handle privacy in the tracestate field

    main

    The tracestate header is intended for vendor-specific, opaque trace-identification information.

    • Prohibition: Vendors MUST NOT include PII in the tracestate header.
    • Mutation Policy: Vendors SHOULD NOT mutate the tracestate field, as doing so prevents multiple tracing systems from collaborating.
    • Mitigation: Vendors who are extremely sensitive to PII exposure MAY implement selective removal of values corresponding to unknown keys.
  9. Generate unique and random `span-id` values

    main

    When implementing span-id generation algorithms for trace context, follow these two primary requirements to ensure interoperability and prevent trace ambiguity:

    1. Uniqueness: The span-id SHOULD be unique within a distributed trace. Non-unique IDs can cause ambiguity in parent-child relationships between spans.
    2. Randomness: Values SHOULD be randomly generated. Randomness helps prevent the exposure of sensitive information (security/privacy) and provides a high probability of uniqueness within a distributed trace.
  10. Respect `tracestate` size and element limits

    main

    Because tracestate is often propagated through messaging systems where metadata costs are a concern, implementers should follow these recommendations to ensure successful propagation:

    • Total Size: There is no strictly enforced maximum length, but implementers should treat the specification's suggested limits as a guide. To ensure essential data is not lost, it is recommended to cut entries larger than 128 characters first when trimming the header.
    • Maximum Elements: A reasonable compromise for the maximum number of key-value elements in tracestate is 32.
    • Trimming Strategy: When the size limit is reached, implementers should remove the least important (oldest/end-of-list) entries first.
  11. Handle unknown trace context versions

    main

    When encountering an unknown version in the trace context, developers have three primary strategies for versioning support:

    1. Pass through unknown headers: The least favorable option, as a single malformed or unknown header can break the entire distributed trace.
    2. Restart the trace: A better approach that avoids restricting future versions. If an unknown header is seen, the system starts a new trace. This limits the impact of a single component breaking the trace to just one 'connection'. To mitigate data loss, the original unrecognized header can be stored in tracestate, though this consumes space (a valid traceparent is 55 characters) and increases the risk of header abuse.
    3. Parse with fallback: Attempt to parse individual parts of the header (like trace-id) and fallback to restarting the trace if parsing fails. Note that the specification suggests future versions should be additive to the current format to prevent abuse.

    If you choose to store the original unrecognized header in tracestate, be aware of the 512-character limit for tracestate and the potential for bad actors to use high version numbers to build custom solutions that bypass standard processing.

  12. How trace context propagation fields work

    main

    Trace context is composed of two distinct propagation fields designed to balance interoperability with extensibility:

    1. traceparent: A portable, fixed-length format that describes the position of an incoming request within its trace graph. It is designed for fast parsing. All tracing tools MUST properly set this header, even if they primarily rely on vendor-specific data.
    2. tracestate: An optional field used to extend traceparent with vendor-specific data, represented as a set of name/value pairs.

    By separating these, the specification allows for a core standard (traceparent) while permitting proprietary extensions (tracestate).