Skip to content

fix(console): Re-patch console in AWS Lambda runtimes#20337

Open
s1gr1d wants to merge 3 commits intodevelopfrom
sig/console-aws-lambda-fix
Open

fix(console): Re-patch console in AWS Lambda runtimes#20337
s1gr1d wants to merge 3 commits intodevelopfrom
sig/console-aws-lambda-fix

Conversation

@s1gr1d
Copy link
Copy Markdown
Member

@s1gr1d s1gr1d commented Apr 15, 2026

On AWS Lambda, the Node.js runtime replaces console.* methods with its own loggers. This means Sentry's console instrumentation gets silently overwritten, and integrations like consoleLoggingIntegration stop capturing console output entirely.

This PR fixes that by introducing a defineProperty-based patching strategy for Lambda environments. Instead of simply assigning a wrapper to console.log (which Lambda can overwrite), we define a getter/setter on the console property. When the Lambda runtime assigns its logger, the setter intercepts it, stores the new function as the underlying delegate, and keeps Sentry's wrapper in place. The handler continues to fire, and the Lambda logger still gets called underneath (I checked that manually - the log is still shown in the CloudWatch logs).

This behavior is guarded behind process.env.LAMBDA_TASK_ROOT, so non-Lambda environments continue to use the existing fill()-based patching with zero behavioral change. If defineProperty fails for any reason, it falls back to fill().

The setter also handles consoleSandbox correctly (recognizes when it restores the original method and allows it through), and defers to other Sentry wrappers by checking for __sentry_original__.


It adds a bit to bundle size, maybe it's worth re-exporting this from @sentry/node 🤔

Closes #18238

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 15, 2026

size-limit report 📦

Path Size % Change Change
@sentry/browser 25.93 kB +0.56% +143 B 🔺
@sentry/browser - with treeshaking flags 24.41 kB +0.55% +132 B 🔺
@sentry/browser (incl. Tracing) 42.92 kB +0.36% +153 B 🔺
@sentry/browser (incl. Tracing, Profiling) 47.55 kB +0.33% +153 B 🔺
@sentry/browser (incl. Tracing, Replay) 81.81 kB +0.16% +124 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 71.35 kB +0.19% +132 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 86.51 kB +0.14% +119 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 98.73 kB +0.14% +130 B 🔺
@sentry/browser (incl. Feedback) 42.74 kB +0.35% +149 B 🔺
@sentry/browser (incl. sendFeedback) 30.59 kB +0.46% +138 B 🔺
@sentry/browser (incl. FeedbackAsync) 35.59 kB +0.4% +141 B 🔺
@sentry/browser (incl. Metrics) 27.22 kB +0.53% +143 B 🔺
@sentry/browser (incl. Logs) 27.34 kB +0.52% +140 B 🔺
⛔️ @sentry/browser (incl. Metrics & Logs) (max: 28 kB) 28.04 kB +0.51% +141 B 🔺
@sentry/react 27.67 kB +0.51% +140 B 🔺
@sentry/react (incl. Tracing) 45.23 kB +0.3% +135 B 🔺
@sentry/vue 30.75 kB +0.46% +139 B 🔺
@sentry/vue (incl. Tracing) 44.78 kB +0.35% +156 B 🔺
@sentry/svelte 25.94 kB +0.54% +139 B 🔺
CDN Bundle 28.62 kB +0.56% +159 B 🔺
CDN Bundle (incl. Tracing) 43.97 kB +0.34% +148 B 🔺
CDN Bundle (incl. Logs, Metrics) 29.98 kB +0.48% +143 B 🔺
⛔️ CDN Bundle (incl. Tracing, Logs, Metrics) (max: 45 kB) 45.03 kB +0.32% +142 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 68.84 kB +0.16% +109 B 🔺
CDN Bundle (incl. Tracing, Replay) 80.93 kB +0.19% +153 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 81.97 kB +0.18% +142 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 86.46 kB +0.18% +151 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 87.48 kB +0.16% +135 B 🔺
⛔️ CDN Bundle - uncompressed (max: 83.5 kB) 83.53 kB +0.49% +407 B 🔺
⛔️ CDN Bundle (incl. Tracing) - uncompressed (max: 130 kB) 130.35 kB +0.32% +407 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 87.67 kB +0.47% +407 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 133.77 kB +0.31% +407 B 🔺
⛔️ CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed (max: 211 kB) 211.04 kB +0.2% +407 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 247.61 kB +0.17% +407 B 🔺
⛔️ CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed (max: 251 kB) 251.01 kB +0.17% +407 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 260.53 kB +0.16% +407 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 263.91 kB +0.16% +407 B 🔺
@sentry/nextjs (client) 47.67 kB +0.31% +143 B 🔺
@sentry/sveltekit (client) 43.41 kB +0.39% +167 B 🔺
@sentry/node-core 58.08 kB +0.26% +149 B 🔺
@sentry/node 174.9 kB +0.08% +123 B 🔺
@sentry/node - without tracing 98 kB +0.14% +134 B 🔺
@sentry/aws-serverless 115.23 kB +0.11% +121 B 🔺

View base workflow run

Copy link
Copy Markdown

@cursor cursor bot left a comment

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 487e210. Configure here.

} else {
// Accept as-is: consoleSandbox restores, other Sentry wrappers, or non-functions
current = newValue;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Infinite recursion when third-party code wraps console

High Severity

The setter creates an infinite recursion when any third-party code wraps a console method using the common capture-and-call pattern (e.g. const prev = console.log; console.log = (...args) => { prev(...args); }). The setter treats the new function as a Lambda replacement, sets underlying = newFunc and keeps current = wrapper. Now calling console.log invokes wrapperunderlying (newFunc) → captured prev (which IS wrapper) → underlying (newFunc) → … causing a stack overflow. The Lambda runtime avoids this because it fully replaces the method without calling the previous one, but any other library or user code that wraps console the standard way in a Lambda environment will trigger this crash.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 487e210. Configure here.

Comment thread .size-limit.js
import: createImport('init', 'metrics', 'logger'),
gzip: true,
limit: '28 KB',
limit: '30 KB',
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Lambda-only code increases browser bundle sizes

Low Severity

The patchWithDefineProperty function and its runtime process.env.LAMBDA_TASK_ROOT check live in @sentry/core, so they're bundled into all browser packages despite being Lambda-specific dead code. The gzipped @sentry/browser limit increased from 28KB to 30KB (~7%). Tree shaking can't eliminate the function because the branch is a runtime check. The PR author noted this might belong in @sentry/node instead. Flagging per project rules on large browser bundle size increases.

Additional Locations (1)
Fix in Cursor Fix in Web

Triggered by project rule: PR Review Guidelines for Cursor Bot

Reviewed by Cursor Bugbot for commit 487e210. Configure here.

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.

Sentry Console Logging Integration not working in AWS Lambda

1 participant