Skip to content

Commit c0a3ea9

Browse files
committed
Expose AWS Progagator variables and update readme
1 parent ea0988a commit c0a3ea9

File tree

3 files changed

+101
-96
lines changed

3 files changed

+101
-96
lines changed

sdk-extension/opentelemetry-sdk-extension-aws/README.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ Propagator:
4141

4242
::
4343

44-
export OTEL_PYTHON_PROPAGATORS = aws_xray
44+
export OTEL_PROPAGATORS = aws_xray
4545

4646

4747
References

sdk-extension/opentelemetry-sdk-extension-aws/src/opentelemetry/sdk/extension/aws/trace/propagation/aws_xray_format.py

+81-78
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,27 @@
2424
TextMapPropagatorT,
2525
)
2626

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+
2748
_logger = logging.getLogger(__name__)
2849

2950

@@ -40,35 +61,14 @@ class AwsXRayFormat(TextMapPropagator):
4061
"""
4162

4263
# 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"
6364

6465
def extract(
6566
self,
6667
getter: Getter[TextMapPropagatorT],
6768
carrier: TextMapPropagatorT,
6869
context: typing.Optional[Context] = None,
6970
) -> 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)
7272

7373
if not trace_header_list or len(trace_header_list) != 1:
7474
return trace.set_span_in_context(
@@ -83,9 +83,11 @@ def extract(
8383
)
8484

8585
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)
8991
except AwsParseTraceHeaderError as err:
9092
_logger.debug(err.message)
9193
return trace.set_span_in_context(
@@ -116,16 +118,15 @@ def extract(
116118
trace.DefaultSpan(span_context), context=context
117119
)
118120

119-
def _extract_span_properties(self, trace_header):
121+
@staticmethod
122+
def _extract_span_properties(trace_header):
120123
trace_id = trace.INVALID_TRACE_ID
121124
span_id = trace.INVALID_SPAN_ID
122125
sampled = False
123126

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):
125128
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)
129130
key, value = key_str.strip(), value_str.strip()
130131
except ValueError as ex:
131132
raise AwsParseTraceHeaderError(
@@ -134,32 +135,32 @@ def _extract_span_properties(self, trace_header):
134135
kv_pair_str,
135136
)
136137
) 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):
139140
raise AwsParseTraceHeaderError(
140141
(
141142
"Invalid TraceId in X-Ray trace header: '%s' with value '%s'. Returning INVALID span context.",
142-
self.TRACE_HEADER_KEY,
143+
TRACE_HEADER_KEY,
143144
trace_header,
144145
)
145146
)
146147

147148
try:
148-
trace_id = self._parse_trace_id(value)
149+
trace_id = AwsXRayFormat._parse_trace_id(value)
149150
except ValueError as ex:
150151
raise AwsParseTraceHeaderError(
151152
(
152153
"Invalid TraceId in X-Ray trace header: '%s' with value '%s'. Returning INVALID span context.",
153-
self.TRACE_HEADER_KEY,
154+
TRACE_HEADER_KEY,
154155
trace_header,
155156
)
156157
) 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):
159160
raise AwsParseTraceHeaderError(
160161
(
161162
"Invalid ParentId in X-Ray trace header: '%s' with value '%s'. Returning INVALID span context.",
162-
self.TRACE_HEADER_KEY,
163+
TRACE_HEADER_KEY,
163164
trace_header,
164165
)
165166
)
@@ -170,61 +171,63 @@ def _extract_span_properties(self, trace_header):
170171
raise AwsParseTraceHeaderError(
171172
(
172173
"Invalid TraceId in X-Ray trace header: '%s' with value '%s'. Returning INVALID span context.",
173-
self.TRACE_HEADER_KEY,
174+
TRACE_HEADER_KEY,
174175
trace_header,
175176
)
176177
) 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):
179180
raise AwsParseTraceHeaderError(
180181
(
181182
"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,
183184
trace_header,
184185
)
185186
)
186187

187-
sampled = self._parse_sampled_flag(value)
188+
sampled = AwsXRayFormat._parse_sampled_flag(value)
188189

189190
return trace_id, span_id, sampled
190191

191-
def _validate_trace_id(self, trace_id_str):
192+
@staticmethod
193+
def _validate_trace_id(trace_id_str):
192194
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
199199
)
200200

201-
def _parse_trace_id(self, trace_id_str):
201+
@staticmethod
202+
def _parse_trace_id(trace_id_str):
202203
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
205205
]
206206
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
208208
]
209209
return int(timestamp_subset + unique_id_subset, 16)
210210

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
213214

214215
@staticmethod
215216
def _parse_span_id(span_id_str):
216217
return int(span_id_str, 16)
217218

218-
def _validate_sampled_flag(self, sampled_flag_str):
219+
@staticmethod
220+
def _validate_sampled_flag(sampled_flag_str):
219221
return len(
220222
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,
224226
)
225227

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
228231

229232
def inject(
230233
self,
@@ -240,37 +243,37 @@ def inject(
240243

241244
otel_trace_id = "{:032x}".format(span_context.trace_id)
242245
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:]
248251
)
249252

250253
parent_id = "{:016x}".format(span_context.span_id)
251254

252255
sampling_flag = (
253-
self.IS_SAMPLED
256+
IS_SAMPLED
254257
if span_context.trace_flags & trace.TraceFlags.SAMPLED
255-
else self.NOT_SAMPLED
258+
else NOT_SAMPLED
256259
)
257260

258261
# TODO: Add OT trace state to the X-Ray trace header
259262

260263
trace_header = (
261-
self.TRACE_ID_KEY
262-
+ self.KEY_AND_VALUE_DELIMITER
264+
TRACE_ID_KEY
265+
+ KEY_AND_VALUE_DELIMITER
263266
+ 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
267270
+ 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
271274
+ sampling_flag
272275
)
273276

274277
set_in_carrier(
275-
carrier, self.TRACE_HEADER_KEY, trace_header,
278+
carrier, TRACE_HEADER_KEY, trace_header,
276279
)

0 commit comments

Comments
 (0)