Skip to content

feat(node): Wire up SentryTracerProvider#21680

Draft
andreiborza wants to merge 10 commits into
ab/sentry-trace-provider-otelfrom
ab/sentry-trace-provider-node
Draft

feat(node): Wire up SentryTracerProvider#21680
andreiborza wants to merge 10 commits into
ab/sentry-trace-provider-otelfrom
ab/sentry-trace-provider-node

Conversation

@andreiborza

@andreiborza andreiborza commented Jun 22, 2026

Copy link
Copy Markdown
Member

Wires up the node SDK to use SentryTracerProvider when _experiments.useSentryTracerProvider is enabled (default opt-in).

When enabled, it uses our SentryTracerProvider and async context strategy instead of the Otel SDK's.

For simplicity, a flag is used, but we could change this to be an explicit call (+ a flag to opt out of the current tracer provider) to save some bundle size.

@andreiborza andreiborza requested a review from a team as a code owner June 22, 2026 09:35
@andreiborza andreiborza requested review from JPeer264 and mydea and removed request for a team June 22, 2026 09:35
@nicohrubec nicohrubec self-requested a review June 22, 2026 09:46
@github-actions

github-actions Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 27.47 kB - -
@sentry/browser - with treeshaking flags 25.91 kB - -
@sentry/browser (incl. Tracing) 45.96 kB -0.01% -1 B 🔽
@sentry/browser (incl. Tracing + Span Streaming) 47.72 kB +0.01% +1 B 🔺
@sentry/browser (incl. Tracing, Profiling) 50.76 kB - -
@sentry/browser (incl. Tracing, Replay) 85.22 kB +0.01% +2 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 74.81 kB +0.01% +3 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 89.92 kB +0.01% +3 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 102.57 kB +0.01% +5 B 🔺
@sentry/browser (incl. Feedback) 44.66 kB - -
@sentry/browser (incl. sendFeedback) 32.26 kB - -
@sentry/browser (incl. FeedbackAsync) 37.4 kB - -
@sentry/browser (incl. Metrics) 28.54 kB - -
@sentry/browser (incl. Logs) 28.78 kB - -
@sentry/browser (incl. Metrics & Logs) 29.47 kB - -
@sentry/react 29.27 kB - -
@sentry/react (incl. Tracing) 48.28 kB - -
@sentry/vue 32.63 kB +0.01% +3 B 🔺
@sentry/vue (incl. Tracing) 47.84 kB - -
@sentry/svelte 27.5 kB - -
CDN Bundle 29.89 kB - -
CDN Bundle (incl. Tracing) 47.9 kB +0.02% +9 B 🔺
CDN Bundle (incl. Logs, Metrics) 31.44 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 49.25 kB +0.03% +13 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 70.78 kB - -
CDN Bundle (incl. Tracing, Replay) 85.41 kB +0.02% +10 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 86.69 kB +0.02% +9 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 91.2 kB +0.02% +12 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.46 kB +0.02% +10 B 🔺
CDN Bundle - uncompressed 88.94 kB - -
CDN Bundle (incl. Tracing) - uncompressed 145.12 kB +0.07% +91 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 93.65 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 149.09 kB +0.07% +91 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 218.62 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 264.14 kB +0.04% +91 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 268.1 kB +0.04% +91 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 277.84 kB +0.04% +91 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 281.78 kB +0.04% +91 B 🔺
@sentry/nextjs (client) 50.67 kB +0.01% +2 B 🔺
@sentry/sveltekit (client) 46.37 kB +0.02% +6 B 🔺
@sentry/core/server 76.53 kB +0.05% +34 B 🔺
@sentry/core/browser 63.65 kB +0.04% +21 B 🔺
@sentry/node-core 61.62 kB +0.19% +116 B 🔺
@sentry/node 123.6 kB +0.78% +951 B 🔺
@sentry/node/import (ESM hook with diagnostics-channel injection) 69.95 kB - -
@sentry/node/light 50.42 kB +0.04% +19 B 🔺
@sentry/node - without tracing 74.39 kB +1.15% +844 B 🔺
@sentry/aws-serverless 85.61 kB +1.04% +874 B 🔺
@sentry/cloudflare (withSentry) - minified 177.04 kB +0.08% +124 B 🔺
@sentry/cloudflare (withSentry) 439.9 kB +0.06% +241 B 🔺

View base workflow run

@andreiborza andreiborza changed the title feat(node): Wire up _experiments.useSentryTracerProvider feat(node): Wire up SentryTracerProvider Jun 22, 2026
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-node branch from e05567e to dc3cd9d Compare June 22, 2026 11:32
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-otel branch from 7f2f88d to 172dd9f Compare June 22, 2026 11:49
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-node branch from dc3cd9d to f3c0c65 Compare June 22, 2026 11:49
Comment thread packages/node/src/sdk/initOtel.ts Outdated
coreDebug.warn(
'Could not register SentryTracerProvider because another OpenTelemetry tracer provider is already registered.',
);
return [undefined, undefined];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

m: is this in a good state if the setup fails here? we won't install the sentry propagator and context manager in here and then we also bail early in the main setupOtel method but we already set up the otel async context strategy. might be fine just checking

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

There is no good state if the tracer provider registration fails users won't get proper traces, but there's no way to recover from this because you can only ever register one global tracer provider and if one is already registered you can't do anything.

That's why we log here, I think it's fine as is.

Comment thread packages/node/src/sdk/initOtel.ts Outdated
): [BasicTracerProvider, AsyncLocalStorageLookup] {
): [OpenTelemetryTraceProvider | undefined, AsyncLocalStorageLookup | undefined] {
if (client.getOptions()._experiments?.useSentryTracerProvider) {
setOpenTelemetryContextAsyncContextStrategy();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

m: do we even need to call this here? setupOtel is called from initOpenTelemetry, which is called in the node init after we make the node-core init which also makes this same call:

setOpenTelemetryContextAsyncContextStrategy();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Removed in 324c8e8

@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-otel branch from 172dd9f to afb77ef Compare June 22, 2026 18:20
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-node branch from e200c8f to 502dca9 Compare June 22, 2026 18:20
Comment thread packages/node/src/sdk/initOtel.ts
Comment thread packages/node/src/sdk/initOtel.ts
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-otel branch from afb77ef to fcdf2df Compare June 22, 2026 18:30
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-node branch from 502dca9 to 6ae8302 Compare June 22, 2026 18:30
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-otel branch 2 times, most recently from 2c670f3 to 308e560 Compare June 22, 2026 18:46
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-node branch from 6ae8302 to e2f91c0 Compare June 22, 2026 18:46
Comment thread packages/node/test/sdk/init.test.ts
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-node branch 2 times, most recently from 4a3010c to d2384e8 Compare June 22, 2026 22:34
Comment thread packages/node/src/sdk/initOtel.ts
Comment thread packages/core/src/types/options.ts Outdated
* @default false
* @experimental
*/
useSentryTracerProvider?: boolean;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should this live in core? is this not a node-specific option?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

also, why experimental? this can just be a regular option, and as discussed I'd actually make it opt-out (or more specifically, make the default dynamic based on if any options are set that require the more fully features tracer, e.g. spanProcessors)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Wouldn't this be a breaking change? I thought the opt-out would be rather for v11 and in v10 it's opt-in

@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-otel branch 2 times, most recently from cc82764 to 400be89 Compare June 23, 2026 15:50
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-node branch from 06f6f64 to 6759aa8 Compare June 23, 2026 19:13
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-node branch from 6759aa8 to 39d4066 Compare June 24, 2026 08:44
@andreiborza andreiborza requested a review from a team as a code owner June 24, 2026 08:44
@andreiborza andreiborza requested review from Lms24, logaretm and mydea and removed request for a team June 24, 2026 08:44
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-otel branch from 400be89 to 0cb493b Compare June 24, 2026 08:44
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-node branch 3 times, most recently from 65315bf to 94c9cfd Compare June 24, 2026 12:56
Comment thread packages/node/src/sdk/initOtel.ts
Comment thread packages/node/src/sdk/initOtel.ts Outdated
});

client.on('preprocessEvent', event => {
if (event.type !== 'transaction' || client.getOptions().traceLifecycle === 'stream') {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

l: event processors aren't called for streamed spans, so no need to check here (unless I'm missing something 😅)

Suggested change
if (event.type !== 'transaction' || client.getOptions().traceLifecycle === 'stream') {
if (event.type !== 'transaction') {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Right, removed! Turns out we don't backfill these otel resources in span streaming but that's probably fine. We are thinking of going away from them completely in v11. TBD.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Dropped in 2db451e

@andreiborza andreiborza marked this pull request as draft June 24, 2026 13:01

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

Comment thread packages/node/src/sdk/initOtel.ts
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-node branch from 2db451e to 96e1f2e Compare June 24, 2026 14:46
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-otel branch from babe9a6 to 71ecd8d Compare June 24, 2026 15:43
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-node branch 2 times, most recently from 04aee59 to 4b3ecb1 Compare June 24, 2026 17:02
Add the SentryTracerProvider under an experimental `useSentryTracerProvider`
flag and update the node setup path to register the new TracerProvider and its
async context strategy instead of the full OTel SDK tracer provider when
enabled.
Outside of span streaming, an outgoing fetch (`http.client`) span with no local
parent is no longer recorded as a standalone transaction — the downstream
sampling decision is left to the server. This is enforced via `onlyIfParent`,
which still creates a non-recording span so trace propagation headers are
injected.

This rule already lives in `SentrySampler`, but that only runs when an
OpenTelemetry SDK tracer provider is set up. Enforcing it in the instrumentation
makes it hold for the `SentryTracerProvider` and for SDKs that don't use an
OpenTelemetry tracer provider at all. The sampler rule is kept for OpenTelemetry
SDK / custom OpenTelemetry setups.
@andreiborza andreiborza force-pushed the ab/sentry-trace-provider-node branch from 58c53f4 to 1e0d83e Compare June 24, 2026 20:23
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.

5 participants