Skip to content

Commit 67c4eb1

Browse files
committed
aws-xray-propagator: ensure trace state is not overwritten
1 parent b232b9a commit 67c4eb1

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

propagator/opentelemetry-propagator-aws-xray/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
- Update `opentelemetry-api` version to 1.16
1111
([#2961](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2961))
12+
- aws-xray-propagator: ensure trace state is not overwritten
13+
([#3774](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/3774))
1214

1315
## Version 1.0.2 (2024-08-05)
1416

propagator/opentelemetry-propagator-aws-xray/src/opentelemetry/propagators/aws/aws_xray_propagator.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
default_getter,
7171
default_setter,
7272
)
73+
from opentelemetry.trace.span import TraceState
7374

7475
TRACE_HEADER_KEY = "X-Amzn-Trace-Id"
7576
AWS_TRACE_HEADER_ENV_KEY = "_X_AMZN_TRACE_ID"
@@ -92,6 +93,8 @@
9293
IS_SAMPLED = "1"
9394
NOT_SAMPLED = "0"
9495

96+
TRACESTATE_HEADER_KEY = "tracestate"
97+
9598

9699
_logger = logging.getLogger(__name__)
97100

@@ -144,12 +147,18 @@ def extract(
144147
if sampled:
145148
options |= trace.TraceFlags.SAMPLED
146149

150+
tracestate_headers = getter.get(carrier, TRACESTATE_HEADER_KEY)
151+
if tracestate_headers is None:
152+
tracestate = trace.TraceState()
153+
else:
154+
tracestate = TraceState.from_header(tracestate_headers)
155+
147156
span_context = trace.SpanContext(
148157
trace_id=trace_id,
149158
span_id=span_id,
150159
is_remote=True,
151160
trace_flags=trace.TraceFlags(options),
152-
trace_state=trace.TraceState(),
161+
trace_state=tracestate,
153162
)
154163

155164
if not span_context.is_valid:

propagator/opentelemetry-propagator-aws-xray/tests/test_aws_xray_propagator.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from opentelemetry.context import Context
2222
from opentelemetry.propagators.aws.aws_xray_propagator import (
2323
TRACE_HEADER_KEY,
24+
TRACESTATE_HEADER_KEY,
2425
AwsXRayPropagator,
2526
)
2627
from opentelemetry.trace import (
@@ -335,3 +336,19 @@ def test_fields(self, mock_trace):
335336
self.assertEqual(
336337
AwsXRayPropagatorTest.XRAY_PROPAGATOR.fields, inject_fields
337338
)
339+
340+
def test_extract_trace_state_from_headers(self):
341+
"""Test that extract properly propagates the trace state without modification."""
342+
context_with_extracted = AwsXRayPropagatorTest.XRAY_PROPAGATOR.extract(
343+
CaseInsensitiveDict(
344+
{
345+
TRACE_HEADER_KEY: "Root=1-8a3c60f7-d188f8fa79d48a391a778fa6;Parent=53995c3f42cd8ad8;Sampled=0",
346+
TRACESTATE_HEADER_KEY: "foo=bar,baz=qux"
347+
}
348+
),
349+
)
350+
351+
extracted_span_context = get_nested_span_context(context_with_extracted)
352+
expected_trace_state = TraceState([("foo", "bar"), ("baz", "qux")])
353+
354+
self.assertEqual(extracted_span_context.trace_state, expected_trace_state)

0 commit comments

Comments
 (0)