4343 is_step_function_event ,
4444 EventTypes ,
4545 EventSubtypes ,
46+ resolve_alb_request_headers ,
4647)
4748from datadog_lambda .durable import extract_context_from_durable_execution
4849
@@ -197,6 +198,11 @@ def extract_context_from_http_event_or_context(
197198 return context
198199
199200 headers = event .get ("headers" )
201+ if not isinstance (headers , dict ) or not headers :
202+ if isinstance (event .get ("multiValueHeaders" ), dict ):
203+ headers = resolve_alb_request_headers (event )
204+ else :
205+ headers = {}
200206 context = propagator .extract (headers )
201207
202208 if not _is_context_complete (context ):
@@ -658,7 +664,9 @@ def extract_dd_trace_context(
658664 context = extract_context_from_request_header_or_context (
659665 event , lambda_context , event_source
660666 )
661- elif isinstance (event , (set , dict )) and "headers" in event :
667+ elif isinstance (event , (set , dict )) and (
668+ "headers" in event or "multiValueHeaders" in event
669+ ):
662670 context = extract_context_from_http_event_or_context (
663671 event , lambda_context , event_source , decode_authorizer_context
664672 )
@@ -837,7 +845,7 @@ def create_inferred_span(
837845 elif event_source .equals (EventTypes .LAMBDA_FUNCTION_URL ):
838846 logger .debug ("Function URL event detected. Inferring a span" )
839847 return create_inferred_span_from_lambda_function_url_event (event , context )
840- elif event_source .equals ( EventTypes . ALB , subtype = EventSubtypes .ALB ) :
848+ elif event_source .event_type == EventTypes .ALB :
841849 logger .debug ("ALB event detected. Inferring a span" )
842850 return create_inferred_span_from_alb_event (event , context )
843851 elif event_source .equals (
@@ -960,9 +968,7 @@ def create_inferred_span_from_alb_event(event, context):
960968 elb = request_context .get ("elb" ) or {}
961969 target_group_arn = elb .get ("targetGroupArn" )
962970
963- headers = event .get ("headers" )
964- if not isinstance (headers , dict ):
965- headers = {}
971+ headers = resolve_alb_request_headers (event )
966972 host = headers .get ("host" )
967973 method = event .get ("httpMethod" )
968974 path = event .get ("path" )
@@ -972,7 +978,9 @@ def create_inferred_span_from_alb_event(event, context):
972978 # fall back to it when DD_TRACE_AWS_SERVICE_REPRESENTATION_ENABLED is on.
973979 service_name = determine_service_name (service_mapping , host , "lambda_alb" , host )
974980
975- http_url = f"{ proto } ://{ host } { path } " if host and path is not None else None
981+ http_url = (
982+ "%s://%s%s" % (proto , host , path ) if host and path is not None else None
983+ )
976984 if method and path is not None :
977985 resource = f"{ method } { path } "
978986 else :
@@ -992,13 +1000,13 @@ def create_inferred_span_from_alb_event(event, context):
9921000 # Drop tags we couldn't derive so the span never carries malformed values.
9931001 tags = {key : value for key , value in tags .items () if value is not None }
9941002
995- InferredSpanInfo .set_tags (tags , tag_source = "self" , synchronicity = "sync" )
9961003 tracer .set_tags (_dd_origin )
9971004 # ALB events carry no request timestamp (unlike API GW requestTimeEpoch /
9981005 # Function URL timeEpoch), so the span starts at handler time.
9991006 span = tracer .trace (
10001007 "aws.alb" , service = service_name , resource = resource , span_type = "http"
10011008 )
1009+ InferredSpanInfo .set_tags (tags , tag_source = "self" , synchronicity = "sync" )
10021010 if span :
10031011 span .set_tags (tags )
10041012 span .set_metric (InferredSpanInfo .METRIC , 1.0 )
0 commit comments