From 5c45bc2c93a7960517e490cd16306642d572d547 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Fri, 7 Aug 2026 12:53:52 +0200 Subject: [PATCH 01/16] chore: Document the three OpenTelemetry setups in the migration guide Co-Authored-By: Claude Opus 5 --- MIGRATION.md | 84 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 9d32a3bad9ae..6c2a9d11e0cf 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -82,40 +82,50 @@ Only `@sentry/nextjs` and `@sentry/sveltekit` still set up an OpenTelemetry comp This means you can run your own OpenTelemetry setup cleanly alongside Sentry without having Sentry spans leak into your pipeline anymore. Your OpenTelemetry setup will no longer be required to use Sentry components for exporting, context management and trace propagation. -This behavior is controlled by the existing `skipOpenTelemetrySetup` option, whose default was flipped in v11. It now defaults to `true` for most server SDKs (including `@sentry/node`, `@sentry/bun`, the serverless SDKs, and `@sentry/cloudflare`) and to `false` for `@sentry/nextjs` and `@sentry/sveltekit`. When `true`, the SDK skips the tracer provider and isolates scopes with a native AsyncLocalStorage strategy; it still emits its own spans, but spans you create through `@opentelemetry/api` are not captured. Set it to `false` to have Sentry register its own `SentryTracerProvider` as the global OpenTelemetry tracer provider, so those `@opentelemetry/api` spans become Sentry spans: +With this, we also heavily reduced our OpenTelemetry dependencies, with `@opentelemetry/api` being the only remaining package we abide by. These changes also mean `@sentry/node-core` no longer serves any purpose and was [merged back into `@sentry/node`](#sentrynode-core-was-merged-back-into-sentrynode). + +For most users, day-to-day tracing is **unchanged**. + +#### Choosing an OpenTelemetry setup + +There are three ways to run the two together, and which one you want depends on who should own spans. This is controlled by the existing `skipOpenTelemetrySetup` option, whose default was flipped in v11: it is now `true` for most server SDKs (including `@sentry/node`, `@sentry/bun`, the serverless SDKs and `@sentry/cloudflare`) and `false` for `@sentry/nextjs` and `@sentry/sveltekit`. + +##### 1. Sentry only, OpenTelemetry ignored + +This is the default for every server-side SDK except `@sentry/nextjs` and `@sentry/sveltekit`. Nothing to configure: ```js Sentry.init({ dsn: '__DSN__', - // Register Sentry's OpenTelemetry tracer provider so spans created via `@opentelemetry/api` are captured - skipOpenTelemetrySetup: false, + tracesSampleRate: 1.0, }); ``` -Note that `skipOpenTelemetrySetup: false` makes Sentry the OpenTelemetry tracer provider. If you run your own tracer provider, keep `skipOpenTelemetrySetup: true` so Sentry does not register a competing provider. The SDK no longer ships a `SentrySpanProcessor` or other components to route your OpenTelemetry spans into Sentry, so spans from your own provider stay in your OpenTelemetry pipeline and are not sent to Sentry. +The SDK emits native Sentry spans and never registers an OpenTelemetry tracer provider or propagator. Scope isolation uses `AsyncLocalStorage` directly. + +Spans created through `@opentelemetry/api` are **ignored**. If a library you depend on emits OpenTelemetry spans and you want them in Sentry, use setup 2. + +##### 2. Light OpenTelemetry mode, everything goes to Sentry -In v10, setting `skipOpenTelemetrySetup: true` also turned Sentry's own HTTP and fetch spans off by default, on the assumption that your own OpenTelemetry `HttpInstrumentation` would emit them instead. That is no longer the case: Sentry now emits HTTP and fetch spans whenever tracing is enabled, regardless of `skipOpenTelemetrySetup`. If you run your own OpenTelemetry HTTP instrumentation alongside Sentry, disable Sentry's spans to avoid duplicates: +Set `skipOpenTelemetrySetup: false`: ```js Sentry.init({ dsn: '__DSN__', - integrations: [ - // Let your own OpenTelemetry HttpInstrumentation own HTTP & fetch spans - Sentry.httpIntegration({ spans: false }), - Sentry.nativeNodeFetchIntegration({ spans: false }), - ], + tracesSampleRate: 1.0, + skipOpenTelemetrySetup: false, }); ``` -With this, we also heavily reduced our OpenTelemetry dependencies, with `@opentelemetry/api` being the only remaining package we abide by. These changes also mean `@sentry/node-core` no longer serves any purpose and was [merged back into `@sentry/node`](#sentrynode-core-was-merged-back-into-sentrynode). +Sentry registers a minimal tracer provider, context manager and propagator. Just enough OpenTelemetry to pick up spans created through `@opentelemetry/api`, which become native Sentry spans. -For most users, day-to-day tracing is **unchanged**. +This is what `@sentry/nextjs` and `@sentry/sveltekit` do by default, because those frameworks emit OpenTelemetry spans that would otherwise be lost. -#### Connecting Sentry to your OpenTelemetry traces +Everything goes to Sentry and only to Sentry. This is not a general OpenTelemetry pipeline: there is no exporter, no OTLP output, and no way to fan spans out to another backend. Sentry also refuses to register its provider if you already registered one of your own, logging a warning instead. If you want a real OpenTelemetry pipeline, use setup 3. -`Sentry.otlpIntegration()` attaches everything Sentry sends that carries trace information (errors, logs, metrics and crons) to the OpenTelemetry span that is active when it happens. It takes no options, and is available from every server-side SDK, so there is nothing extra to install or import. +##### 3. Your own OpenTelemetry, Sentry linked to it -It does not set up a span exporter, span processor, or tracer provider. You keep full ownership of your OpenTelemetry pipeline, and outgoing request propagation is left to your OpenTelemetry propagator. To send your spans to Sentry, point your own exporter at the URL and auth headers that `Sentry.getOtlpTracesEndpoint()` derives from your DSN: +Turn Sentry tracing off, own the OpenTelemetry setup yourself, and add `otlpIntegration()`: ```js import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; @@ -131,28 +141,50 @@ provider.register(); Sentry.init({ dsn: '__DSN__', + // no tracesSampleRate: OpenTelemetry owns spans, Sentry owns errors and logs integrations: [Sentry.otlpIntegration()], }); ``` -An active Sentry span still takes precedence, so this only changes what happens when Sentry has no span of its own, which is the usual setup when OpenTelemetry owns tracing. +OpenTelemetry owns spans end to end. Sentry captures errors and logs, and `otlpIntegration()` attaches them to whatever OpenTelemetry span is active so they land on the same trace. `getOtlpTracesEndpoint()` turns your DSN into the URL and auth headers for Sentry's OTLP endpoint, so you can point your own exporter at Sentry, at your own collector, or at both. -If you used the v10 integration from `@sentry/node-core/light/otlp`, three things changed: it moved to the main export of every server SDK, it [no longer sets up an exporter for you and lost its options](#3-removed-apis), and it [reports itself as `Otlp` rather than `OtlpIntegration`](#otlpintegration-integration-renamed-to-otlp). Configure your own exporter as shown above, pointing it at your collector's URL if you route through one. +Sentry does not touch your pipeline: no exporter, no span processor, no tracer provider, and outgoing trace propagation is left to your propagator. See [Connecting Sentry to your OpenTelemetry traces](#connecting-sentry-to-your-opentelemetry-traces) for the details, including what changed if you used the v10 integration. -```js -// before -import * as Sentry from '@sentry/node-core/light'; -import { otlpIntegration } from '@sentry/node-core/light/otlp'; +##### Avoiding duplicate spans -Sentry.init({ dsn: '__DSN__', integrations: [otlpIntegration()] }); +Leaving `tracesSampleRate` unset is what keeps setup 3 clean. Sentry instruments many of the same libraries OpenTelemetry does (Express, Postgres, Redis, Prisma, Kafka and so on), so enabling Sentry tracing on top of your own instrumentation gives you two spans for every operation. With tracing off, Sentry's instrumentation stays installed and keeps doing request isolation, but emits no spans, so there is nothing to collide. -// after -import * as Sentry from '@sentry/node'; +Note that this changed since v10, where setting `skipOpenTelemetrySetup: true` also turned Sentry's HTTP and fetch spans off by default. Sentry now emits those whenever tracing is enabled, regardless of `skipOpenTelemetrySetup`. -// set up your own tracer provider and exporter, then: -Sentry.init({ dsn: '__DSN__', integrations: [Sentry.otlpIntegration()] }); +If you do want Sentry spans alongside your own, drop the integrations that overlap. HTTP and fetch are the exception: keep those two and turn off only their spans, because `httpIntegration` also provides request isolation, request data and session tracking. + +```js +Sentry.init({ + dsn: '__DSN__', + tracesSampleRate: 1.0, + integrations: integrations => [ + // your own OpenTelemetry instrumentation already covers these + ...integrations.filter(integration => integration.name !== 'Postgres'), + Sentry.httpIntegration({ spans: false }), + Sentry.nativeNodeFetchIntegration({ spans: false }), + ], +}); ``` +##### The v10 bridge is gone + +If you previously wired Sentry into your own OpenTelemetry setup with `SentryContextManager`, `SentrySampler` and `SentrySpanProcessor`, that path no longer exists. Those components were removed, so there is no longer a way to route spans from your own provider into Sentry as Sentry spans. Export them over OTLP instead, as shown in setup 3. + +#### Connecting Sentry to your OpenTelemetry traces + +`Sentry.otlpIntegration()` attaches everything Sentry sends that carries trace information (errors, logs, metrics and crons) to the OpenTelemetry span that is active when it happens. It takes no options, and is available from every server-side SDK, so there is nothing extra to install or import. See [setup 3](#3-your-own-opentelemetry-sentry-linked-to-it) above for a complete example. + +It does not set up a span exporter, span processor, or tracer provider. You keep full ownership of your OpenTelemetry pipeline, and outgoing request propagation is left to your OpenTelemetry propagator. To send your spans to Sentry, point your own exporter at the URL and auth headers that `Sentry.getOtlpTracesEndpoint()` derives from your DSN. + +An active Sentry span still takes precedence, so this only changes what happens when Sentry has no span of its own, which is the usual setup when OpenTelemetry owns tracing. + +If you used the v10 integration from `@sentry/node-core/light/otlp`, three things changed: it moved to the main export of every server SDK, it [no longer sets up an exporter for you and lost its options](#3-removed-apis), and it [reports itself as `Otlp` rather than `OtlpIntegration`](#otlpintegration-integration-renamed-to-otlp). Configure your own exporter as shown in setup 3, pointing it at your collector's URL if you route through one. + > **TODO(v11):** Link to the upcoming guide covering common use cases with the new OpenTelemetry setup > (running your own OpenTelemetry setup alongside Sentry, connecting Sentry events to OTel traces, etc.). From d28ed780df91be9a8708311107411250f1db3fd6 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Fri, 7 Aug 2026 13:42:03 +0200 Subject: [PATCH 02/16] Rename setup 2 to OpenTelemetry-compatible mode --- MIGRATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index 6c2a9d11e0cf..65cb3713f396 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -105,7 +105,7 @@ The SDK emits native Sentry spans and never registers an OpenTelemetry tracer pr Spans created through `@opentelemetry/api` are **ignored**. If a library you depend on emits OpenTelemetry spans and you want them in Sentry, use setup 2. -##### 2. Light OpenTelemetry mode, everything goes to Sentry +##### 2. OpenTelemetry-compatible mode, everything goes to Sentry Set `skipOpenTelemetrySetup: false`: From ddc676f9c791ff9ff1c4b5da1bf2a8d3245b26ed Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Fri, 7 Aug 2026 14:39:26 +0200 Subject: [PATCH 03/16] Document the skipOpenTelemetrySetup requirement for setup 3 --- MIGRATION.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index 65cb3713f396..294e07cc59dc 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -125,7 +125,7 @@ Everything goes to Sentry and only to Sentry. This is not a general OpenTelemetr ##### 3. Your own OpenTelemetry, Sentry linked to it -Turn Sentry tracing off, own the OpenTelemetry setup yourself, and add `otlpIntegration()`: +Leave `skipOpenTelemetrySetup` unset or set it to `true`, turn Sentry tracing off, own the OpenTelemetry setup yourself, and add `otlpIntegration()`: ```js import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; @@ -146,6 +146,8 @@ Sentry.init({ }); ``` +`skipOpenTelemetrySetup` already defaults to `true` on most server SDKs, so there is nothing to set. On `@sentry/nextjs` and `@sentry/sveltekit` it defaults to `false`, so you have to set it explicitly. Otherwise Sentry registers its own tracer provider and you end up in setup 2 rather than this one. + OpenTelemetry owns spans end to end. Sentry captures errors and logs, and `otlpIntegration()` attaches them to whatever OpenTelemetry span is active so they land on the same trace. `getOtlpTracesEndpoint()` turns your DSN into the URL and auth headers for Sentry's OTLP endpoint, so you can point your own exporter at Sentry, at your own collector, or at both. Sentry does not touch your pipeline: no exporter, no span processor, no tracer provider, and outgoing trace propagation is left to your propagator. See [Connecting Sentry to your OpenTelemetry traces](#connecting-sentry-to-your-opentelemetry-traces) for the details, including what changed if you used the v10 integration. From 66787aa63590263356269401b675f6450a616fc7 Mon Sep 17 00:00:00 2001 From: Andrei <168741329+andreiborza@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:51:10 +0200 Subject: [PATCH 04/16] Update MIGRATION.md Co-authored-by: Nicolas Hrubec --- MIGRATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index 294e07cc59dc..56a6b3dc33a5 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -90,7 +90,7 @@ For most users, day-to-day tracing is **unchanged**. There are three ways to run the two together, and which one you want depends on who should own spans. This is controlled by the existing `skipOpenTelemetrySetup` option, whose default was flipped in v11: it is now `true` for most server SDKs (including `@sentry/node`, `@sentry/bun`, the serverless SDKs and `@sentry/cloudflare`) and `false` for `@sentry/nextjs` and `@sentry/sveltekit`. -##### 1. Sentry only, OpenTelemetry ignored +##### 1. Sentry only This is the default for every server-side SDK except `@sentry/nextjs` and `@sentry/sveltekit`. Nothing to configure: From 84799a0e0acb20c70247e017b6c0c332bb5b7c26 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Fri, 7 Aug 2026 14:53:32 +0200 Subject: [PATCH 05/16] Trim setup 1 to the Sentry-only case --- MIGRATION.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 56a6b3dc33a5..c09e4c2c714d 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -92,7 +92,7 @@ There are three ways to run the two together, and which one you want depends on ##### 1. Sentry only -This is the default for every server-side SDK except `@sentry/nextjs` and `@sentry/sveltekit`. Nothing to configure: +The default, and what most users want. Tracing works out of the box: ```js Sentry.init({ @@ -101,9 +101,7 @@ Sentry.init({ }); ``` -The SDK emits native Sentry spans and never registers an OpenTelemetry tracer provider or propagator. Scope isolation uses `AsyncLocalStorage` directly. - -Spans created through `@opentelemetry/api` are **ignored**. If a library you depend on emits OpenTelemetry spans and you want them in Sentry, use setup 2. +If a library you depend on emits its own OpenTelemetry spans and you want those in Sentry too, use setup 2. ##### 2. OpenTelemetry-compatible mode, everything goes to Sentry From 75d59637809ca49b835a82075823e6347b3e209b Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Fri, 7 Aug 2026 15:12:19 +0200 Subject: [PATCH 06/16] Clarify that setup 2 registers an OpenTelemetry-compatible provider --- MIGRATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index c09e4c2c714d..2b2256c9d9c3 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -115,7 +115,7 @@ Sentry.init({ }); ``` -Sentry registers a minimal tracer provider, context manager and propagator. Just enough OpenTelemetry to pick up spans created through `@opentelemetry/api`, which become native Sentry spans. +Sentry registers a minimal OpenTelemetry-compatible tracer provider, context manager and propagator. Just enough OpenTelemetry to pick up spans created through `@opentelemetry/api`, which become native Sentry spans. This is what `@sentry/nextjs` and `@sentry/sveltekit` do by default, because those frameworks emit OpenTelemetry spans that would otherwise be lost. From 35c15d808123643cd354ac6b42ac6860914b31fb Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Fri, 7 Aug 2026 15:17:01 +0200 Subject: [PATCH 07/16] Apply review feedback on setups 2 and 3 Drops the Next.js/SvelteKit note from setup 2, since setup 1 already points readers there when a library emits its own OpenTelemetry spans, and reword setup 3's opening. --- MIGRATION.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 2b2256c9d9c3..70f83b6e5dfc 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -117,13 +117,11 @@ Sentry.init({ Sentry registers a minimal OpenTelemetry-compatible tracer provider, context manager and propagator. Just enough OpenTelemetry to pick up spans created through `@opentelemetry/api`, which become native Sentry spans. -This is what `@sentry/nextjs` and `@sentry/sveltekit` do by default, because those frameworks emit OpenTelemetry spans that would otherwise be lost. - Everything goes to Sentry and only to Sentry. This is not a general OpenTelemetry pipeline: there is no exporter, no OTLP output, and no way to fan spans out to another backend. Sentry also refuses to register its provider if you already registered one of your own, logging a warning instead. If you want a real OpenTelemetry pipeline, use setup 3. ##### 3. Your own OpenTelemetry, Sentry linked to it -Leave `skipOpenTelemetrySetup` unset or set it to `true`, turn Sentry tracing off, own the OpenTelemetry setup yourself, and add `otlpIntegration()`: +Leave `skipOpenTelemetrySetup` unset or set it to `true`, turn Sentry tracing off, use your own OpenTelemetry setup, and add the Sentry `otlpIntegration()`: ```js import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; From 0d9ff5f3fba344a1e9d60d5e49de7df80c8a6574 Mon Sep 17 00:00:00 2001 From: Andrei <168741329+andreiborza@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:19:15 +0200 Subject: [PATCH 08/16] Update MIGRATION.md Co-authored-by: Nicolas Hrubec --- MIGRATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index 70f83b6e5dfc..5fc8e5407138 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -144,7 +144,7 @@ Sentry.init({ `skipOpenTelemetrySetup` already defaults to `true` on most server SDKs, so there is nothing to set. On `@sentry/nextjs` and `@sentry/sveltekit` it defaults to `false`, so you have to set it explicitly. Otherwise Sentry registers its own tracer provider and you end up in setup 2 rather than this one. -OpenTelemetry owns spans end to end. Sentry captures errors and logs, and `otlpIntegration()` attaches them to whatever OpenTelemetry span is active so they land on the same trace. `getOtlpTracesEndpoint()` turns your DSN into the URL and auth headers for Sentry's OTLP endpoint, so you can point your own exporter at Sentry, at your own collector, or at both. +OpenTelemetry owns spans end to end. Sentry captures errors and logs, and the Sentry `otlpIntegration()` attaches them to the active OpenTelemetry span so all your telemetry is connected in one trace. `getOtlpTracesEndpoint()` turns your DSN into the URL and auth headers for Sentry's OTLP endpoint, so you can point your own exporter at Sentry, at your own collector, or at both. Sentry does not touch your pipeline: no exporter, no span processor, no tracer provider, and outgoing trace propagation is left to your propagator. See [Connecting Sentry to your OpenTelemetry traces](#connecting-sentry-to-your-opentelemetry-traces) for the details, including what changed if you used the v10 integration. From 1459211a334c8f5d89b9fbae6c1de2650d2d532d Mon Sep 17 00:00:00 2001 From: Andrei <168741329+andreiborza@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:22:17 +0200 Subject: [PATCH 09/16] Update MIGRATION.md Co-authored-by: Charly Gomez --- MIGRATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index 5fc8e5407138..9cf6163086b3 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -82,7 +82,7 @@ Only `@sentry/nextjs` and `@sentry/sveltekit` still set up an OpenTelemetry comp This means you can run your own OpenTelemetry setup cleanly alongside Sentry without having Sentry spans leak into your pipeline anymore. Your OpenTelemetry setup will no longer be required to use Sentry components for exporting, context management and trace propagation. -With this, we also heavily reduced our OpenTelemetry dependencies, with `@opentelemetry/api` being the only remaining package we abide by. These changes also mean `@sentry/node-core` no longer serves any purpose and was [merged back into `@sentry/node`](#sentrynode-core-was-merged-back-into-sentrynode). +With this, we also heavily reduced our OpenTelemetry dependencies, with `@opentelemetry/api` being the only one remaining. These changes also mean `@sentry/node-core` no longer serves any purpose and was [merged back into `@sentry/node`](#sentrynode-core-was-merged-back-into-sentrynode). For most users, day-to-day tracing is **unchanged**. From 775d210207065bf932bf4f2b841990070b72f8a1 Mon Sep 17 00:00:00 2001 From: Andrei <168741329+andreiborza@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:23:11 +0200 Subject: [PATCH 10/16] Update MIGRATION.md Co-authored-by: Nicolas Hrubec --- MIGRATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index 9cf6163086b3..30b5c4c7e079 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -150,7 +150,7 @@ Sentry does not touch your pipeline: no exporter, no span processor, no tracer p ##### Avoiding duplicate spans -Leaving `tracesSampleRate` unset is what keeps setup 3 clean. Sentry instruments many of the same libraries OpenTelemetry does (Express, Postgres, Redis, Prisma, Kafka and so on), so enabling Sentry tracing on top of your own instrumentation gives you two spans for every operation. With tracing off, Sentry's instrumentation stays installed and keeps doing request isolation, but emits no spans, so there is nothing to collide. +Sentry instruments many of the same libraries OpenTelemetry does (Express, Postgres, Redis, Prisma, Kafka and so on), so enabling Sentry tracing on top of your own instrumentation gives you two spans for every operation. Leave `traceSampleRate` in your `Sentry.init` unset to avoid duplicate spans. With tracing off, Sentry's instrumentation stays installed and keeps isolating requests, but emits no spans. Note that this changed since v10, where setting `skipOpenTelemetrySetup: true` also turned Sentry's HTTP and fetch spans off by default. Sentry now emits those whenever tracing is enabled, regardless of `skipOpenTelemetrySetup`. From 122c4f3fe35d7faf6bf989162cd7c87be6b10db8 Mon Sep 17 00:00:00 2001 From: Andrei <168741329+andreiborza@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:23:47 +0200 Subject: [PATCH 11/16] Update MIGRATION.md Co-authored-by: Nicolas Hrubec --- MIGRATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index 30b5c4c7e079..75040cdb7bc4 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -154,7 +154,7 @@ Sentry instruments many of the same libraries OpenTelemetry does (Express, Postg Note that this changed since v10, where setting `skipOpenTelemetrySetup: true` also turned Sentry's HTTP and fetch spans off by default. Sentry now emits those whenever tracing is enabled, regardless of `skipOpenTelemetrySetup`. -If you do want Sentry spans alongside your own, drop the integrations that overlap. HTTP and fetch are the exception: keep those two and turn off only their spans, because `httpIntegration` also provides request isolation, request data and session tracking. +If you do want Sentry spans alongside your own, keep `traceSampleRate` set and drop the integrations that overlap. HTTP and fetch are the exception: turn off only their spans, because `httpIntegration` also provides request isolation, request data and session tracking: ```js Sentry.init({ From a4ece4f6834b9a61bea5a75e5a722b9f460e36ce Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Fri, 7 Aug 2026 15:26:03 +0200 Subject: [PATCH 12/16] Fix traceSampleRate typo in the duplicate spans section The option is `tracesSampleRate`. --- MIGRATION.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 75040cdb7bc4..80a17b99df73 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -150,11 +150,11 @@ Sentry does not touch your pipeline: no exporter, no span processor, no tracer p ##### Avoiding duplicate spans -Sentry instruments many of the same libraries OpenTelemetry does (Express, Postgres, Redis, Prisma, Kafka and so on), so enabling Sentry tracing on top of your own instrumentation gives you two spans for every operation. Leave `traceSampleRate` in your `Sentry.init` unset to avoid duplicate spans. With tracing off, Sentry's instrumentation stays installed and keeps isolating requests, but emits no spans. +Sentry instruments many of the same libraries OpenTelemetry does (Express, Postgres, Redis, Prisma, Kafka and so on), so enabling Sentry tracing on top of your own instrumentation gives you two spans for every operation. Leave `tracesSampleRate` in your `Sentry.init` unset to avoid duplicate spans. With tracing off, Sentry's instrumentation stays installed and keeps isolating requests, but emits no spans. Note that this changed since v10, where setting `skipOpenTelemetrySetup: true` also turned Sentry's HTTP and fetch spans off by default. Sentry now emits those whenever tracing is enabled, regardless of `skipOpenTelemetrySetup`. -If you do want Sentry spans alongside your own, keep `traceSampleRate` set and drop the integrations that overlap. HTTP and fetch are the exception: turn off only their spans, because `httpIntegration` also provides request isolation, request data and session tracking: +If you do want Sentry spans alongside your own, keep `tracesSampleRate` set and drop the integrations that overlap. HTTP and fetch are the exception: turn off only their spans, because `httpIntegration` also provides request isolation, request data and session tracking: ```js Sentry.init({ From af3c2d59c50786d272c4a23e1e49609eb55a9988 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Fri, 7 Aug 2026 15:32:34 +0200 Subject: [PATCH 13/16] Rename the v10 bridge section to Migrating custom OpenTelemetry setups --- MIGRATION.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 80a17b99df73..9150006990df 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -169,9 +169,9 @@ Sentry.init({ }); ``` -##### The v10 bridge is gone +##### Migrating custom OpenTelemetry setups -If you previously wired Sentry into your own OpenTelemetry setup with `SentryContextManager`, `SentrySampler` and `SentrySpanProcessor`, that path no longer exists. Those components were removed, so there is no longer a way to route spans from your own provider into Sentry as Sentry spans. Export them over OTLP instead, as shown in setup 3. +In v10, running your own OpenTelemetry setup meant registering Sentry's own components into it: `SentryContextManager`, `SentrySampler` and `SentrySpanProcessor`. Those were removed, so there is no longer a way to route spans from your own provider into Sentry as Sentry spans. Export them over OTLP instead, as shown in setup 3. #### Connecting Sentry to your OpenTelemetry traces From 22206442659a2dcd038fc56326c5286dd784efdf Mon Sep 17 00:00:00 2001 From: Andrei <168741329+andreiborza@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:38:03 +0200 Subject: [PATCH 14/16] Update MIGRATION.md Co-authored-by: Lukas Stracke --- MIGRATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index 9150006990df..543f250208bb 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -84,7 +84,7 @@ This means you can run your own OpenTelemetry setup cleanly alongside Sentry wit With this, we also heavily reduced our OpenTelemetry dependencies, with `@opentelemetry/api` being the only one remaining. These changes also mean `@sentry/node-core` no longer serves any purpose and was [merged back into `@sentry/node`](#sentrynode-core-was-merged-back-into-sentrynode). -For most users, day-to-day tracing is **unchanged**. +If you only use the Sentry SDK, day-to-day tracing remains **unchanged**. #### Choosing an OpenTelemetry setup From 3ffea0e9411349c39d6f9885dc5d9807ab940a35 Mon Sep 17 00:00:00 2001 From: Andrei Borza Date: Fri, 7 Aug 2026 15:40:11 +0200 Subject: [PATCH 15/16] Apply review feedback on the section intro and setup 2 Name both SDKs in the intro, and drop the claim that spans cannot be fanned out to another backend, since a custom transport can still do that. --- MIGRATION.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MIGRATION.md b/MIGRATION.md index 543f250208bb..2b4230310f0e 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -88,7 +88,7 @@ If you only use the Sentry SDK, day-to-day tracing remains **unchanged**. #### Choosing an OpenTelemetry setup -There are three ways to run the two together, and which one you want depends on who should own spans. This is controlled by the existing `skipOpenTelemetrySetup` option, whose default was flipped in v11: it is now `true` for most server SDKs (including `@sentry/node`, `@sentry/bun`, the serverless SDKs and `@sentry/cloudflare`) and `false` for `@sentry/nextjs` and `@sentry/sveltekit`. +There are three ways to run the Sentry and OpenTelemetry SDKs together, and which one you want depends on who should own spans. This is controlled by the existing `skipOpenTelemetrySetup` option, whose default was flipped in v11: it is now `true` for most server SDKs (including `@sentry/node`, `@sentry/bun`, the serverless SDKs and `@sentry/cloudflare`) and `false` for `@sentry/nextjs` and `@sentry/sveltekit`. ##### 1. Sentry only @@ -117,7 +117,7 @@ Sentry.init({ Sentry registers a minimal OpenTelemetry-compatible tracer provider, context manager and propagator. Just enough OpenTelemetry to pick up spans created through `@opentelemetry/api`, which become native Sentry spans. -Everything goes to Sentry and only to Sentry. This is not a general OpenTelemetry pipeline: there is no exporter, no OTLP output, and no way to fan spans out to another backend. Sentry also refuses to register its provider if you already registered one of your own, logging a warning instead. If you want a real OpenTelemetry pipeline, use setup 3. +Spans go to Sentry. This is not a general OpenTelemetry pipeline: there is no exporter and no OTLP output. Sentry also refuses to register its provider if you already registered one of your own, logging a warning instead. If you want a real OpenTelemetry pipeline, use setup 3. ##### 3. Your own OpenTelemetry, Sentry linked to it From 1a6b5b9af713aabacb7215a599e26ef483b57465 Mon Sep 17 00:00:00 2001 From: Andrei <168741329+andreiborza@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:53:21 +0200 Subject: [PATCH 16/16] Apply suggestion from @Lms24 Co-authored-by: Lukas Stracke --- MIGRATION.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MIGRATION.md b/MIGRATION.md index 2b4230310f0e..38cbb52f1ebf 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -92,7 +92,7 @@ There are three ways to run the Sentry and OpenTelemetry SDKs together, and whic ##### 1. Sentry only -The default, and what most users want. Tracing works out of the box: +The default, and what you most likely want. Tracing works out of the box: ```js Sentry.init({