Skip to content

WIP feat(opentelemetry): Add SentryTraceProvider#21181

Draft
andreiborza wants to merge 25 commits into
developfrom
ab/sentry-tracer-provider
Draft

WIP feat(opentelemetry): Add SentryTraceProvider#21181
andreiborza wants to merge 25 commits into
developfrom
ab/sentry-tracer-provider

Conversation

@andreiborza

Copy link
Copy Markdown
Member

WIP

Comment thread packages/opentelemetry/src/sentryTraceProvider.ts
@github-actions

github-actions Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 27.39 kB +0.01% +1 B 🔺
@sentry/browser - with treeshaking flags 25.82 kB +0.01% +2 B 🔺
@sentry/browser (incl. Tracing) 46 kB +0.7% +318 B 🔺
@sentry/browser (incl. Tracing + Span Streaming) 48.25 kB +0.69% +329 B 🔺
@sentry/browser (incl. Tracing, Profiling) 50.77 kB +0.58% +288 B 🔺
@sentry/browser (incl. Tracing, Replay) 85.19 kB +0.35% +294 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 74.8 kB +0.39% +286 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 89.9 kB +0.34% +301 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 102.57 kB +0.28% +282 B 🔺
@sentry/browser (incl. Feedback) 44.55 kB +0.01% +1 B 🔺
@sentry/browser (incl. sendFeedback) 32.19 kB -0.01% -1 B 🔽
@sentry/browser (incl. FeedbackAsync) 37.3 kB +0.01% +2 B 🔺
@sentry/browser (incl. Metrics) 28.46 kB +0.02% +3 B 🔺
@sentry/browser (incl. Logs) 28.7 kB +0.02% +3 B 🔺
@sentry/browser (incl. Metrics & Logs) 29.39 kB +0.01% +2 B 🔺
@sentry/react 29.18 kB +0.02% +3 B 🔺
@sentry/react (incl. Tracing) 48.33 kB +0.74% +351 B 🔺
@sentry/vue 32.63 kB +0.7% +226 B 🔺
@sentry/vue (incl. Tracing) 47.87 kB +0.63% +298 B 🔺
@sentry/svelte 27.41 kB -0.01% -1 B 🔽
CDN Bundle 29.81 kB +0.11% +32 B 🔺
CDN Bundle (incl. Tracing) 48.52 kB +0.74% +356 B 🔺
CDN Bundle (incl. Logs, Metrics) 31.35 kB +0.09% +26 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 49.83 kB +0.72% +352 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 70.64 kB +0.05% +31 B 🔺
CDN Bundle (incl. Tracing, Replay) 85.85 kB +0.4% +340 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 87.13 kB +0.44% +380 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 91.71 kB +0.4% +364 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.97 kB +0.4% +369 B 🔺
CDN Bundle - uncompressed 88.54 kB +0.1% +80 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 146.91 kB +0.85% +1.23 kB 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 93.25 kB +0.09% +80 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 150.88 kB +0.83% +1.23 kB 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 218.07 kB +0.04% +80 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 265.78 kB +0.47% +1.24 kB 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 269.74 kB +0.47% +1.24 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 279.48 kB +0.45% +1.24 kB 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 283.43 kB +0.45% +1.24 kB 🔺
@sentry/nextjs (client) 50.71 kB +0.57% +284 B 🔺
@sentry/sveltekit (client) 46.42 kB +0.69% +315 B 🔺
@sentry/core/server 76.22 kB +0.28% +209 B 🔺
@sentry/core/browser 63.36 kB +0.35% +219 B 🔺
@sentry/node-core 62.07 kB +0.57% +350 B 🔺
@sentry/node 131.76 kB +1.05% +1.36 kB 🔺
@sentry/node - without tracing 75.35 kB +1.69% +1.25 kB 🔺
@sentry/aws-serverless 87.66 kB +1.59% +1.37 kB 🔺
@sentry/cloudflare (withSentry) - minified 174.85 kB +0.68% +1.17 kB 🔺
@sentry/cloudflare (withSentry) 437.07 kB +0.75% +3.23 kB 🔺

View base workflow run

@andreiborza andreiborza force-pushed the ab/sentry-tracer-provider branch from 0f2020a to 71e7c69 Compare May 27, 2026 05:27
Comment thread packages/core/src/tracing/sentrySpan.ts Outdated
*/
public recordException(_exception: unknown, _time?: number | undefined): void {
// noop
public recordException(exception: unknown, time?: SpanTimeInput | undefined): void {

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.

I think we can leave this as noop, we do not care about this and do not really support it, doing nothing with events etc.

@andreiborza andreiborza force-pushed the ab/sentry-tracer-provider branch from 71e7c69 to a44215e Compare May 28, 2026 04:15
Comment thread packages/opentelemetry/src/sentryTraceProvider.ts
Comment thread packages/node/src/sdk/initOtel.ts
Comment thread packages/opentelemetry/src/sentryTraceProvider.ts
@andreiborza andreiborza force-pushed the ab/sentry-tracer-provider branch from cf369b6 to 749e7e7 Compare June 6, 2026 22:56
Comment thread packages/node/src/sdk/initOtel.ts
Comment thread packages/core/src/tracing/trace.ts
@andreiborza andreiborza force-pushed the ab/sentry-tracer-provider branch 5 times, most recently from f79c234 to 8ebaf6b Compare June 8, 2026 08:54
andreiborza and others added 8 commits June 8, 2026 12:53
# Conflicts:
#	dev-packages/e2e-tests/test-applications/nextjs-13/instrumentation.ts
#	dev-packages/e2e-tests/test-applications/nextjs-14/instrumentation.ts
#	dev-packages/e2e-tests/test-applications/nextjs-15-basepath/sentry.server.config.ts
#	dev-packages/e2e-tests/test-applications/nextjs-15-intl/sentry.server.config.ts
#	dev-packages/e2e-tests/test-applications/nextjs-15/sentry.server.config.ts
#	dev-packages/e2e-tests/test-applications/nextjs-16-cacheComponents/sentry.server.config.ts
#	dev-packages/e2e-tests/test-applications/nextjs-16-streaming/sentry.server.config.ts
#	dev-packages/e2e-tests/test-applications/nextjs-16-trailing-slash/sentry.server.config.ts
#	dev-packages/e2e-tests/test-applications/nextjs-16-tunnel/sentry.server.config.ts
#	dev-packages/e2e-tests/test-applications/nextjs-16-userfeedback/sentry.server.config.ts
#	dev-packages/e2e-tests/test-applications/nextjs-16/sentry.server.config.ts
#	dev-packages/e2e-tests/test-applications/nextjs-app-dir/instrumentation.ts
#	dev-packages/e2e-tests/test-applications/nextjs-pages-dir/instrumentation.ts
#	dev-packages/e2e-tests/test-applications/supabase-nextjs/sentry.server.config.ts
SentryNonRecordingSpan can now store a `sampled` flag that distinguishes
"sampled negative" from "no sampling decision yet" in TwP mode. Trace
header generation uses the new `spanToTraceSamplingDecision` helper to
propagate this decision instead of always inferring from traceFlags.

Also aligns `recordException` signature to use `SpanTimeInput` on both
the Span interface and its implementations.

Co-Authored-By: Claude <noreply@anthropic.com>
@andreiborza andreiborza force-pushed the ab/sentry-tracer-provider branch from 8ebaf6b to 2b70730 Compare June 8, 2026 10:54
Comment thread packages/core/src/utils/spanUtils.ts
@andreiborza andreiborza force-pushed the ab/sentry-tracer-provider branch from 959483b to 87ed1f0 Compare June 8, 2026 14:05
andreiborza and others added 2 commits June 9, 2026 12:03
Co-Authored-By: Claude <noreply@anthropic.com>
In Tracing without Performance mode, a root non-recording span froze a DSC whose
`transaction` was always the local span name, overwriting the frozen transaction
of a continued trace. Keep the incoming/derived transaction and only fall back
to the local span name when there is none.

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread packages/opentelemetry/src/sentryTraceProvider.ts
andreiborza and others added 2 commits June 9, 2026 16:14
Explain that the getter exists so the generic `spanToJSON` fallback can surface
`parent_span_id` for non-recording spans.

Co-Authored-By: Claude <noreply@anthropic.com>
…ir parent

When tracing is suppressed, `_createNonRecordingSpan` copied only the parent's
`traceId` and dropped its `spanId`, so a child span under a suppressed active
parent did not carry `parent_span_id` in span JSON or trace headers. Pass the
parent `spanId` as `parentSpanId` so the parent link is preserved.

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread packages/core/src/tracing/trace.ts
…otSpan

The scope-capture move into `_startRootSpan`/`_startChildSpan` left the
non-recording return paths (tracing disabled, ignored spans, and the no-client
child) without captured scopes. SentryTraceProvider.startActiveSpan reads those
scopes to fork the isolation scope onto the OTel context, so attach them on
every span returned from createChildOrRootSpan.

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread packages/opentelemetry/src/sentryTraceProvider.ts
Comment thread packages/opentelemetry/src/sentryTraceProvider.ts Outdated
andreiborza and others added 3 commits June 9, 2026 17:46
…istration

The provider called `setIsSetup('SentryTraceProvider')` in its constructor,
before `trace.setGlobalTracerProvider` ran. If registration failed (another
tracer provider already registered), setup validation still treated the minimal
provider as configured while the global tracer was a different implementation,
skipping the required SentrySpanProcessor/SentrySampler checks. Move the marking
to `setupSentryTraceProvider` after a successful registration.

Co-Authored-By: Claude <noreply@anthropic.com>
Align idle spans and `startSpan`/`startInactiveSpan` in Tracing without
Performance mode: when continuing a trace, freeze the incoming DSC as-is (even
an empty `{}` from a `sentry-trace` header without baggage) instead of merging
in the local span name or fabricating client fields. Only a new trace derives
the DSC from the client and attaches the local span name. Idle spans now defer
the sampling decision in TwP like `startSpan`.

Co-Authored-By: Claude <noreply@anthropic.com>
When tracing is suppressed, `startSpan` returns `_createNonRecordingSpan`
directly, bypassing the `_INTERNAL_startInactiveSpan`/`createChildOrRootSpan`
path where scopes are captured. As a result `startActiveSpan` read no captured
isolation scope and couldn't fork it onto the OTel context, breaking scope
isolation for work inside suppressed active spans. Capture the current scope and
isolation scope on the non-recording span, mirroring `createChildOrRootSpan`.

Co-Authored-By: Claude <noreply@anthropic.com>
Comment thread packages/core/src/tracing/idleSpan.ts
andreiborza and others added 2 commits June 9, 2026 18:43
In Tracing without Performance mode `startIdleSpan` builds a non-recording
placeholder and freezes its DSC but never attached the current/isolation scopes,
unlike the parallel non-recording paths in `createChildOrRootSpan`. Capture them
so consumers like SentryTraceProvider can read the scopes off the placeholder.

Co-Authored-By: Claude <noreply@anthropic.com>
… spans

Non-recording child spans (unsampled) and ignored spans now carry their
parent's span id, so `spanToJSON` surfaces `parent_span_id` for them. Also store
captured scopes on the TwP placeholder in `startSpan`/`startSpanManual`.

Co-Authored-By: Claude <noreply@anthropic.com>

@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 5917bab. Configure here.

Comment thread packages/node/src/sdk/initOtel.ts
andreiborza and others added 3 commits June 9, 2026 20:52
Mirror `getDynamicSamplingContextFromSpan`: when a TwP placeholder span's source
is "url", omit the local span name from the frozen DSC (URLs may contain PII).
Applies to both `createChildOrRootSpan` and `startIdleSpan`.

Co-Authored-By: Claude <noreply@anthropic.com>
…sEvent

In the SentryTraceProvider transaction `preprocessEvent` hook, the response
context spread `...event.contexts.response` after setting `status_code` from
`http.response.status_code`, so a pre-existing `response.status_code` overrode
the span-derived value. Spread the existing response first so the span-derived
status_code wins.

Co-Authored-By: Claude <noreply@anthropic.com>
Add an `includeTransaction` option to the `eventEnvelope` helper and use it where
the http.server span source is `url` (the TwP DSC omits the span name as raw URLs
may contain PII). Adds a dedicated dsc-url-source suite proving the name is absent
from the DSC even when tracing is enabled and a transaction is recorded.

Co-Authored-By: Claude <noreply@anthropic.com>
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.

2 participants