Skip to content

feat(aws-lambda): Detect Lambda triggers - #8222

Merged
sentrivana merged 20 commits into
major/3.0from
junior/aws-lambda-trigger
Nov 12, 2026
Merged

sentrivana merged 20 commits into
major/3.0from
junior/aws-lambda-trigger

Conversation

@sentry-junior

@sentry-junior sentry-junior Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Description

Sets faas.trigger on the Lambda span based on the shape of the delivered event:

  • http: API Gateway REST/HTTP, function URLs, ALB, CloudFront, AppSync
  • pubsub: SQS, SNS, Kinesis, Kafka, MQ, SES, EventBridge
  • datasource: S3, DynamoDB Streams, DocumentDB
  • timer: EventBridge schedules
  • other: anything else

The trigger is read from the event envelope, never from its payload. test_trigger has one case per code path. Other event sources use the same lookup table, so they have no extra cases.

This PR doesn't touch messaging.batch.message_count. That change is in #8229.

This is Pablo's code from pablo/aws-lambda-trigger, without his batch counting for the invocation span. It's the second of three stacked PRs (#8221 → this → #8223).

Issues

via @dingsdax.

--

View Session [Sentry]

pabloDeputter and others added 7 commits October 23, 2026 15:08
A synchronous boto3 Invoke now carries sentry-trace and baggage in
ClientContext.custom (added with the Lambda service extension). The
Lambda integration continues the trace from there. ClientContext wins
over event headers, because a forwarded HTTP event can keep headers
from further upstream.

The ClientContextTrace test function works around sam local, which
drops ClientContext, by handing the event's client_context to the
runtime.

Co-Authored-By: Johannes Daxböck <114897+dingsdax@users.noreply.github.com>
Classify the delivered event into faas.trigger: http (API Gateway,
function URLs, ALB, CloudFront, AppSync), pubsub (SQS, SNS, Kinesis,
Kafka, MQ, SES, EventBridge), datasource (S3, DynamoDB Streams,
DocumentDB), timer (EventBridge schedules) or other. The trigger is
read from the event envelope, never from its payload.

messaging.batch.message_count is now only set for messaging
deliveries, with the number of delivered messages.

Co-Authored-By: Johannes Daxböck <114897+dingsdax@users.noreply.github.com>
@linear-code

linear-code Bot commented Nov 9, 2026

Copy link
Copy Markdown

PY-3018

@github-actions

github-actions Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Coverage Results 📊

✅ 58565 passed | ❌ 1 failed | ⏭️ 3071 skipped | Total: 61637 | Pass Rate: 95.02% | Execution Time: 157m 1s

📊 Comparison with Base Branch

Metric Change
Total Tests 📉 -85446
Passed Tests 📉 -80656
Failed Tests —
Skipped Tests 📉 -4790

➕ New Tests (1)

View new tests
  • test_cache_spans_templatetag
    • File: tests.integrations.django.test_cache_module
    • Status: ❌ Failing

➖ Removed Tests (1)

View removed tests
  • test_openfeature_integration_threaded
    • File: tests.integrations.openfeature.test_openfeature

❌ Failed Tests

test_cache_spans_templatetag

File: tests.integrations.django.test_cache_module
Suite: py3.15-django-v6.1.3
Error: tests/integrations/django/test_cache_module.py:362: in test_cache_spans_templatetag assert not spans[0]["attributes"]["cache.hit"] E assert not True

Stack Trace
tests/integrations/django/test_cache_module.py:362: in test_cache_spans_templatetag
    assert not spans[0]["attributes"]["cache.hit"]
E   assert not True

❌ Patch coverage is 24.24% (8 of 33 changed executable lines covered; target 80%).
Project statement coverage is 90.21% (unchanged from base (08ebd25) to head (61c3b58)).

Changed files with executable lines (3)
File Patch coverage Changed executable lines
sentry_sdk/integrations/aws_lambda/_trigger.py 17.86% 5/28 covered; missed: 42, 51, 53, 54, 55, 57, 58, 62, 63, 66, 68, 69, 71, 72, 74, 75, 77, 78, 80, 81, 85, 86, 88
sentry_sdk/integrations/aws_lambda/_handler.py 33.33% 1/3 covered; missed: 235, 236
sentry_sdk/consts.py 100.00% 2/2 covered
Coverage diff
@@            Coverage Diff             @@
##        master     #8222       +/-##
==========================================
  Coverage    90.21%    90.21%        —%
==========================================
  Files          203       200        -3
  Tracked lines     27335     21857     -5478
  Branches     10246      7622     -2624
==========================================
- Hits         24660     19717     -4943
+ Misses        2675      2140      -535
+ Partials      1559      1254      -305

Generated by Coverage Action

sentry-junior Bot and others added 5 commits November 9, 2026 07:57
…a span

Keep the count on messaging spans only (boto3 receive and batch-send
spans, and queue.process for SQS/SNS triggers), as in the OTel
messaging conventions and the JS SDK. This drops the batch counting for
Kafka, MQ and RabbitMQ deliveries, and matches #8219 so both PRs change
these lines the same way.

Co-Authored-By: johdax <114897+dingsdax@users.noreply.github.com>
Read client_context and its custom dict with getattr, so a context
object without them falls back to the event headers.

Co-Authored-By: Johannes Daxböck <114897+dingsdax@users.noreply.github.com>
…r/aws-lambda-trigger

Co-Authored-By: Johannes Daxböck <114897+dingsdax@users.noreply.github.com>
Each case is a SAM invoke. The removed cases only checked other keys of
the same lookup table.

Co-Authored-By: Johannes Daxböck <114897+dingsdax@users.noreply.github.com>
…a-invoke-trace-continuation

# Conflicts:
#	sentry_sdk/integrations/boto3/_client.py
#	sentry_sdk/integrations/boto3/_instrumentation.py
#	sentry_sdk/integrations/boto3/_services/base.py
#	sentry_sdk/integrations/boto3/_services/lambda_.py
#	sentry_sdk/integrations/boto3/_services/registry.py
@sentry-junior
sentry-junior Bot marked this pull request as ready for review November 11, 2026 17:47
@sentry-junior
sentry-junior Bot requested a review from a team as a code owner November 11, 2026 17:47

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

sentrivana pushed a commit that referenced this pull request Nov 12, 2026
### Description

With #8117 (merged), a synchronous boto3 `Invoke` carries `sentry-trace`
and `baggage` in `ClientContext.custom`. This PR adds the receiving
side: the Lambda integration continues the trace from
`context.client_context.custom`. `ClientContext` wins over event
headers, because a forwarded HTTP event can still carry headers from
further upstream.

`sam local` drops `ClientContext`, so the new `ClientContextTrace` test
function hands the event's `client_context` to the runtime. That way the
container tests can cover it.

This is Pablo's code from `pablo/aws-lambda-client-context-trace`. The
one change: `client_context` and `custom` are read with `getattr`, so a
context object without them falls back to event headers instead of
failing. It's the first of three stacked PRs for the stretch Lambda
work: this PR → trigger detection (#8222) → `queue.process` spans
(#8223).

#### Issues
* resolves: PY-3009 (receiving side; #8117 does the injection)
* Part of #8071

<!-- junior-request-attribution:start -->
via @dingsdax.
<!-- junior-request-attribution:end -->

<!-- junior-session-footer:start -->
<!-- junior-conversation-id:slack%3AC0C9X9V5NMT%3A1793904671.980379 -->

--

[View
Session](https://junior-prod.sentry.dev/conversations/slack%3AC0C9X9V5NMT%3A1793904671.980379)
[[Sentry]](https://sentry.sentry.io/explore/conversations/slack%3AC0C9X9V5NMT%3A1793904671.980379/?project=4510944073809921)

<!-- junior-session-footer:end -->

---------

Co-authored-by: Pablo Deputter <pablo.deputter@sentry.io>
Co-authored-by: Pablo Deputter <71842639+pabloDeputter@users.noreply.github.com>
Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: Johannes Daxböck <114897+dingsdax@users.noreply.github.com>
Base automatically changed from junior/aws-lambda-invoke-trace-continuation to major/3.0 November 12, 2026 11:23

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

sentrivana added a commit that referenced this pull request Nov 12, 2026
)

### Description

Since #8137, #8142, and #8145, boto3 puts `sentry-trace` in SQS and SNS
message attributes, but nothing reads it on the Lambda side. This PR is
the smallest change that closes the loop for SQS- and SNS-triggered
functions. The Lambda integration now reads `sentry-trace` from each
record and adds a `message_origin` link from the invocation span to each
distinct producer span. This matches what the boto3 `ReceiveMessage`
span already does. Messages never become the invocation's parent.

It reads:
- SQS records: `messageAttributes["sentry-trace"].stringValue`
- SNS records: `Sns.MessageAttributes["sentry-trace"].Value`
- SNS → SQS without raw message delivery: the SNS envelope in the SQS
`body`, the same as boto3 does

Links are deduplicated, because a batch send gives many messages the
same producer span, and capped at 128, OTel's default, because Lambda
can deliver up to 10,000 SQS messages at once.

**Scope.** This is intentionally kept separate from the stretch stack.
It doesn't add `faas.trigger` (#8222) or `queue.process` spans (#8223),
and it doesn't touch `messaging.batch.message_count` (#8229). The
invocation span is otherwise unchanged. Synchronous `Invoke` propagation
through `ClientContext` is #8221. That PR changes the `continue_trace`
call and this one only adds `links=`, so the two are independent.

The link-building code repeats boto3's `_message_link` in a Lambda-event
shape: Lambda records use `messageAttributes` / `stringValue` / `body`,
while the boto3 response uses `MessageAttributes` / `StringValue` /
`Body`. Importing from the boto3 integration would make `aws_lambda`
depend on botocore.

**Testing.** `test_producer_links` sends SQS, SNS, and SNS-to-SQS events
to `BasicOkSpanStreaming`. It asserts the segment span's `links` and
that the segment span has no parent. It passes in CI's Cloud (Lambda)
jobs, and `ruff` and `mypy sentry_sdk` pass. `codecov/patch` is red
because the Lambda tests run in `sam local` containers, so their
coverage isn't counted.

#### Issues
* Part of #8081

<!-- junior-request-attribution:start -->
via **webb**, @sentrivana.
<!-- junior-request-attribution:end -->

<!-- junior-session-footer:start -->
<!-- junior-conversation-id:slack%3AC09M26BC6A1%3A1794211222.463239 -->

--

[View
Session](https://junior-prod.sentry.dev/conversations/slack%3AC09M26BC6A1%3A1794211222.463239)
[[Sentry]](https://sentry.sentry.io/explore/conversations/slack%3AC09M26BC6A1%3A1794211222.463239/?project=4510944073809921)

<!-- junior-session-footer:end -->

---------

Co-authored-by: sentry-junior[bot] <264270552+sentry-junior[bot]@users.noreply.github.com>
Co-authored-by: Alexander Webb <alexander.webb@sentry.io>
Co-authored-by: Ivana Kellyer <131587164+sentrivana@users.noreply.github.com>
@sentrivana

Copy link
Copy Markdown
Collaborator

Take the messaging.batch.message_count stuff out of this PR. As I understand, #8229 is a separate PR for exactly that.

Restores the batch count on the invocation span, as on major/3.0, so this
PR only adds faas.trigger.
…a-trigger

# Conflicts:
#	tests/integrations/aws_lambda/test_aws_lambda.py

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 151b3a4. Configure here.

@sentrivana
sentrivana merged commit 4213a82 into major/3.0 Nov 12, 2026
151 of 152 checks passed
@sentrivana
sentrivana deleted the junior/aws-lambda-trigger branch November 12, 2026 13:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants