7272propagator = HTTPPropagator ()
7373
7474DD_TRACE_JAVA_TRACE_ID_PADDING = "00000000"
75+ HIGHER_64_BITS = "HIGHER_64_BITS"
76+ LOWER_64_BITS = "LOWER_64_BITS"
7577
7678
7779def _convert_xray_trace_id (xray_trace_id ):
@@ -354,14 +356,16 @@ def extract_context_from_kinesis_event(event, lambda_context):
354356 return extract_context_from_lambda_context (lambda_context )
355357
356358
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 )
365369 if result == 0 :
366370 return 1
367371 return result
@@ -376,13 +380,27 @@ def extract_context_from_step_functions(event, lambda_context):
376380 execution_id = event .get ("Execution" ).get ("Id" )
377381 state_name = event .get ("State" ).get ("Name" )
378382 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
382390 )
391+
383392 sampling_priority = SamplingPriority .AUTO_KEEP
384393 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+ },
386404 )
387405 except Exception as e :
388406 logger .debug ("The Step Functions trace extractor returned with error %s" , e )
@@ -1246,9 +1264,9 @@ def create_function_execution_span(
12461264 "function_version" : function_version ,
12471265 "request_id" : context .aws_request_id ,
12481266 "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+ ) ,
12521270 "datadog_lambda" : datadog_lambda_version ,
12531271 "dd_trace" : ddtrace_version ,
12541272 "span.name" : "aws.lambda" ,
0 commit comments