How to Generate and Propagate W3C Trace Context Headers in Python
Generate and propagate W3C traceparent and tracestate headers for distributed tracing in Python, with mock service headers.
Python code
38 linesimport uuid
def generate_w3c_traceparent(trace_id=None, parent_id=None, flags="01"):
if trace_id is None:
trace_id = uuid.uuid4().hex[:32]
if parent_id is None:
parent_id = uuid.uuid4().hex[:16]
return f"00-{trace_id}-{parent_id}-{flags}"
def create_mock_headers(service_name, trace_id=None, parent_id=None):
traceparent = generate_w3c_traceparent(trace_id, parent_id)
tracestate = f"{service_name}=mock:{traceparent[:8]}"
return {
"traceparent": traceparent,
"tracestate": tracestate,
}
def propagate_headers(headers, child_service_name):
traceparent = headers["traceparent"]
version, trace_id, _, flags = traceparent.split("-")
new_parent_id = uuid.uuid4().hex[:16]
child_traceparent = f"{version}-{trace_id}-{new_parent_id}-{flags}"
child_tracestate = f"{child_service_name}=mock:{child_traceparent[:8]}"
return {
"traceparent": child_traceparent,
"tracestate": child_tracestate,
}
if __name__ == "__main__":
service_a_headers = create_mock_headers("svc-a")
print("Service A headers:", service_a_headers)
service_b_headers = propagate_headers(service_a_headers, "svc-b")
print("Service B headers:", service_b_headers)
Output
Service A headers: {'traceparent': '00-3f7b0f2c6e1d4a8b9c2e5f6a7b8c9d0e-a1b2c3d4e5f6a7b8-01', 'tracestate': 'svc-a=mock:00-3f7b0f2c'}
Service B headers: {'traceparent': '00-3f7b0f2c6e1d4a8b9c2e5f6a7b8c9d0e-9c8b7a6f5e4d3c2b-01', 'tracestate': 'svc-b=mock:00-3f7b0f2c'}
How it works
The generate_w3c_traceparent function creates a valid W3C traceparent string in the format version-trace_id-parent_id-flags. It uses uuid.uuid4().hex to generate random 128-bit trace IDs (32 hex chars) and 64-bit parent IDs (16 hex chars). The create_mock_headers function builds initial headers with a service name embedded in tracestate. The propagate_headers function parses an existing traceparent, extracts the trace_id and flags, generates a new parent_id for the child span, and returns updated headers — preserving the trace context across service calls.
Common mistakes
- Forgetting to include the version prefix '00-' in the traceparent string
- Using the same parent_id for child spans instead of generating a new one
- Hardcoding trace IDs instead of generating random UUIDs for new traces
Variations
- Use the `opentelemetry` library's `trace` module for full OpenTelemetry integration
- Parse existing traceparent headers more strictly by validating version and ID formats
Real-world use cases
- Microservices architectures where each service must forward trace IDs to propagate the same trace across distributed calls.
- Mocking trace headers in unit tests to simulate distributed tracing flows without a real tracing backend.
- Edge services generating trace headers for incoming HTTP requests before dispatching to downstream services.
Sponsored
More from Observability & SRE
- Adding a Correlation ID to Log Context in Python medium
- Calculate Error Rate from Log Stream in Python easy
- Check if a Timestamp Falls in a Daily Maintenance Window in Python easy
- Export Metrics with OTLP Mock in Python medium
- Generate Mock CPU and Memory Metrics in Python easy
- Generate Prometheus Text Exposition Format in Python easy
Keep learning
Related tutorials and quizzes for this topic.