Skip to content

Commit c86be18

Browse files
Xray parenting fix (#179)
* Address X-Ray/dd-trace trace mergeing edge case * Add test for x-ray tracing edge case * Add comment
1 parent b3b00d9 commit c86be18

File tree

2 files changed

+59
-1
lines changed

2 files changed

+59
-1
lines changed

datadog_lambda/tracing.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,13 @@ def is_lambda_context():
362362

363363
def set_dd_trace_py_root(trace_context_source, merge_xray_traces):
364364
if trace_context_source == TraceContextSource.EVENT or merge_xray_traces:
365-
headers = _context_obj_to_headers(dd_trace_context)
365+
context = dict(dd_trace_context)
366+
if merge_xray_traces:
367+
xray_context = _get_xray_trace_context()
368+
if xray_context is not None:
369+
context["parent-id"] = xray_context["parent-id"]
370+
371+
headers = _context_obj_to_headers(context)
366372
span_context = propagator.extract(headers)
367373
tracer.context_provider.activate(span_context)
368374
logger.debug(

tests/test_tracing.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from mock import MagicMock, patch, call
99

1010
from ddtrace.helpers import get_correlation_ids
11+
from ddtrace.context import Context
1112

1213
from datadog_lambda.constants import SamplingPriority, TraceHeader, XraySubsegment
1314
from datadog_lambda.tracing import (
@@ -16,6 +17,7 @@
1617
create_function_execution_span,
1718
get_dd_trace_context,
1819
set_correlation_ids,
20+
set_dd_trace_py_root,
1921
_convert_xray_trace_id,
2022
_convert_xray_entity_id,
2123
_convert_xray_sampling,
@@ -493,3 +495,53 @@ def test_function_with_trigger_tags(self):
493495
self.assertEqual(
494496
span.get_tag("function_trigger.event_source"), "cloudwatch-logs"
495497
)
498+
499+
500+
class TestSetTraceRootSpan(unittest.TestCase):
501+
def setUp(self):
502+
global dd_tracing_enabled
503+
dd_tracing_enabled = False
504+
os.environ["_X_AMZN_TRACE_ID"] = fake_xray_header_value
505+
patcher = patch("datadog_lambda.tracing.send_segment")
506+
self.mock_send_segment = patcher.start()
507+
self.addCleanup(patcher.stop)
508+
patcher = patch("datadog_lambda.tracing.is_lambda_context")
509+
self.mock_is_lambda_context = patcher.start()
510+
self.mock_is_lambda_context.return_value = True
511+
self.addCleanup(patcher.stop)
512+
patcher = patch("ddtrace.tracer.context_provider.activate")
513+
self.mock_activate = patcher.start()
514+
self.mock_activate.return_value = True
515+
self.addCleanup(patcher.stop)
516+
517+
def tearDown(self):
518+
global dd_tracing_enabled
519+
dd_tracing_enabled = False
520+
del os.environ["_X_AMZN_TRACE_ID"]
521+
522+
def test_mixed_parent_context_when_merging(self):
523+
# When trace merging is enabled, and dd_trace headers are present,
524+
# use the dd-trace trace-id and the x-ray parent-id
525+
# This allows parenting relationships like dd-trace -> x-ray -> dd-trace
526+
lambda_ctx = get_mock_context()
527+
ctx, source = extract_dd_trace_context(
528+
{
529+
"headers": {
530+
TraceHeader.TRACE_ID: "123",
531+
TraceHeader.PARENT_ID: "321",
532+
TraceHeader.SAMPLING_PRIORITY: "1",
533+
}
534+
},
535+
lambda_ctx,
536+
)
537+
set_dd_trace_py_root(
538+
source, True
539+
) # When merging is off, always use dd-trace-context
540+
541+
expected_context = Context(
542+
trace_id=123, # Trace Id from incomming context
543+
span_id=int(fake_xray_header_value_parent_decimal), # Parent Id from x-ray
544+
sampling_priority=1, # Sampling priority from incomming context
545+
)
546+
self.mock_activate.assert_called()
547+
self.mock_activate.assert_has_calls([call(expected_context)])

0 commit comments

Comments
 (0)