Skip to content

Commit 7d3fe4c

Browse files
pegasascartermp
andauthored
Supply example on Document baggage propagation (open-telemetry#3716)
Co-authored-by: Phillip Carter <[email protected]>
1 parent 96e72a7 commit 7d3fe4c

File tree

1 file changed

+96
-0
lines changed

1 file changed

+96
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
---
2+
title: Propagation
3+
description: Context propagation for the Python SDK
4+
aliases: [api/propagation]
5+
weight: 65
6+
cSpell:ignore: tracestate
7+
---
8+
9+
Propagation is the mechanism that moves data between services and processes.
10+
Although not limited to tracing, it is what allows traces to build causal
11+
information about a system across services that are arbitrarily distributed
12+
across process and network boundaries.
13+
14+
## Manual W3C Trace Context Propagation
15+
16+
The following generic example demonstrates how you can propagate trace context
17+
manually.
18+
19+
First, on the sending service, you'll need to inject the current `context`:
20+
21+
```python
22+
from flask import Flask
23+
import requests
24+
from opentelemetry import trace, propagators, baggage
25+
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
26+
from opentelemetry.baggage.propagation import W3CBaggagePropagator
27+
from opentelemetry.sdk.trace import TracerProvider
28+
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, BatchSpanProcessor
29+
30+
app = Flask(__name__)
31+
32+
trace.set_tracer_provider(TracerProvider())
33+
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
34+
35+
tracer = trace.get_tracer(__name__)
36+
37+
@app.route('/')
38+
def hello():
39+
with tracer.start_as_current_span("api1_span") as span:
40+
ctx = baggage.set_baggage("hello", "world")
41+
42+
headers = {}
43+
W3CBaggagePropagator().inject(headers, ctx)
44+
TraceContextTextMapPropagator().inject(headers, ctx)
45+
print(headers)
46+
47+
response = requests.get('http://127.0.0.1:5001/', headers=headers)
48+
return f"Hello from API 1! Response from API 2: {response.text}"
49+
50+
if __name__ == '__main__':
51+
app.run(port=5002)
52+
```
53+
54+
On the receiving service, you'll need to extract `context` (for example, from
55+
parsed HTTP headers) and then set them as the current trace context.
56+
57+
```python
58+
from flask import Flask, request
59+
from opentelemetry import trace, baggage
60+
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator
61+
from opentelemetry.sdk.trace import TracerProvider
62+
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, BatchSpanProcessor
63+
from opentelemetry.baggage.propagation import W3CBaggagePropagator
64+
65+
app = Flask(__name__)
66+
67+
trace.set_tracer_provider(TracerProvider())
68+
trace.get_tracer_provider().add_span_processor(BatchSpanProcessor(ConsoleSpanExporter()))
69+
70+
tracer = trace.get_tracer(__name__)
71+
72+
@app.route('/')
73+
def hello():
74+
# Example: Log headers received in the request in API 2
75+
headers = dict(request.headers)
76+
print(f"Received headers: {headers}")
77+
carrier ={'traceparent': headers['Traceparent']}
78+
ctx = TraceContextTextMapPropagator().extract(carrier=carrier)
79+
print(f"Received context: {ctx}")
80+
81+
b2 ={'baggage': headers['Baggage']}
82+
ctx2 = W3CBaggagePropagator().extract(b2, context=ctx)
83+
print(f"Received context2: {ctx2}")
84+
85+
# Start a new span
86+
with tracer.start_span("api2_span", context=ctx2):
87+
# Use propagated context
88+
print(baggage.get_baggage('hello', ctx2))
89+
return "Hello from API 2!"
90+
91+
if __name__ == '__main__':
92+
app.run(port=5001)
93+
```
94+
95+
From there, when you have a deserialized active context, you can create spans
96+
that will be a part of the same trace from the other service.

0 commit comments

Comments
 (0)