@@ -112,6 +112,10 @@ def _wrap(*args, **kwargs):
112112 "api-gateway-websocket-disconnect" ,
113113 Context (trace_id = 12345 , span_id = 67890 , sampling_priority = 2 ),
114114 ),
115+ (
116+ "application-load-balancer" ,
117+ Context (trace_id = 12345 , span_id = 67890 , sampling_priority = 2 ),
118+ ),
115119 (
116120 "authorizer-request-api-gateway-v1" ,
117121 Context (
@@ -1953,6 +1957,133 @@ def test_remaps_specific_inferred_span_service_names_from_eventbridge_event(
19531957 self .assertEqual (span2 .get_tag ("operation_name" ), "aws.eventbridge" )
19541958 self .assertEqual (span2 .service , "different.eventbridge.custom.event.sender" )
19551959
1960+ def test_remaps_all_inferred_span_service_names_from_alb_event (self ):
1961+ self .set_service_mapping ({"lambda_alb" : "new-name" })
1962+ with open (f"{ event_samples } application-load-balancer.json" ) as event :
1963+ original_event = json .load (event )
1964+
1965+ ctx = get_mock_context ()
1966+ ctx .aws_request_id = "123"
1967+
1968+ span1 = create_inferred_span (original_event , ctx )
1969+ self .assertEqual (span1 .get_tag ("operation_name" ), "aws.alb" )
1970+ self .assertEqual (span1 .service , "new-name" )
1971+
1972+ event2 = copy .deepcopy (original_event )
1973+ event2 ["headers" ]["host" ] = "different-alb.us-east-2.elb.amazonaws.com"
1974+ span2 = create_inferred_span (event2 , ctx )
1975+ self .assertEqual (span2 .get_tag ("operation_name" ), "aws.alb" )
1976+ self .assertEqual (span2 .service , "new-name" )
1977+
1978+ def test_remaps_specific_inferred_span_service_names_from_alb_event (self ):
1979+ host = "lambda-alb-123578498.us-east-2.elb.amazonaws.com"
1980+ self .set_service_mapping ({host : "mapped-alb-service" })
1981+ with open (f"{ event_samples } application-load-balancer.json" ) as event :
1982+ original_event = json .load (event )
1983+
1984+ ctx = get_mock_context ()
1985+ ctx .aws_request_id = "123"
1986+
1987+ span1 = create_inferred_span (original_event , ctx )
1988+ self .assertEqual (span1 .get_tag ("operation_name" ), "aws.alb" )
1989+ self .assertEqual (span1 .service , "mapped-alb-service" )
1990+
1991+ event2 = copy .deepcopy (original_event )
1992+ event2 ["headers" ]["host" ] = "other-alb.us-east-2.elb.amazonaws.com"
1993+ span2 = create_inferred_span (event2 , ctx )
1994+ self .assertEqual (span2 .get_tag ("operation_name" ), "aws.alb" )
1995+ self .assertEqual (span2 .service , "other-alb.us-east-2.elb.amazonaws.com" )
1996+
1997+
1998+ class TestAlbInferredSpan (unittest .TestCase ):
1999+ ALB_SAMPLE = "application-load-balancer"
2000+ ALB_MULTIVALUE = "application-load-balancer-multivalue-headers"
2001+ ALB_HOST = "lambda-alb-123578498.us-east-2.elb.amazonaws.com"
2002+ ALB_USER_AGENT = (
2003+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
2004+ "(KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
2005+ )
2006+
2007+ def _load_event (self , sample_name ):
2008+ with open (f"{ event_samples } { sample_name } .json" ) as event_file :
2009+ return json .load (event_file )
2010+
2011+ def test_create_inferred_span_from_alb_event (self ):
2012+ event = self ._load_event (self .ALB_SAMPLE )
2013+ ctx = get_mock_context (aws_request_id = "123" )
2014+
2015+ span = create_inferred_span (event , ctx )
2016+
2017+ self .assertIsNotNone (span )
2018+ self .assertEqual (span .name , "aws.alb" )
2019+ self .assertEqual (span .span_type , "http" )
2020+ self .assertEqual (span .service , self .ALB_HOST )
2021+ self .assertEqual (span .resource , "GET /lambda" )
2022+ self .assertEqual (span .get_tag ("operation_name" ), "aws.alb" )
2023+ self .assertEqual (span .get_tag ("span.kind" ), "server" )
2024+ self .assertEqual (span .get_tag ("http.method" ), "GET" )
2025+ self .assertEqual (
2026+ span .get_tag ("http.url" ), f"http://{ self .ALB_HOST } /lambda"
2027+ )
2028+ self .assertEqual (span .get_tag ("http.useragent" ), self .ALB_USER_AGENT )
2029+ self .assertEqual (span .get_tag ("endpoint" ), "/lambda" )
2030+ self .assertEqual (span .get_tag ("resource_names" ), "GET /lambda" )
2031+ self .assertEqual (span .get_tag ("request_id" ), "123" )
2032+ self .assertEqual (span .get_tag ("_inferred_span.synchronicity" ), "sync" )
2033+ self .assertEqual (span .get_tag ("_inferred_span.tag_source" ), "self" )
2034+ self .assertEqual (span .get_metric ("_dd._inferred_span" ), 1.0 )
2035+ self .assertEqual (
2036+ span .get_tag ("target_group_arn" ),
2037+ "arn:aws:elasticloadbalancing:us-east-2:123456789012:targetgroup/lambda-xyz/123abc" ,
2038+ )
2039+
2040+ def test_create_inferred_span_omits_tags_when_headers_missing (self ):
2041+ event = self ._load_event (self .ALB_SAMPLE )
2042+ del event ["headers" ]
2043+ event ["httpMethod" ] = None
2044+ event ["path" ] = None
2045+
2046+ span = create_inferred_span (event , get_mock_context ())
2047+
2048+ self .assertIsNotNone (span )
2049+ self .assertNotIn ("http.url" , span .get_tags ())
2050+ self .assertNotIn ("http.method" , span .get_tags ())
2051+ self .assertNotIn ("http.useragent" , span .get_tags ())
2052+
2053+ def test_multivalue_headers_subtype_returns_none (self ):
2054+ event = self ._load_event (self .ALB_MULTIVALUE )
2055+ span = create_inferred_span (event , get_mock_context ())
2056+ self .assertIsNone (span )
2057+
2058+ @with_trace_propagation_style ("datadog" )
2059+ def test_inbound_datadog_context_parents_inferred_span (self ):
2060+ event = self ._load_event (self .ALB_SAMPLE )
2061+ ctx = get_mock_context ()
2062+
2063+ parent_ctx , source , _ = extract_dd_trace_context (event , ctx )
2064+ set_dd_trace_py_root (source , merge_xray_traces = False )
2065+ span = create_inferred_span (event , ctx )
2066+
2067+ self .assertEqual (span .trace_id , parent_ctx .trace_id )
2068+ self .assertEqual (span .parent_id , parent_ctx .span_id )
2069+
2070+ def test_inbound_w3c_context_extracted_from_alb_event (self ):
2071+ event = self ._load_event (self .ALB_SAMPLE )
2072+ event ["headers" ] = {
2073+ "host" : self .ALB_HOST ,
2074+ "user-agent" : self .ALB_USER_AGENT ,
2075+ "x-forwarded-proto" : "http" ,
2076+ "traceparent" : "00-0000000000000000000000000000abcd-000000000000004d-01" ,
2077+ "tracestate" : "dd=s:1" ,
2078+ }
2079+
2080+ ctx , source , _ = extract_dd_trace_context (event , get_mock_context ())
2081+
2082+ self .assertIsNotNone (ctx )
2083+ self .assertEqual (source , TraceContextSource .EVENT )
2084+ self .assertEqual (ctx .trace_id , 0xABCD )
2085+ self .assertEqual (ctx .span_id , 0x4D )
2086+
19562087
19572088class _Span (object ):
19582089 def __init__ (self , service , start , span_type , parent_name = None , tags = None ):
0 commit comments