24
24
TextMapPropagatorT ,
25
25
)
26
26
27
+ TRACE_HEADER_KEY = "X-Amzn-Trace-Id"
28
+ KV_PAIR_DELIMITER = ";"
29
+ KEY_AND_VALUE_DELIMITER = "="
30
+
31
+ TRACE_ID_KEY = "Root"
32
+ TRACE_ID_LENGTH = 35
33
+ TRACE_ID_VERSION = "1"
34
+ TRACE_ID_DELIMITER = "-"
35
+ TRACE_ID_DELIMITER_INDEX_1 = 1
36
+ TRACE_ID_DELIMITER_INDEX_2 = 10
37
+ TRACE_ID_FIRST_PART_LENGTH = 8
38
+
39
+ PARENT_ID_KEY = "Parent"
40
+ PARENT_ID_LENGTH = 16
41
+
42
+ SAMPLED_FLAG_KEY = "Sampled"
43
+ SAMPLED_FLAG_LENGTH = 1
44
+ IS_SAMPLED = "1"
45
+ NOT_SAMPLED = "0"
46
+
47
+
27
48
_logger = logging .getLogger (__name__ )
28
49
29
50
@@ -40,35 +61,14 @@ class AwsXRayFormat(TextMapPropagator):
40
61
"""
41
62
42
63
# AWS
43
- TRACE_HEADER_KEY = "X-Amzn-Trace-Id"
44
-
45
- KV_PAIR_DELIMITER = ";"
46
- KEY_AND_VALUE_DELIMITER = "="
47
-
48
- TRACE_ID_KEY = "Root"
49
- TRACE_ID_LENGTH = 35
50
- TRACE_ID_VERSION = "1"
51
- TRACE_ID_DELIMITER = "-"
52
- TRACE_ID_DELIMITER_INDEX_1 = 1
53
- TRACE_ID_DELIMITER_INDEX_2 = 10
54
- TRACE_ID_FIRST_PART_LENGTH = 8
55
-
56
- PARENT_ID_KEY = "Parent"
57
- PARENT_ID_LENGTH = 16
58
-
59
- SAMPLED_FLAG_KEY = "Sampled"
60
- SAMPLED_FLAG_LENGTH = 1
61
- IS_SAMPLED = "1"
62
- NOT_SAMPLED = "0"
63
64
64
65
def extract (
65
66
self ,
66
67
getter : Getter [TextMapPropagatorT ],
67
68
carrier : TextMapPropagatorT ,
68
69
context : typing .Optional [Context ] = None ,
69
70
) -> Context :
70
- trace_header_list = getter (carrier , self .TRACE_HEADER_KEY )
71
- trace_header_list = getter .get (carrier , self .TRACE_HEADER_KEY )
71
+ trace_header_list = getter .get (carrier , TRACE_HEADER_KEY )
72
72
73
73
if not trace_header_list or len (trace_header_list ) != 1 :
74
74
return trace .set_span_in_context (
@@ -83,9 +83,11 @@ def extract(
83
83
)
84
84
85
85
try :
86
- trace_id , span_id , sampled = self ._extract_span_properties (
87
- trace_header
88
- )
86
+ (
87
+ trace_id ,
88
+ span_id ,
89
+ sampled ,
90
+ ) = AwsXRayFormat ._extract_span_properties (trace_header )
89
91
except AwsParseTraceHeaderError as err :
90
92
_logger .debug (err .message )
91
93
return trace .set_span_in_context (
@@ -116,16 +118,15 @@ def extract(
116
118
trace .DefaultSpan (span_context ), context = context
117
119
)
118
120
119
- def _extract_span_properties (self , trace_header ):
121
+ @staticmethod
122
+ def _extract_span_properties (trace_header ):
120
123
trace_id = trace .INVALID_TRACE_ID
121
124
span_id = trace .INVALID_SPAN_ID
122
125
sampled = False
123
126
124
- for kv_pair_str in trace_header .split (self . KV_PAIR_DELIMITER ):
127
+ for kv_pair_str in trace_header .split (KV_PAIR_DELIMITER ):
125
128
try :
126
- key_str , value_str = kv_pair_str .split (
127
- self .KEY_AND_VALUE_DELIMITER
128
- )
129
+ key_str , value_str = kv_pair_str .split (KEY_AND_VALUE_DELIMITER )
129
130
key , value = key_str .strip (), value_str .strip ()
130
131
except ValueError as ex :
131
132
raise AwsParseTraceHeaderError (
@@ -134,32 +135,32 @@ def _extract_span_properties(self, trace_header):
134
135
kv_pair_str ,
135
136
)
136
137
) from ex
137
- if key == self . TRACE_ID_KEY :
138
- if not self ._validate_trace_id (value ):
138
+ if key == TRACE_ID_KEY :
139
+ if not AwsXRayFormat ._validate_trace_id (value ):
139
140
raise AwsParseTraceHeaderError (
140
141
(
141
142
"Invalid TraceId in X-Ray trace header: '%s' with value '%s'. Returning INVALID span context." ,
142
- self . TRACE_HEADER_KEY ,
143
+ TRACE_HEADER_KEY ,
143
144
trace_header ,
144
145
)
145
146
)
146
147
147
148
try :
148
- trace_id = self ._parse_trace_id (value )
149
+ trace_id = AwsXRayFormat ._parse_trace_id (value )
149
150
except ValueError as ex :
150
151
raise AwsParseTraceHeaderError (
151
152
(
152
153
"Invalid TraceId in X-Ray trace header: '%s' with value '%s'. Returning INVALID span context." ,
153
- self . TRACE_HEADER_KEY ,
154
+ TRACE_HEADER_KEY ,
154
155
trace_header ,
155
156
)
156
157
) from ex
157
- elif key == self . PARENT_ID_KEY :
158
- if not self ._validate_span_id (value ):
158
+ elif key == PARENT_ID_KEY :
159
+ if not AwsXRayFormat ._validate_span_id (value ):
159
160
raise AwsParseTraceHeaderError (
160
161
(
161
162
"Invalid ParentId in X-Ray trace header: '%s' with value '%s'. Returning INVALID span context." ,
162
- self . TRACE_HEADER_KEY ,
163
+ TRACE_HEADER_KEY ,
163
164
trace_header ,
164
165
)
165
166
)
@@ -170,61 +171,63 @@ def _extract_span_properties(self, trace_header):
170
171
raise AwsParseTraceHeaderError (
171
172
(
172
173
"Invalid TraceId in X-Ray trace header: '%s' with value '%s'. Returning INVALID span context." ,
173
- self . TRACE_HEADER_KEY ,
174
+ TRACE_HEADER_KEY ,
174
175
trace_header ,
175
176
)
176
177
) from ex
177
- elif key == self . SAMPLED_FLAG_KEY :
178
- if not self ._validate_sampled_flag (value ):
178
+ elif key == SAMPLED_FLAG_KEY :
179
+ if not AwsXRayFormat ._validate_sampled_flag (value ):
179
180
raise AwsParseTraceHeaderError (
180
181
(
181
182
"Invalid Sampling flag in X-Ray trace header: '%s' with value '%s'. Returning INVALID span context." ,
182
- self . TRACE_HEADER_KEY ,
183
+ TRACE_HEADER_KEY ,
183
184
trace_header ,
184
185
)
185
186
)
186
187
187
- sampled = self ._parse_sampled_flag (value )
188
+ sampled = AwsXRayFormat ._parse_sampled_flag (value )
188
189
189
190
return trace_id , span_id , sampled
190
191
191
- def _validate_trace_id (self , trace_id_str ):
192
+ @staticmethod
193
+ def _validate_trace_id (trace_id_str ):
192
194
return (
193
- len (trace_id_str ) == self .TRACE_ID_LENGTH
194
- and trace_id_str .startswith (self .TRACE_ID_VERSION )
195
- and trace_id_str [self .TRACE_ID_DELIMITER_INDEX_1 ]
196
- == self .TRACE_ID_DELIMITER
197
- and trace_id_str [self .TRACE_ID_DELIMITER_INDEX_2 ]
198
- == self .TRACE_ID_DELIMITER
195
+ len (trace_id_str ) == TRACE_ID_LENGTH
196
+ and trace_id_str .startswith (TRACE_ID_VERSION )
197
+ and trace_id_str [TRACE_ID_DELIMITER_INDEX_1 ] == TRACE_ID_DELIMITER
198
+ and trace_id_str [TRACE_ID_DELIMITER_INDEX_2 ] == TRACE_ID_DELIMITER
199
199
)
200
200
201
- def _parse_trace_id (self , trace_id_str ):
201
+ @staticmethod
202
+ def _parse_trace_id (trace_id_str ):
202
203
timestamp_subset = trace_id_str [
203
- self .TRACE_ID_DELIMITER_INDEX_1
204
- + 1 : self .TRACE_ID_DELIMITER_INDEX_2
204
+ TRACE_ID_DELIMITER_INDEX_1 + 1 : TRACE_ID_DELIMITER_INDEX_2
205
205
]
206
206
unique_id_subset = trace_id_str [
207
- self . TRACE_ID_DELIMITER_INDEX_2 + 1 : self . TRACE_ID_LENGTH
207
+ TRACE_ID_DELIMITER_INDEX_2 + 1 : TRACE_ID_LENGTH
208
208
]
209
209
return int (timestamp_subset + unique_id_subset , 16 )
210
210
211
- def _validate_span_id (self , span_id_str ):
212
- return len (span_id_str ) == self .PARENT_ID_LENGTH
211
+ @staticmethod
212
+ def _validate_span_id (span_id_str ):
213
+ return len (span_id_str ) == PARENT_ID_LENGTH
213
214
214
215
@staticmethod
215
216
def _parse_span_id (span_id_str ):
216
217
return int (span_id_str , 16 )
217
218
218
- def _validate_sampled_flag (self , sampled_flag_str ):
219
+ @staticmethod
220
+ def _validate_sampled_flag (sampled_flag_str ):
219
221
return len (
220
222
sampled_flag_str
221
- ) == self . SAMPLED_FLAG_LENGTH and sampled_flag_str in (
222
- self . IS_SAMPLED ,
223
- self . NOT_SAMPLED ,
223
+ ) == SAMPLED_FLAG_LENGTH and sampled_flag_str in (
224
+ IS_SAMPLED ,
225
+ NOT_SAMPLED ,
224
226
)
225
227
226
- def _parse_sampled_flag (self , sampled_flag_str ):
227
- return sampled_flag_str [0 ] == self .IS_SAMPLED
228
+ @staticmethod
229
+ def _parse_sampled_flag (sampled_flag_str ):
230
+ return sampled_flag_str [0 ] == IS_SAMPLED
228
231
229
232
def inject (
230
233
self ,
@@ -240,37 +243,37 @@ def inject(
240
243
241
244
otel_trace_id = "{:032x}" .format (span_context .trace_id )
242
245
xray_trace_id = (
243
- self . TRACE_ID_VERSION
244
- + self . TRACE_ID_DELIMITER
245
- + otel_trace_id [: self . TRACE_ID_FIRST_PART_LENGTH ]
246
- + self . TRACE_ID_DELIMITER
247
- + otel_trace_id [self . TRACE_ID_FIRST_PART_LENGTH :]
246
+ TRACE_ID_VERSION
247
+ + TRACE_ID_DELIMITER
248
+ + otel_trace_id [:TRACE_ID_FIRST_PART_LENGTH ]
249
+ + TRACE_ID_DELIMITER
250
+ + otel_trace_id [TRACE_ID_FIRST_PART_LENGTH :]
248
251
)
249
252
250
253
parent_id = "{:016x}" .format (span_context .span_id )
251
254
252
255
sampling_flag = (
253
- self . IS_SAMPLED
256
+ IS_SAMPLED
254
257
if span_context .trace_flags & trace .TraceFlags .SAMPLED
255
- else self . NOT_SAMPLED
258
+ else NOT_SAMPLED
256
259
)
257
260
258
261
# TODO: Add OT trace state to the X-Ray trace header
259
262
260
263
trace_header = (
261
- self . TRACE_ID_KEY
262
- + self . KEY_AND_VALUE_DELIMITER
264
+ TRACE_ID_KEY
265
+ + KEY_AND_VALUE_DELIMITER
263
266
+ xray_trace_id
264
- + self . KV_PAIR_DELIMITER
265
- + self . PARENT_ID_KEY
266
- + self . KEY_AND_VALUE_DELIMITER
267
+ + KV_PAIR_DELIMITER
268
+ + PARENT_ID_KEY
269
+ + KEY_AND_VALUE_DELIMITER
267
270
+ parent_id
268
- + self . KV_PAIR_DELIMITER
269
- + self . SAMPLED_FLAG_KEY
270
- + self . KEY_AND_VALUE_DELIMITER
271
+ + KV_PAIR_DELIMITER
272
+ + SAMPLED_FLAG_KEY
273
+ + KEY_AND_VALUE_DELIMITER
271
274
+ sampling_flag
272
275
)
273
276
274
277
set_in_carrier (
275
- carrier , self . TRACE_HEADER_KEY , trace_header ,
278
+ carrier , TRACE_HEADER_KEY , trace_header ,
276
279
)
0 commit comments