feat(node): Wire up SentryTracerProvider#21680
Conversation
size-limit report 📦
|
e05567e to
dc3cd9d
Compare
7f2f88d to
172dd9f
Compare
dc3cd9d to
f3c0c65
Compare
| coreDebug.warn( | ||
| 'Could not register SentryTracerProvider because another OpenTelemetry tracer provider is already registered.', | ||
| ); | ||
| return [undefined, undefined]; |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
| ): [BasicTracerProvider, AsyncLocalStorageLookup] { | ||
| ): [OpenTelemetryTraceProvider | undefined, AsyncLocalStorageLookup | undefined] { | ||
| if (client.getOptions()._experiments?.useSentryTracerProvider) { | ||
| setOpenTelemetryContextAsyncContextStrategy(); |
There was a problem hiding this comment.
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:
172dd9f to
afb77ef
Compare
e200c8f to
502dca9
Compare
afb77ef to
fcdf2df
Compare
502dca9 to
6ae8302
Compare
2c670f3 to
308e560
Compare
6ae8302 to
e2f91c0
Compare
4a3010c to
d2384e8
Compare
| * @default false | ||
| * @experimental | ||
| */ | ||
| useSentryTracerProvider?: boolean; |
There was a problem hiding this comment.
should this live in core? is this not a node-specific option?
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
Wouldn't this be a breaking change? I thought the opt-out would be rather for v11 and in v10 it's opt-in
cc82764 to
400be89
Compare
06f6f64 to
6759aa8
Compare
400be89 to
0cb493b
Compare
65315bf to
94c9cfd
Compare
| }); | ||
|
|
||
| client.on('preprocessEvent', event => { | ||
| if (event.type !== 'transaction' || client.getOptions().traceLifecycle === 'stream') { |
There was a problem hiding this comment.
l: event processors aren't called for streamed spans, so no need to check here (unless I'm missing something 😅)
| if (event.type !== 'transaction' || client.getOptions().traceLifecycle === 'stream') { | |
| if (event.type !== 'transaction') { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ 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.
2db451e to
96e1f2e
Compare
babe9a6 to
71ecd8d
Compare
58c53f4 to
1e0d83e
Compare
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.
1e0d83e to
8aeffe4
Compare

Wires up the node SDK to use
SentryTracerProviderwhen_experiments.useSentryTracerProvideris 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.