0
# OpenTelemetry Jaeger Propagator
1
2
OpenTelemetry Jaeger Propagator enables seamless integration between OpenTelemetry tracing and Jaeger by handling the conversion of trace context between OpenTelemetry's internal representation and Jaeger's uber-trace-id format. It implements the TextMapPropagator interface to extract and inject trace information including trace IDs, span IDs, parent span relationships, and baggage data across service boundaries, supporting both trace sampling flags and debug modes.
3
4
## Package Information
5
6
- **Package Name**: opentelemetry-propagator-jaeger
7
- **Language**: Python
8
- **Installation**: `pip install opentelemetry-propagator-jaeger`
9
- **Requires Python**: >=3.9
10
- **Dependencies**: `opentelemetry-api ~= 1.3`
11
12
## Core Imports
13
14
```python
15
from opentelemetry.propagators.jaeger import JaegerPropagator
16
```
17
18
Entry point import (when using OpenTelemetry's propagator registry):
19
20
```python
21
# Via entry point configuration
22
from opentelemetry.propagate import get_global_textmap
23
# JaegerPropagator registered as 'jaeger' entry point
24
```
25
26
## Basic Usage
27
28
```python
29
from opentelemetry.propagators.jaeger import JaegerPropagator
30
from opentelemetry import trace
31
from opentelemetry.context import Context
32
33
# Create propagator instance
34
propagator = JaegerPropagator()
35
36
# Extract trace context from incoming HTTP headers
37
incoming_headers = {
38
"uber-trace-id": "000000000000000000000000deadbeef:00000000deadbef0:00000000:01"
39
}
40
context = propagator.extract(incoming_headers)
41
42
# Get current span from context
43
span = trace.get_current_span(context)
44
span_context = span.get_span_context()
45
46
# Inject trace context into outgoing HTTP headers
47
outgoing_headers = {}
48
propagator.inject(outgoing_headers, context=context)
49
print(outgoing_headers) # Contains uber-trace-id header
50
51
# Check fields used by propagator
52
print(propagator.fields) # {'uber-trace-id'}
53
```
54
55
## Architecture
56
57
The JaegerPropagator implements OpenTelemetry's TextMapPropagator interface to provide bidirectional conversion between OpenTelemetry trace contexts and Jaeger's uber-trace-id format. The propagator handles:
58
59
- **Trace Context Extraction**: Parses Jaeger uber-trace-id headers into OpenTelemetry SpanContext objects
60
- **Trace Context Injection**: Formats OpenTelemetry trace information into Jaeger uber-trace-id headers
61
- **Baggage Propagation**: Handles baggage key-value pairs using uberctx- prefixed headers
62
- **Flag Management**: Preserves sampling and debug flags between formats
63
- **Error Handling**: Graceful handling of invalid or malformed trace headers
64
65
The uber-trace-id format follows the pattern: `{trace-id}:{span-id}:{parent-span-id}:{flags}`
66
67
## Capabilities
68
69
### Trace Context Extraction
70
71
Extracts trace context from carrier headers using Jaeger's uber-trace-id format, creating OpenTelemetry SpanContext objects with proper trace relationships and flags.
72
73
```python { .api }
74
def extract(
75
self,
76
carrier: CarrierT,
77
context: typing.Optional[Context] = None,
78
getter: Getter = default_getter,
79
) -> Context:
80
"""
81
Extract trace context from carrier using Jaeger format.
82
83
Parameters:
84
- carrier: The carrier containing trace headers (typically HTTP headers dict)
85
- context: Optional existing context to merge with extracted context
86
- getter: Getter implementation for extracting values from carrier
87
88
Returns:
89
Context with extracted trace information and baggage
90
"""
91
```
92
93
Usage example:
94
95
```python
96
from opentelemetry.propagators.jaeger import JaegerPropagator
97
98
propagator = JaegerPropagator()
99
100
# Extract from HTTP headers
101
headers = {
102
"uber-trace-id": "000000000000000000000000deadbeef:00000000deadbef0:00000000:01",
103
"uberctx-user-id": "john.doe",
104
"uberctx-session": "abc123"
105
}
106
107
context = propagator.extract(headers)
108
span = trace.get_current_span(context)
109
print(f"Trace ID: {span.get_span_context().trace_id}")
110
```
111
112
### Trace Context Injection
113
114
Injects trace context into carrier headers using Jaeger's uber-trace-id format, including baggage propagation with uberctx- prefixed headers.
115
116
```python { .api }
117
def inject(
118
self,
119
carrier: CarrierT,
120
context: typing.Optional[Context] = None,
121
setter: Setter = default_setter,
122
) -> None:
123
"""
124
Inject trace context into carrier using Jaeger format.
125
126
Parameters:
127
- carrier: The carrier to inject headers into (typically HTTP headers dict)
128
- context: Optional context containing trace information (uses current if None)
129
- setter: Setter implementation for injecting values into carrier
130
131
Returns:
132
None (modifies carrier in-place)
133
134
Note: When injecting sampled traces, the DEBUG_FLAG (0x02) is OR'd with
135
existing trace flags in the uber-trace-id format.
136
"""
137
```
138
139
Usage example:
140
141
```python
142
from opentelemetry.propagators.jaeger import JaegerPropagator
143
from opentelemetry import baggage, trace
144
145
propagator = JaegerPropagator()
146
147
# Set baggage in current context
148
context = baggage.set_baggage("user-id", "john.doe")
149
context = baggage.set_baggage("session", "abc123", context)
150
151
# Inject into HTTP headers
152
headers = {}
153
propagator.inject(headers, context=context)
154
print(headers)
155
# Output: {'uber-trace-id': '...', 'uberctx-user-id': 'john.doe', 'uberctx-session': 'abc123'}
156
```
157
158
### Propagator Fields
159
160
Returns the set of header field names used by this propagator for trace context propagation.
161
162
```python { .api }
163
@property
164
def fields(self) -> typing.Set[str]:
165
"""
166
Get the fields used by this propagator.
167
168
Returns:
169
Set of header field names used for trace propagation
170
"""
171
```
172
173
Usage example:
174
175
```python
176
from opentelemetry.propagators.jaeger import JaegerPropagator
177
178
propagator = JaegerPropagator()
179
print(propagator.fields) # {'uber-trace-id'}
180
```
181
182
## Constants
183
184
The JaegerPropagator class defines several constants used in Jaeger trace propagation:
185
186
```python { .api }
187
class JaegerPropagator(TextMapPropagator):
188
TRACE_ID_KEY = "uber-trace-id" # Header key for Jaeger trace ID
189
BAGGAGE_PREFIX = "uberctx-" # Prefix for baggage headers
190
DEBUG_FLAG = 0x02 # Debug flag OR'd with sampled traces
191
```
192
193
## Types
194
195
### CarrierT
196
197
```python { .api }
198
CarrierT = typing.TypeVar('CarrierT')
199
```
200
201
Type variable representing the carrier object (typically a dictionary for HTTP headers).
202
203
### Getter
204
205
```python { .api }
206
class Getter(typing.Protocol):
207
def get(self, carrier: CarrierT, key: str) -> typing.Optional[typing.List[str]]: ...
208
def keys(self, carrier: CarrierT) -> typing.List[str]: ...
209
```
210
211
Protocol for extracting values from carriers. The default_getter handles dictionary-like carriers.
212
213
### Setter
214
215
```python { .api }
216
class Setter(typing.Protocol):
217
def set(self, carrier: CarrierT, key: str, value: str) -> None: ...
218
```
219
220
Protocol for setting values in carriers. The default_setter handles dictionary-like carriers.
221
222
### Context
223
224
```python { .api }
225
from opentelemetry.context import Context
226
```
227
228
OpenTelemetry context object that holds trace and baggage information.
229
230
## Error Handling
231
232
The propagator handles various error conditions gracefully:
233
234
- **Missing trace headers**: Returns the original context unchanged
235
- **Invalid trace ID format**: Ignores malformed trace information, still extracts baggage
236
- **Invalid hex values**: Falls back to invalid trace/span IDs while preserving other data
237
- **Non-recording spans**: Handles injection without crashing
238
239
Example with invalid trace header:
240
241
```python
242
from opentelemetry.propagators.jaeger import JaegerPropagator
243
244
propagator = JaegerPropagator()
245
246
# Invalid trace header (wrong number of components)
247
headers = {
248
"uber-trace-id": "invalid:format",
249
"uberctx-user-id": "john.doe" # Baggage still extracted
250
}
251
252
context = propagator.extract(headers)
253
# Trace context will be invalid, but baggage is still available
254
```
255
256
## Integration with OpenTelemetry
257
258
The JaegerPropagator is registered as an OpenTelemetry propagator plugin and can be used with the OpenTelemetry SDK:
259
260
```python
261
from opentelemetry import propagate
262
from opentelemetry.propagators.jaeger import JaegerPropagator
263
264
# Register as global propagator
265
propagate.set_global_textmap(JaegerPropagator())
266
267
# Or combine with other propagators
268
from opentelemetry.propagators.composite import CompositePropagator
269
from opentelemetry.propagators.b3 import B3SingleFormatPropagator
270
271
composite = CompositePropagator([
272
JaegerPropagator(),
273
B3SingleFormatPropagator()
274
])
275
propagate.set_global_textmap(composite)
276
```