@@ -229,10 +229,29 @@ def create_sns_event(message):
229
229
230
230
def extract_context_from_sqs_or_sns_event_or_context (event , lambda_context ):
231
231
"""
232
- Extract Datadog trace context from the first SQS message attributes.
232
+ Extract Datadog trace context from an SQS event.
233
+
234
+ The extraction chain goes as follows:
235
+ EB => SQS (First records body contains EB context), or
236
+ SNS => SQS (First records body contains SNS context), or
237
+ SQS or SNS (`messageAttributes` for SQS context,
238
+ `MessageAttributes` for SNS context), else
239
+ Lambda Context.
233
240
234
241
Falls back to lambda context if no trace data is found in the SQS message attributes.
235
242
"""
243
+
244
+ # EventBridge => SQS
245
+ try :
246
+ (
247
+ trace_id ,
248
+ parent_id ,
249
+ sampling_priority ,
250
+ ) = _extract_context_from_eventbridge_sqs_event (event )
251
+ return trace_id , parent_id , sampling_priority
252
+ except Exception :
253
+ logger .debug ("Failed extracting context as EventBridge to SQS." )
254
+
236
255
try :
237
256
first_record = event .get ("Records" )[0 ]
238
257
@@ -283,6 +302,30 @@ def extract_context_from_sqs_or_sns_event_or_context(event, lambda_context):
283
302
return extract_context_from_lambda_context (lambda_context )
284
303
285
304
305
+ def _extract_context_from_eventbridge_sqs_event (event ):
306
+ """
307
+ Extracts Datadog trace context from an SQS event triggered by
308
+ EventBridge.
309
+
310
+ This is only possible if first record in `Records` contains a
311
+ `body` field which contains the EventBridge `detail` as a JSON string.
312
+ """
313
+ try :
314
+ first_record = event .get ("Records" )[0 ]
315
+ if "body" in first_record :
316
+ body_str = first_record .get ("body" , {})
317
+ body = json .loads (body_str )
318
+
319
+ detail = body .get ("detail" )
320
+ dd_context = detail .get ("_datadog" )
321
+ trace_id = dd_context .get (TraceHeader .TRACE_ID )
322
+ parent_id = dd_context .get (TraceHeader .PARENT_ID )
323
+ sampling_priority = dd_context .get (TraceHeader .SAMPLING_PRIORITY )
324
+ return trace_id , parent_id , sampling_priority
325
+ except Exception :
326
+ raise
327
+
328
+
286
329
def extract_context_from_eventbridge_event (event , lambda_context ):
287
330
"""
288
331
Extract datadog trace context from an EventBridge message's Details.
@@ -995,21 +1038,33 @@ def create_inferred_span_from_sqs_event(event, context):
995
1038
}
996
1039
start_time = int (request_time_epoch ) / 1000
997
1040
998
- # logic to deal with SNS => SQS event
999
- sns_span = None
1041
+ upstream_span = None
1000
1042
if "body" in event_record :
1001
1043
body_str = event_record .get ("body" , {})
1002
1044
try :
1003
1045
body = json .loads (body_str )
1046
+
1047
+ # logic to deal with SNS => SQS event
1004
1048
if body .get ("Type" , "" ) == "Notification" and "TopicArn" in body :
1005
1049
logger .debug ("Found SNS message inside SQS event" )
1006
- sns_span = create_inferred_span_from_sns_event (
1050
+ upstream_span = create_inferred_span_from_sns_event (
1007
1051
create_sns_event (body ), context
1008
1052
)
1009
- sns_span .finish (finish_time = start_time )
1053
+ upstream_span .finish (finish_time = start_time )
1054
+
1055
+ # EventBridge => SQS
1056
+ elif body .get ("detail" ):
1057
+ detail = body .get ("detail" )
1058
+ if detail .get ("_datadog" ):
1059
+ logger .debug ("Found an EventBridge message inside SQS event" )
1060
+ upstream_span = create_inferred_span_from_eventbridge_event (
1061
+ body , context
1062
+ )
1063
+ upstream_span .finish (finish_time = start_time )
1064
+
1010
1065
except Exception as e :
1011
1066
logger .debug (
1012
- "Unable to create SNS span from SQS message, with error %s" % e
1067
+ "Unable to create upstream span from SQS message, with error %s" % e
1013
1068
)
1014
1069
pass
1015
1070
@@ -1021,8 +1076,8 @@ def create_inferred_span_from_sqs_event(event, context):
1021
1076
if span :
1022
1077
span .set_tags (tags )
1023
1078
span .start = start_time
1024
- if sns_span :
1025
- span .parent_id = sns_span .span_id
1079
+ if upstream_span :
1080
+ span .parent_id = upstream_span .span_id
1026
1081
1027
1082
return span
1028
1083
0 commit comments