feat: inferred alb spans#838
Conversation
When a Lambda is invoked behind an Application Load Balancer, create an inferred aws.alb span with HTTP request tags and populate ALB HTTP facet tags for http.url, http.route, and http.useragent. FRSLES-851 / APMSVLS-542 Co-authored-by: Cursor <cursoragent@cursor.com>
Cover ALB inferred-span creation, service mapping, inbound trace context, HTTP trigger tags, and full wrapper lifecycle including status code and parent/child linkage. FRSLES-851 / APMSVLS-542 Co-authored-by: Cursor <cursoragent@cursor.com>
This comment has been minimized.
This comment has been minimized.
Handle both ALB event subtypes via resolve_alb_request_headers, fix inbound trace propagation from multiValueHeaders, and expand unit/wrapper coverage for HTTPS URLs, peer.service, and dd_resource_key. FRSLES-851 Co-authored-by: Cursor <cursoragent@cursor.com>
Collapse http_url assignment and reformat TestAlbInferredSpanWrapper tests so check_format.sh passes. FRSLES-851 Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Pull request overview
This PR adds first-class inferred tracing support for Application Load Balancer (ALB)–triggered Lambdas by creating an aws.alb inferred span and ensuring HTTP tag extraction + inbound trace propagation work for both single-value headers and multiValueHeaders ALB event shapes.
Changes:
- Add ALB inferred span creation (
aws.alb,span_type=http,span.kind=server) and wire it intocreate_inferred_span. - Introduce
resolve_alb_request_headersto flatten ALBmultiValueHeadersfor span creation, HTTP tag extraction, and context propagation. - Fix
extract_http_tagsfor ALB events sohttp.url,http.route, andhttp.useragentare populated; add/extend tests for inferred spans, mapping, propagation, and wrapper lifecycle.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
datadog_lambda/trigger.py |
Adds ALB header resolution and improves ALB HTTP tag extraction logic. |
datadog_lambda/tracing.py |
Adds ALB inferred span creation and enables context extraction for ALB multiValueHeaders. |
tests/test_trigger.py |
Extends trigger tag assertions for ALB and adds a multivalue-headers test. |
tests/test_tracing.py |
Adds ALB to propagation coverage and introduces a dedicated inferred-span test suite for ALB. |
tests/test_wrapper.py |
Adds end-to-end wrapper tests validating ALB inferred span behavior and tag copying. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Reuse resolve_alb_request_headers for referer tagging so multiValueHeaders events and lowercase referer keys are handled consistently with other ALB HTTP facet tags. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
ojproductions
left a comment
There was a problem hiding this comment.
looks really good. Just a couple nits
| return event_source_arn | ||
|
|
||
|
|
||
| def resolve_alb_request_headers(event): |
There was a problem hiding this comment.
I think this should be renamed to something like resolve_multivalue_headers as this function isnt specific to ALB
| headers = event.get("headers") | ||
| if not isinstance(headers, dict) or not headers: | ||
| if isinstance(event.get("multiValueHeaders"), dict): | ||
| headers = resolve_alb_request_headers(event) | ||
| else: | ||
| headers = {} |
There was a problem hiding this comment.
this logic is a bit redundant. resolve_alb_request_headers is making the same checks. a simple
headers = resolve_alb_request_headers(event)
would probably work
Address PR review feedback: the header resolver is not ALB-specific, and extract_context_from_http_event_or_context can delegate to it directly. Co-authored-by: Cursor <cursoragent@cursor.com>
Summary
create_inferred_span_from_alb_eventto emit an inferredaws.albspan (span_type=http,span.kind=server) for ALB-triggered Lambdas, with HTTP request tags (http.method,http.url,http.useragent, etc.).create_inferred_spanonevent_type == EventTypes.ALBso both subtypes are covered: single-valueheadersandmultiValueHeaders.resolve_alb_request_headersto flattenmultiValueHeaders(first value per key, matching datadog-lambda-js) for span creation, HTTP tag extraction, and inbound trace propagation.extract_http_tagsfor ALB events (norequestContext.stage) sohttp.url,http.route, andhttp.useragentare populated and copied onto the inferred span by the wrapper post-response (http.status_code,http.route,peer.service,dd_resource_key).Closes FRSLES-851.
Test plan
pytest tests/test_trigger.py -k application_load_balancer -vpytest tests/test_tracing.py::TestAlbInferredSpan -vpytest tests/test_wrapper.py::TestAlbInferredSpanWrapper -vmultiValueHeadersALB fixtures (inferred span, HTTP tags, Datadog + W3C propagation)http.status_code,http.route, 5xx errors,peer.service,dd_resource_key,make_inferred_span=Falseaws.alb)Test traces:
Before

After

