72
72
propagator = HTTPPropagator ()
73
73
74
74
DD_TRACE_JAVA_TRACE_ID_PADDING = "00000000"
75
+ HIGHER_64_BITS = "HIGHER_64_BITS"
76
+ LOWER_64_BITS = "LOWER_64_BITS"
75
77
76
78
77
79
def _convert_xray_trace_id (xray_trace_id ):
@@ -354,14 +356,16 @@ def extract_context_from_kinesis_event(event, lambda_context):
354
356
return extract_context_from_lambda_context (lambda_context )
355
357
356
358
357
- def _deterministic_md5_hash (s : str ) -> int :
358
- """MD5 here is to generate trace_id, not for any encryption."""
359
- hex_number = hashlib .md5 (s .encode ("ascii" )).hexdigest ()
360
- binary = bin (int (hex_number , 16 ))
361
- binary_str = str (binary )
362
- binary_str_remove_0b = binary_str [2 :].rjust (128 , "0" )
363
- most_significant_64_bits_without_leading_1 = "0" + binary_str_remove_0b [1 :- 64 ]
364
- result = int (most_significant_64_bits_without_leading_1 , 2 )
359
+ def _deterministic_sha256_hash (s : str , part : str ) -> (int , int ):
360
+ sha256_hash = hashlib .sha256 (s .encode ()).hexdigest ()
361
+
362
+ # First two chars is '0b'. zfill to ensure 256 bits, but we only care about the first 128 bits
363
+ binary_hash = bin (int (sha256_hash , 16 ))[2 :].zfill (256 )
364
+ if part == HIGHER_64_BITS :
365
+ updated_binary_hash = "0" + binary_hash [1 :64 ]
366
+ else :
367
+ updated_binary_hash = "0" + binary_hash [65 :128 ]
368
+ result = int (updated_binary_hash , 2 )
365
369
if result == 0 :
366
370
return 1
367
371
return result
@@ -376,13 +380,27 @@ def extract_context_from_step_functions(event, lambda_context):
376
380
execution_id = event .get ("Execution" ).get ("Id" )
377
381
state_name = event .get ("State" ).get ("Name" )
378
382
state_entered_time = event .get ("State" ).get ("EnteredTime" )
379
- trace_id = _deterministic_md5_hash (execution_id )
380
- parent_id = _deterministic_md5_hash (
381
- f"{ execution_id } #{ state_name } #{ state_entered_time } "
383
+ # returning 128 bits since 128bit traceId will be break up into
384
+ # traditional traceId and _dd.p.tid tag
385
+ # https://github.com/DataDog/dd-trace-py/blob/3e34d21cb9b5e1916e549047158cb119317b96ab/ddtrace/propagation/http.py#L232-L240
386
+ trace_id = _deterministic_sha256_hash (execution_id , LOWER_64_BITS )
387
+
388
+ parent_id = _deterministic_sha256_hash (
389
+ f"{ execution_id } #{ state_name } #{ state_entered_time } " , HIGHER_64_BITS
382
390
)
391
+
383
392
sampling_priority = SamplingPriority .AUTO_KEEP
384
393
return Context (
385
- trace_id = trace_id , span_id = parent_id , sampling_priority = sampling_priority
394
+ trace_id = trace_id ,
395
+ span_id = parent_id ,
396
+ sampling_priority = sampling_priority ,
397
+ # take the higher 64 bits as _dd.p.tid tag and use hex to encode
398
+ # [2:] to remove '0x' in the hex str
399
+ meta = {
400
+ "_dd.p.tid" : hex (
401
+ _deterministic_sha256_hash (execution_id , HIGHER_64_BITS )
402
+ )[2 :]
403
+ },
386
404
)
387
405
except Exception as e :
388
406
logger .debug ("The Step Functions trace extractor returned with error %s" , e )
@@ -1246,9 +1264,9 @@ def create_function_execution_span(
1246
1264
"function_version" : function_version ,
1247
1265
"request_id" : context .aws_request_id ,
1248
1266
"resource_names" : context .function_name ,
1249
- "functionname" : context . function_name . lower ()
1250
- if context .function_name
1251
- else None ,
1267
+ "functionname" : (
1268
+ context . function_name . lower () if context .function_name else None
1269
+ ) ,
1252
1270
"datadog_lambda" : datadog_lambda_version ,
1253
1271
"dd_trace" : ddtrace_version ,
1254
1272
"span.name" : "aws.lambda" ,
0 commit comments