Skip to content

Commit 00850d8

Browse files
committed
using context object instead of pre-hashed values
1 parent 068c2fc commit 00850d8

File tree

2 files changed

+63
-33
lines changed

2 files changed

+63
-33
lines changed

datadog_lambda/tracing.py

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -356,11 +356,8 @@ def extract_context_from_kinesis_event(event, lambda_context):
356356
return extract_context_from_lambda_context(lambda_context)
357357

358358

359-
def _deterministic_sha256_hash(s: str, part: str) -> (int, int):
360-
return _sha256_to_binary_part(hashlib.sha256(s.encode()).hexdigest(), part)
361-
362-
363-
def _sha256_to_binary_part(sha256_hash: str, part: str) -> (int, int):
359+
def _deterministic_sha256_hash(s: str, part: str) -> int:
360+
sha256_hash = hashlib.sha256(s.encode()).hexdigest()
364361
# First two chars is '0b'. zfill to ensure 256 bits, but we only care about the first 128 bits
365362
binary_hash = bin(int(sha256_hash, 16))[2:].zfill(256)
366363
if part == HIGHER_64_BITS:
@@ -373,35 +370,56 @@ def _sha256_to_binary_part(sha256_hash: str, part: str) -> (int, int):
373370
return result
374371

375372

373+
def _parse_high_64_bits(trace_tags: str) -> str:
374+
# todo: testme
375+
if trace_tags:
376+
for tag in trace_tags.split(","):
377+
if "_dd.p.tid=" in tag:
378+
return tag.split("=")[1]
379+
380+
return ""
381+
382+
383+
def _sfn_context_to_parent_id(context: dict) -> int:
384+
# todo: testme
385+
execution_id = context.get("Execution").get("Id")
386+
state_name = context.get("State").get("Name")
387+
state_entered_time = context.get("State").get("EnteredTime")
388+
389+
return _deterministic_sha256_hash(
390+
f"{execution_id}#{state_name}#{state_entered_time}", HIGHER_64_BITS
391+
)
392+
393+
376394
def extract_context_from_step_functions(event, lambda_context):
377395
"""
378396
Only extract datadog trace context when Step Functions Context Object is injected
379397
into lambda's event dict.
380398
"""
399+
# todo: update docstring
381400
try:
382401
meta = {}
402+
dd_data = event.get("_datadog")
383403

384-
if "_datadog" in event:
385-
dd_data = event.get("_datadog")
386-
parent_id = _sha256_to_binary_part(
387-
dd_data.get("x-datadog-parent-id-hash"), HIGHER_64_BITS
388-
)
404+
if dd_data and dd_data.get("serverless-version") == "v2":
389405
if "x-datadog-trace-id" in dd_data: # lambda root
390-
dd_data["x-datadog-parent-id"] = str(parent_id)
391-
return propagator.extract(dd_data)
406+
trace_id = dd_data.get("x-datadog-trace-id")
407+
high_64_bit_trace_id = _parse_high_64_bits(dd_data.get("x-datadog-tags"))
408+
if high_64_bit_trace_id:
409+
meta["_dd.p.tid"] = high_64_bit_trace_id
392410
else: # sfn root
393-
trace_id = _sha256_to_binary_part(
394-
dd_data.get("x-datadog-trace-id-hash"), LOWER_64_BITS
411+
trace_id = _deterministic_sha256_hash(
412+
dd_data.get("RootExecutionId"), LOWER_64_BITS
395413
)
396414
meta["_dd.p.tid"] = hex(
397-
_sha256_to_binary_part(
398-
dd_data.get("x-datadog-trace-id-hash"), HIGHER_64_BITS
415+
_deterministic_sha256_hash(
416+
dd_data.get("RootExecutionId"), HIGHER_64_BITS
399417
)
400418
)[2:]
419+
420+
parent_id = _sfn_context_to_parent_id(dd_data)
401421
else:
402422
execution_id = event.get("Execution").get("Id")
403-
state_name = event.get("State").get("Name")
404-
state_entered_time = event.get("State").get("EnteredTime")
405423
# returning 128 bits since 128bit traceId will be break up into
406424
# traditional traceId and _dd.p.tid tag
407425
# https://github.com/DataDog/dd-trace-py/blob/3e34d21cb9b5e1916e549047158cb119317b96ab/ddtrace/propagation/http.py#L232-L240
@@ -412,9 +430,7 @@ def extract_context_from_step_functions(event, lambda_context):
412430
_deterministic_sha256_hash(execution_id, HIGHER_64_BITS)
413431
)[2:]
414432

415-
parent_id = _deterministic_sha256_hash(
416-
f"{execution_id}#{state_name}#{state_entered_time}", HIGHER_64_BITS
417-
)
433+
parent_id = _sfn_context_to_parent_id(event)
418434

419435
sampling_priority = SamplingPriority.AUTO_KEEP
420436
return Context(

tests/test_tracing.py

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -656,22 +656,29 @@ def test_step_function_trace_data_lambda_root(self):
656656
lambda_ctx = get_mock_context()
657657
sfn_event = {
658658
"_datadog": {
659+
"Execution": {
660+
"Id": "665c417c-1237-4742-aaca-8b3becbb9e75",
661+
},
662+
"StateMachine": {},
663+
"State": {
664+
"Name": "my-awesome-state",
665+
"EnteredTime": "Mon Nov 13 12:43:33 PST 2023",
666+
},
659667
"x-datadog-trace-id": "5821803790426892636",
660668
"x-datadog-sampling-priority": "1",
661669
"x-datadog-tags": "_dd.p.dm=-0,_dd.p.tid=672a7cb100000000",
662670
"traceparent": "00-672a7cb10000000050cb33b3c06ae95c-5fda9d8d1d1373f9-01",
663671
"tracestate": "dd=p:5fda9d8d1d1373f9;s:1;t.dm:-0;t.tid:672a7cb100000000",
664-
"x-datadog-parent-id-hash": "a926584eba705d6ec904c54db2ecc4d4a2c91e7dabe7ce87ac26edb43388fbc5",
665672
"serverless-version": "v2",
666673
}
667674
}
668675
ctx, source, event_source = extract_dd_trace_context(sfn_event, lambda_ctx)
669676
self.assertEqual(source, "event")
670677
expected_context = Context(
671-
trace_id=137131089076080415507232535361568303452,
672-
span_id=2965154499828669806,
678+
trace_id=5821803790426892636,
679+
span_id=6880978411788117524,
673680
sampling_priority=1,
674-
meta={"_dd.p.dm": "-0", "_dd.p.tid": "672a7cb100000000"},
681+
meta={"_dd.p.tid": "672a7cb100000000"},
675682
)
676683
self.assertEqual(ctx, expected_context)
677684
self.assertEqual(
@@ -680,7 +687,7 @@ def test_step_function_trace_data_lambda_root(self):
680687
TraceHeader.TRACE_ID: "5821803790426892636",
681688
TraceHeader.PARENT_ID: "10713633173203262661",
682689
TraceHeader.SAMPLING_PRIORITY: "1",
683-
TraceHeader.TAGS: "_dd.p.dm=-0,_dd.p.tid=672a7cb100000000",
690+
TraceHeader.TAGS: "_dd.p.tid=672a7cb100000000",
684691
},
685692
)
686693
create_dd_dummy_metadata_subsegment(ctx, XraySubsegment.TRACE_KEY)
@@ -694,27 +701,34 @@ def test_step_function_trace_data_sfn_root(self):
694701
lambda_ctx = get_mock_context()
695702
sfn_event = {
696703
"_datadog": {
697-
"x-datadog-trace-id-hash": "fed93f8c162880cb9aa90fcd1f8395383835841d5470d30215f3dd52906ebc58",
698-
"x-datadog-parent-id-hash": "c5eb94cc9220ab5783e1db53debd54b8c93f6f2a3eae1c680d7b849f2d34e551",
704+
"Execution": {
705+
"Id": "665c417c-1237-4742-aaca-8b3becbb9e75",
706+
},
707+
"StateMachine": {},
708+
"State": {
709+
"Name": "my-awesome-state",
710+
"EnteredTime": "Mon Nov 13 12:43:33 PST 2023",
711+
},
712+
"RootExecutionId": "4875aba4-ae31-4a4c-bf8a-63e9eee31dad",
699713
"serverless-version": "v2",
700714
}
701715
}
702716
ctx, source, event_source = extract_dd_trace_context(sfn_event, lambda_ctx)
703717
self.assertEqual(source, "event")
704718
expected_context = Context(
705-
trace_id=1921084089721656632,
706-
span_id=5038284214489885527,
719+
trace_id=4521899030418994483,
720+
span_id=6880978411788117524,
707721
sampling_priority=1,
708-
meta={"_dd.p.tid": "7ed93f8c162880cb"},
722+
meta={"_dd.p.tid": "12d1270d99cc5e03"},
709723
)
710724
self.assertEqual(ctx, expected_context)
711725
self.assertEqual(
712726
get_dd_trace_context(),
713727
{
714-
TraceHeader.TRACE_ID: "1921084089721656632",
728+
TraceHeader.TRACE_ID: "4521899030418994483",
715729
TraceHeader.PARENT_ID: "10713633173203262661",
716730
TraceHeader.SAMPLING_PRIORITY: "1",
717-
TraceHeader.TAGS: "_dd.p.tid=7ed93f8c162880cb",
731+
TraceHeader.TAGS: "_dd.p.tid=12d1270d99cc5e03",
718732
},
719733
)
720734
create_dd_dummy_metadata_subsegment(ctx, XraySubsegment.TRACE_KEY)

0 commit comments

Comments
 (0)