Skip to content

feat(aws-serverless): Replace OTel Lambda instrumentation with handler redirection#22079

Open
andreiborza wants to merge 14 commits into
developfrom
ab/aws-lambda-handler-redirect
Open

feat(aws-serverless): Replace OTel Lambda instrumentation with handler redirection#22079
andreiborza wants to merge 14 commits into
developfrom
ab/aws-lambda-handler-redirect

Conversation

@andreiborza

@andreiborza andreiborza commented Jul 8, 2026

Copy link
Copy Markdown
Member

What

Replaces the vendored @opentelemetry/instrumentation-aws-lambda (module patching via InstrumentationBase + import-in-the-middle) with handler redirection.

The idea is that the AWS runtime reads _HANDLER only after all --import/--require preloads (and thus Sentry.init()) have run. So during init, the AwsLambda integration points _HANDLER at a Sentry shim and stores the original value in SENTRY_ORIGINAL_HANDLER. The runtime then loads the shim instead of the user's handler; the shim resolves the original handler with the same rules as the runtime, wraps it with the existing span logic and wrapHandler, and re-exports it.

sequenceDiagram
    participant Preload as Node.js preload<br/>(--import .../awslambda-auto)
    participant RIC as Lambda runtime
    participant Shim as Sentry shim<br/>(run-lambda-handler.mjs)
    participant User as User handler module

    Note over Preload: Sentry.init()
    Preload->>Preload: SENTRY_ORIGINAL_HANDLER = "index.handler"<br/>_HANDLER = ".../run-lambda-handler.handler"
    RIC->>Shim: reads _HANDLER, await import()
    Shim->>User: resolves SENTRY_ORIGINAL_HANDLER,<br/>require() for CJS / import() for ESM
    User-->>Shim: original handler
    Shim-->>RIC: exports wrapped handler<br/>(span logic + wrapHandler, streaming symbols preserved)
    loop every invocation
        RIC->>Shim: wrapped handler(event, context)
        Shim->>User: original handler(event, context)
        User-->>Shim: result
        Shim-->>RIC: result (span ended, events flushed)
    end
Loading

Because the shim wraps the handler value (whatever the export resolves to), this also covers wrapped (e.g. middy), re-exported and streaming handlers. Behavior is unchanged (same spans, attributes, origins, mechanisms), verified by the unchanged SAM e2e assertions (Node 18/20, layer and npm install methods) and against a real Lambda function. Datadog (redirect handler) and New Relic (wrapper handler) use the same approach in their layers.

Why not orchestrion

The issue proposed orchestrion, but it does not fit the Lambda case:

  • Module matching only recognizes packages under node_modules; the handler is an arbitrary user file resolved from _HANDLER.
  • Function queries match function definitions in source, silently missing middy(...), awslambda.streamifyResponse(...), re-exports and bundled output.
  • Tracing-channel subscribers are synchronous, so they cannot delay the handler's return for the flush that must complete before the runtime freezes the sandbox.

Closes: #20908

…r redirection

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Comment thread packages/aws-serverless/src/handlerResolution.ts
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 27.59 kB - -
@sentry/browser - with treeshaking flags 26.03 kB - -
@sentry/browser (incl. Tracing) 46.34 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 48.13 kB - -
@sentry/browser (incl. Tracing, Profiling) 51.12 kB - -
@sentry/browser (incl. Tracing, Replay) 85.61 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 75.26 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 90.32 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 102.97 kB - -
@sentry/browser (incl. Feedback) 44.76 kB - -
@sentry/browser (incl. sendFeedback) 32.38 kB - -
@sentry/browser (incl. FeedbackAsync) 37.51 kB - -
@sentry/browser (incl. Metrics) 28.67 kB - -
@sentry/browser (incl. Logs) 28.91 kB - -
@sentry/browser (incl. Metrics & Logs) 29.59 kB - -
@sentry/react 29.38 kB - -
@sentry/react (incl. Tracing) 48.61 kB - -
@sentry/vue 33.03 kB - -
@sentry/vue (incl. Tracing) 48.24 kB - -
@sentry/svelte 27.61 kB - -
CDN Bundle 30 kB - -
CDN Bundle (incl. Tracing) 48.32 kB - -
CDN Bundle (incl. Logs, Metrics) 31.57 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 49.64 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 70.81 kB - -
CDN Bundle (incl. Tracing, Replay) 85.84 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 87.14 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 91.64 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.92 kB - -
CDN Bundle - uncompressed 89.35 kB - -
CDN Bundle (incl. Tracing) - uncompressed 146.1 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 94.05 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 150.07 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 218.75 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 265.27 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 269.23 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 278.97 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 282.92 kB - -
@sentry/nextjs (client) 51.16 kB - -
@sentry/sveltekit (client) 46.75 kB - -
@sentry/core/server 78.42 kB - -
@sentry/core/browser 64.74 kB - -
@sentry/node-core 62.72 kB +0.01% +3 B 🔺
@sentry/node 125.33 kB +0.01% +1 B 🔺
@sentry/node (incl. diagnostics channel injection) 134.97 kB - -
@sentry/node/import (ESM hook with diagnostics-channel injection) 69.95 kB - -
@sentry/node/light 50.72 kB - -
@sentry/node - without tracing 74.05 kB +0.01% +2 B 🔺
@sentry/aws-serverless 83.23 kB -2.66% -2.27 kB 🔽
@sentry/cloudflare (withSentry) - minified 181.71 kB - -
@sentry/cloudflare (withSentry) 449.16 kB - -

View base workflow run

@andreiborza andreiborza marked this pull request as ready for review July 8, 2026 20:24
@andreiborza andreiborza requested a review from a team as a code owner July 8, 2026 20:24
@andreiborza andreiborza requested review from JPeer264, Lms24, chargome and mydea and removed request for a team and JPeer264 July 8, 2026 20:24
Comment thread packages/aws-serverless/src/integration/awslambda.ts

@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 2 potential issues.

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 2d5a898. Configure here.

Comment thread packages/aws-serverless/src/instrumentHandler.ts Outdated
Comment thread packages/aws-serverless/src/run-lambda-handler.ts
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.

Rewrite AwsLambdaInstrumentation to orchestrion

1 participant