From e7029b94ba36cc3bdad1c807bdbb47c82e53a397 Mon Sep 17 00:00:00 2001 From: Martin Sonnberger Date: Wed, 16 Sep 2026 13:29:26 +0200 Subject: [PATCH 01/10] docs(javascript): Update OpenTelemetry setup option for v11 Refs SDK-1471 --- .../configuration/integrations/http.mdx | 2 +- .../configuration/integrations/nodefetch.mdx | 2 +- .../javascript/common/install/esm.mdx | 26 ------------------- .../common/opentelemetry/custom-setup.mdx | 8 +++--- .../javascript/guides/nestjs/install/esm.mdx | 26 ------------------- .../error-monitoring-only/javascript.bun.mdx | 3 +-- .../error-monitoring-only/javascript.mdx | 6 ++--- .../opentelemetry-setup/javascript.bun.mdx | 6 ++--- .../opentelemetry-setup/javascript.mdx | 6 ++--- .../with-custom-sampler/javascript.bun.mdx | 2 +- .../with-custom-sampler/javascript.mdx | 16 +++--------- 11 files changed, 19 insertions(+), 84 deletions(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/http.mdx b/docs/platforms/javascript/common/configuration/integrations/http.mdx index c3666472ad12d..00eb0ae99c224 100644 --- a/docs/platforms/javascript/common/configuration/integrations/http.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/http.mdx @@ -93,7 +93,7 @@ The callback function receives two arguments: _Type: `boolean`_ (Defaults to `true`) -Whether to inject trace propagation headers (`sentry-trace`, `baggage`, `traceparent`) into outgoing HTTP requests. When set to `false`, Sentry will not inject any trace propagation headers but will still create breadcrumbs (if `breadcrumbs` is enabled). This is useful when `skipOpenTelemetrySetup: true` is configured and your external OpenTelemetry setup already handles trace propagation, to avoid duplicate headers. +Whether to inject trace propagation headers (`sentry-trace`, `baggage`, `traceparent`) into outgoing HTTP requests. When set to `false`, Sentry will not inject any trace propagation headers but will still create breadcrumbs (if `breadcrumbs` is enabled). This is useful when `enableOpenTelemetrySetup: false` is configured and your external OpenTelemetry setup already handles trace propagation, to avoid duplicate headers. ### `ignoreOutgoingRequests` diff --git a/docs/platforms/javascript/common/configuration/integrations/nodefetch.mdx b/docs/platforms/javascript/common/configuration/integrations/nodefetch.mdx index e18f6fea19c0b..1ecfe131d0ac5 100644 --- a/docs/platforms/javascript/common/configuration/integrations/nodefetch.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/nodefetch.mdx @@ -61,7 +61,7 @@ If set to false, no breadcrumbs will be captured. _Type: `boolean`_ (Defaults to `true`) -Whether to inject trace propagation headers (`sentry-trace`, `baggage`, `traceparent`) into outgoing fetch requests. When set to `false`, Sentry will not inject any trace propagation headers but will still create breadcrumbs (if `breadcrumbs` is enabled). This is useful when `skipOpenTelemetrySetup: true` is configured and your external OpenTelemetry setup already handles trace propagation, to avoid duplicate headers. +Whether to inject trace propagation headers (`sentry-trace`, `baggage`, `traceparent`) into outgoing fetch requests. When set to `false`, Sentry will not inject any trace propagation headers but will still create breadcrumbs (if `breadcrumbs` is enabled). This is useful when `enableOpenTelemetrySetup: false` is configured and your external OpenTelemetry setup already handles trace propagation, to avoid duplicate headers. ### `ignoreOutgoingRequests` diff --git a/docs/platforms/javascript/common/install/esm.mdx b/docs/platforms/javascript/common/install/esm.mdx index d222a843810b8..1e94c9aadb69c 100644 --- a/docs/platforms/javascript/common/install/esm.mdx +++ b/docs/platforms/javascript/common/install/esm.mdx @@ -52,29 +52,3 @@ on `--import` or `NODE_OPTIONS`, use the Adding Additional OpenTelemetry Instrumentation instead. @@ -121,7 +121,7 @@ You can add your own `@opentelemetry/instrumentation-http` instance in your Open ```javascript const sentryClient = Sentry.init({ dsn: "___DSN___", - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, integrations: [Sentry.httpIntegration({ spans: false, tracePropagation: false })], }); ``` @@ -131,7 +131,7 @@ You can add your own `@opentelemetry/instrumentation-http` instance in your Open ```javascript const sentryClient = Sentry.init({ dsn: "___DSN___", - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, integrations: (integrations) => // Also filter out the BunServer integration to avoid emitting duplicated spans from Sentry AND your custom OTel instrumentation integrations.filter((i) => i.name !== "BunServer") @@ -150,7 +150,7 @@ If your OpenTelemetry setup already handles trace propagation for fetch requests ```javascript const sentryClient = Sentry.init({ dsn: "___DSN___", - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, integrations: [ Sentry.nativeNodeFetchIntegration({ tracePropagation: false }), ], diff --git a/docs/platforms/javascript/guides/nestjs/install/esm.mdx b/docs/platforms/javascript/guides/nestjs/install/esm.mdx index 9ba9ba454e9a0..fb036cb73ad7a 100644 --- a/docs/platforms/javascript/guides/nestjs/install/esm.mdx +++ b/docs/platforms/javascript/guides/nestjs/install/esm.mdx @@ -42,29 +42,3 @@ NODE_OPTIONS="--import ./instrument.mjs" npm run start ``` We do not support ESM in Node versions before 18.19.0. - -## Troubleshooting ESM Instrumentation - -By default, all packages are automatically wrapped by -[import-in-the-middle](https://www.npmjs.com/package/import-in-the-middle) to -aid instrumenting them. - -If `import-in-the-middle` encounters problems wrapping a package, you may see -syntax errors at runtime or logged errors in your console: - -```logs -SyntaxError: The requested module '...' does not provide an export named '...' -(node:3368) Error: 'import-in-the-middle' failed to wrap 'file://../../path/to/file.js' -``` - -To confirm that these errors are caused by `import-in-the-middle`, -disable it by setting `registerEsmLoaderHooks` to false. Note, this will also -disable tracing instrumentation: - -```javascript {tabTitle:ESM} {filename: instrument.mjs} {4} -import * as Sentry from "@sentry/nestjs"; - -Sentry.init({ - registerEsmLoaderHooks: false, -}); -``` diff --git a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx index 6119cfb7459cf..c03e674fe1882 100644 --- a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx +++ b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx @@ -10,8 +10,7 @@ import { registerInstrumentations } from "@opentelemetry/instrumentation"; const sentryClient = Sentry.init({ dsn: "___DSN___", - // Skipping the OpenTelemetry setup automatically disables emitting spans in the httpIntegration with `spans: false` - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, // Important: We do not define a tracesSampleRate here at all! // This leads to tracing being disabled diff --git a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx index 5f03de4bd1cab..c2985e25fdfb0 100644 --- a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx +++ b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx @@ -9,8 +9,7 @@ import { registerInstrumentations } from "@opentelemetry/instrumentation"; const sentryClient = Sentry.init({ dsn: "___DSN___", - // Skipping the OpenTelemetry setup automatically disables emitting spans in the httpIntegration with `spans: false` - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, // Important: We do not define a tracesSampleRate here at all! // This leads to tracing being disabled @@ -53,8 +52,7 @@ const { registerInstrumentations } = require("@opentelemetry/instrumentation"); const sentryClient = Sentry.init({ dsn: "___DSN___", - // Skipping the OpenTelemetry setup automatically disables emitting spans in the httpIntegration with `spans: false` - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, // Important: We do not define a tracesSampleRate here at all! // This leads to tracing being disabled diff --git a/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx b/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx index 4927978b8dd07..4d1044bcb9bd8 100644 --- a/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx +++ b/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx @@ -1,4 +1,4 @@ -To use an existing OpenTelemetry setup, set `skipOpenTelemetrySetup: true` in your `init({})` config, then set up all the components that Sentry needs yourself. Finish by installing `@sentry/opentelemetry` and adding the following: +To use an existing OpenTelemetry setup, set `enableOpenTelemetrySetup: false` in your `init({})` config, then set up all the components that Sentry needs yourself. Finish by installing `@sentry/opentelemetry` and adding the following: ```javascript {tabTitle: NodeTracerProvider} import * as Sentry from "@sentry/bun"; @@ -9,7 +9,7 @@ import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; const sentryClient = Sentry.init({ dsn: "___DSN___", - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, // The SentrySampler will use this to determine which traces to sample tracesSampleRate: 1.0, @@ -52,7 +52,7 @@ import { NodeSDK } from "@opentelemetry/sdk-node"; const sentryClient = Sentry.init({ dsn: "___PUBLIC_DSN___", - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, // The SentrySampler will use this to determine which traces to sample tracesSampleRate: 1.0, diff --git a/platform-includes/performance/opentelemetry-setup/javascript.mdx b/platform-includes/performance/opentelemetry-setup/javascript.mdx index 8e89e864d6d5b..2b2d1343e9dc9 100644 --- a/platform-includes/performance/opentelemetry-setup/javascript.mdx +++ b/platform-includes/performance/opentelemetry-setup/javascript.mdx @@ -1,4 +1,4 @@ -To use an existing OpenTelemetry setup, set `skipOpenTelemetrySetup: true` in your `init({})` config, then set up all the components that Sentry needs yourself. Finish by installing `@sentry/opentelemetry` and adding the following: +To use an existing OpenTelemetry setup, set `enableOpenTelemetrySetup: false` in your `init({})` config, then set up all the components that Sentry needs yourself. Finish by installing `@sentry/opentelemetry` and adding the following: ```javascript {tabTitle: NodeTracerProvider} const Sentry = require("@sentry/node"); @@ -8,7 +8,7 @@ const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); const sentryClient = Sentry.init({ dsn: "___DSN___", - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, // The SentrySampler will use this to determine which traces to sample tracesSampleRate: 1.0, @@ -47,7 +47,7 @@ const { SentrySpanProcessor, SentryPropagator, SentrySampler } = require("@sentr const sentryClient = Sentry.init({ dsn: "___PUBLIC_DSN___", - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, // The SentrySampler will use this to determine which traces to sample tracesSampleRate: 1.0, diff --git a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx index 5604a57c79512..4415967cbd31d 100644 --- a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx +++ b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx @@ -24,7 +24,7 @@ class CustomSampler { const sentryClient = Sentry.init({ dsn: "___DSN___", - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, // By defining any sample rate, // tracing integrations will be added by default diff --git a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx index af76cec370154..0236197815566 100644 --- a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx +++ b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx @@ -23,7 +23,7 @@ class CustomSampler { const sentryClient = Sentry.init({ dsn: "___DSN___", - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, // By defining any sample rate, // tracing integrations will be added by default @@ -65,7 +65,7 @@ class CustomSampler { const sentryClient = Sentry.init({ dsn: "___DSN___", - skipOpenTelemetrySetup: true, + enableOpenTelemetrySetup: false, // By defining any sample rate, // tracing integrations will be added by default @@ -87,14 +87,4 @@ Sentry.validateOpenTelemetrySetup(); If your application is running in ESM (`import`/`export` syntax), OpenTelemetry requires you to set up _ESM loader hooks_. -The Sentry SDK will automatically register ESM loader hooks by default. -However, if you have your own OpenTelemetry setup, it is recommended to configure the Sentry SDK to not register these hooks and instead register them yourself. -You can do so by setting `registerEsmLoaderHooks` to `false` and [setting up ESM loader hooks](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm): - -```javascript -Sentry.init({ - dsn: "___DSN___", - skipOpenTelemetrySetup: true, - registerEsmLoaderHooks: false, -}); -``` +The Sentry SDK does not register ESM loader hooks. [Register the hooks yourself](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm) for your OpenTelemetry instrumentation. From ea5784273a3813a6df7fe5cf3b357adbbb228be5 Mon Sep 17 00:00:00 2001 From: Martin Sonnberger Date: Wed, 16 Sep 2026 13:46:06 +0200 Subject: [PATCH 02/10] docs(javascript): Document v11 OpenTelemetry integration Replace the legacy custom OpenTelemetry setup with OTLP export examples. Document openTelemetryIntegration and getOtlpTracesEndpoint. Fixes SDK-1490 --- .../common/opentelemetry/custom-setup.mdx | 146 ++++-------------- .../common/opentelemetry/integration.mdx | 93 +++++++++++ .../error-monitoring-only/javascript.bun.mdx | 49 +----- .../error-monitoring-only/javascript.mdx | 85 ++-------- .../opentelemetry-setup/javascript.bun.mdx | 89 ++++------- .../opentelemetry-setup/javascript.mdx | 89 ++++------- .../with-custom-sampler/javascript.bun.mdx | 46 ++---- .../with-custom-sampler/javascript.mdx | 95 ++---------- 8 files changed, 228 insertions(+), 464 deletions(-) create mode 100644 docs/platforms/javascript/common/opentelemetry/integration.mdx diff --git a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx index 43eb9e8cc5ddc..4b296b516379f 100644 --- a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx +++ b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx @@ -30,128 +30,71 @@ notSupported: sidebar_order: 0 --- - - -Use this guide when you already have a completely custom OpenTelemetry setup or when you intend to add a custom OpenTelemetry setup next to the Sentry SDK. - -The `enableOpenTelemetrySetup` option defaults to `false`, except in `@sentry/nextjs` and `@sentry/sveltekit`. Setting `enableOpenTelemetrySetup: false` disables the Sentry SDK's automatic OpenTelemetry configuration, **requiring** you to perform the setup manually. For example, to ensure errors are correctly associated with their scope, you must add the `SentryContextManager` to your OpenTelemetry setup. You can find details on the required manual setup further down on this page. +Use this guide when your application already has an OpenTelemetry pipeline and you want to send its spans to Sentry or associate Sentry errors with its traces. -If you are looking to simply add individual OpenTelemetry instrumentation to your Sentry setup, you should read Adding Additional OpenTelemetry Instrumentation instead. +In SDK v11, OpenTelemetry and Sentry use separate tracing pipelines. Your OpenTelemetry setup owns span creation, sampling, propagation, and export. Add `Sentry.openTelemetryIntegration()` to associate Sentry errors, logs, metrics, and crons with the active OpenTelemetry span. This integration does not export spans. - +Set `enableOpenTelemetrySetup: false` to keep your own OpenTelemetry provider. This is the default except in `@sentry/nextjs` and `@sentry/sveltekit`. Leave both `tracesSampleRate` and `tracesSampler` unset so Sentry does not create a second set of spans. - -If you don't need the full `@sentry/node` SDK and want a simpler way to bridge your existing OpenTelemetry setup with Sentry, consider using lightweight mode with the OTLP integration instead. It requires significantly less manual wiring. +Migrating from v10? Remove `SentryContextManager`, `SentryPropagator`, `SentrySampler`, `SentrySpanProcessor`, `wrapSamplingDecision`, and `validateOpenTelemetrySetup` from your setup. Use OpenTelemetry's context management, propagation, and sampling, and export spans over OTLP as shown below. - - - - -## Using Sentry for Error Monitoring Only - -If you have a custom OpenTelemetry setup and only want to use Sentry for error monitoring, you can skip adding the `SentrySpanProcessor`. You'll still need to add the `SentryContextManager`, `SentryPropagator`, and `SentrySampler` to your setup even if you don't want to send any tracing data to Sentry. Read on to learn why this is needed. - -In order for the Sentry SDK to work as expected, and for it to be in sync with OpenTelemetry, we need a few components to be in place. -**Components needed for Sentry to work correctly:** +## Sending OpenTelemetry Spans to Sentry -- **SentryContextManager**: Ensures that the OpenTelemetry context is in sync with Sentry, for example to correctly isolate data between simultaneous requests. -- **SentrySampler**: Ensures that the Sentry `tracesSampleRate` is respected. Even if you don't use Sentry for tracing, you'll still need this in order for trace propagation to work as expected. Read [Using a Custom Sampler](./#using-a-custom-sampler) if you want to use a custom sampler. -- **SentryPropagator**: Ensures that trace propagation works correctly. -- [Required Instrumentation](./#required-instrumentation): Ensures that trace propagation works correctly. +Initialize your OpenTelemetry provider before calling `Sentry.init()`. Add the exporter to your existing provider rather than registering a second provider. -**Additional components needed to also use Sentry for tracing:** - -- **SentrySpanProcessor**: Ensures that spans are correctly sent to Sentry. + - - Trace propagation is needed for Sentry to automatically connect services - together. (For example, if you want to connect the frontend and backend, or - different backend services.) This makes it possible to see related errors - across services.{" "} - - Learn more about Trace Propagation. - - +## Using Sentry for Error Monitoring Only -The following code snippet shows how to set up Sentry for error monitoring only: +Keep your existing OpenTelemetry setup and exporter. Add `Sentry.openTelemetryIntegration()` to link Sentry errors to the active OpenTelemetry trace without exporting spans to Sentry. You do not need Sentry-specific span processors, samplers, or context managers. ## Required Instrumentation -By default, Sentry will register OpenTelemetry instrumentation to automatically capture spans for traces spanning incoming and outgoing HTTP requests, DB queries, and more. - -If tracing is not enabled (no `tracesSampleRate` is defined in the SDK configuration), only a minimal amount of OpenTelemetry instrumentation will be registered. This includes the following: - -{/* prettier-ignore-start */} - -- A Sentry-specific HTTP instrumentation that handles request isolation and trace propagation. This can work in parallel with [@opentelemetry/instrumentation-http](https://www.npmjs.com/package/@opentelemetry/instrumentation-http), if you register it. -- [nativeNodeFetchIntegration](/platforms/javascript/guides/node/configuration/integrations/nodefetch/) registers [opentelemetry-instrumentation-fetch-node](https://www.npmjs.com/package/opentelemetry-instrumentation-fetch-node) which is needed for trace propagation. - -{/* prettier-ignore-end */} - - - - If tracing is not enabled, performance instrumentations will not be - registered but they will still be included in the bundle. If you want to - reduce the bundle size or used dependencies, you can also{" "} - - Set up Sentry without Performance Integrations - - - +Register the OpenTelemetry instrumentation you need to create spans for incoming requests, outgoing requests, database queries, and other operations. Sentry's instrumentation does not create OpenTelemetry spans in v11. -These are needed to make sure that trace propagation works correctly. - -If you want to add your own http/node-fetch instrumentation, you have to follow the following steps: +With Sentry tracing disabled, Sentry's instrumentation still isolates requests and captures errors and breadcrumbs. Keep it enabled alongside your OpenTelemetry instrumentation. ### Custom HTTP Instrumentation - - -You can add your own `@opentelemetry/instrumentation-http` instance in your OpenTelemetry setup. However, in this case, you need to disable span creation in Sentry's `httpIntegration`. You can also set `tracePropagation: false` to prevent Sentry from injecting trace headers, letting your OpenTelemetry setup handle propagation instead: +If your OpenTelemetry setup handles HTTP trace propagation, disable Sentry's outgoing HTTP trace headers to avoid duplicate headers. Keep `httpIntegration` enabled for request isolation and breadcrumbs: - ```javascript - const sentryClient = Sentry.init({ - dsn: "___DSN___", - enableOpenTelemetrySetup: false, - integrations: [Sentry.httpIntegration({ spans: false, tracePropagation: false })], -}); - ``` - - ```javascript - const sentryClient = Sentry.init({ - dsn: "___DSN___", +Sentry.init({ + dsn: "___PUBLIC_DSN___", enableOpenTelemetrySetup: false, - integrations: (integrations) => - // Also filter out the BunServer integration to avoid emitting duplicated spans from Sentry AND your custom OTel instrumentation - integrations.filter((i) => i.name !== "BunServer") + integrations: [ + Sentry.openTelemetryIntegration(), + Sentry.httpIntegration({ tracePropagation: false }), + ], }); ``` + -It's important that `httpIntegration` is still registered this way to ensure that the Sentry SDK can correctly isolate requests, for example when capturing errors. + -### Custom Node Fetch Instrumentation +Leave `tracesSampleRate` and `tracesSampler` unset to disable Sentry spans. You do not need to remove the `BunServer` integration to avoid duplicate spans. -If tracing is disabled, the Node Fetch instrumentation will not emit any spans. In this scenario, it will only inject sentry-specific trace propagation headers. You are free to add your own Node Fetch instrumentation on top of this which may emit spans as you like. + + +### Custom Node Fetch Instrumentation -If your OpenTelemetry setup already handles trace propagation for fetch requests, you can set `tracePropagation: false` to prevent Sentry from injecting duplicate trace headers: +If your OpenTelemetry setup handles fetch trace propagation, disable Sentry's outgoing fetch trace headers: ```javascript -const sentryClient = Sentry.init({ - dsn: "___DSN___", +Sentry.init({ + dsn: "___PUBLIC_DSN___", enableOpenTelemetrySetup: false, integrations: [ + Sentry.openTelemetryIntegration(), Sentry.nativeNodeFetchIntegration({ tracePropagation: false }), ], }); @@ -159,35 +102,12 @@ const sentryClient = Sentry.init({ ## Using a Custom Sampler -While you can use your own sampler, we recommend that you use the `SentrySampler`. This will ensure that the correct subset of traces will be sent to Sentry, based on your `tracesSampleRate`. It will also ensure that all other Sentry features like trace propagation work as expected. If you do need to use your own sampler, make sure to wrap your `SamplingResult` with our `wrapSamplingDecision` method like in the example below: - - - - +Configure sampling on your OpenTelemetry provider. Sentry's `tracesSampleRate` and `tracesSampler` do not control spans exported over OTLP. -It is recommended registering your own ESM loader hooks when you have a complete custom OpenTelemetry setup, first and foremost because it makes the most sense architecturally. -You likely went through the effort to set up OpenTelemetry by itself and now you want to add Sentry to your application without messing with your OpenTelemetry setup. +You can use an OpenTelemetry sampler or your own implementation of its `Sampler` interface. Return an OpenTelemetry `SamplingResult` directly, without `wrapSamplingDecision`. For example, this sampler respects the parent's decision and samples 10% of new traces: -Additionally, there are a few pitfalls that can very simply be avoided by registering your own hooks: + -- Registering loader hooks multiple times might result in duplicated spans being created. [More details.](https://github.com/getsentry/sentry-javascript/issues/14065#issuecomment-2435546961) -- OpenTelemetry instrumentation in ESM is very sensitive as to _when_ it is added relative to _when_ the loader hooks are registered. - The control over this should stay with the owner of the OpenTelemetry setup and not the Sentry SDK. +## ESM Loaders - - - - - - Learn more about ESM installation methods. - - - +The Sentry SDK does not register ESM loader hooks. If your OpenTelemetry instrumentation needs them, [register OpenTelemetry's ESM loader hooks](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm) before loading the modules you want to instrument. diff --git a/docs/platforms/javascript/common/opentelemetry/integration.mdx b/docs/platforms/javascript/common/opentelemetry/integration.mdx new file mode 100644 index 0000000000000..70c54eb834114 --- /dev/null +++ b/docs/platforms/javascript/common/opentelemetry/integration.mdx @@ -0,0 +1,93 @@ +--- +title: OpenTelemetry Integration +description: "Connect Sentry errors, logs, metrics, and crons to your OpenTelemetry traces with openTelemetryIntegration, and configure OTLP export with getOtlpTracesEndpoint." +supported: + - javascript.nextjs + - javascript.node + - javascript.aws-lambda + - javascript.azure-functions + - javascript.bun + - javascript.connect + - javascript.express + - javascript.fastify + - javascript.gcp-functions + - javascript.hapi + - javascript.hono + - javascript.koa + - javascript.nestjs + - javascript.nitro + - javascript.nuxt + - javascript.solidstart + - javascript.sveltekit + - javascript.astro + - javascript.remix + - javascript.react-router + - javascript.tanstackstart-react +notSupported: + - javascript +sidebar_order: 1 +--- + + + +_Import name: `Sentry.openTelemetryIntegration`_ + +Use this integration when your application runs its own OpenTelemetry pipeline. It attaches the active OpenTelemetry span's trace ID and span ID to Sentry errors, logs, metrics, and cron check-ins. The integration reports its name as `OpenTelemetry` and takes no options. + +The integration does not create or export spans. Your OpenTelemetry SDK remains responsible for sampling, propagation, and export. To send those spans to Sentry, configure an OTLP exporter using [`getOtlpTracesEndpoint`](#getotlptracesendpoint). + +## Setup + +This integration runs on the server and is not enabled by default. Import your OpenTelemetry configuration before initializing Sentry: + +```javascript {filename: instrument.mjs} +import "./otel.config.mjs"; +import * as Sentry from "___SDK_PACKAGE___"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + enableOpenTelemetrySetup: false, + // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. + integrations: [Sentry.openTelemetryIntegration()], +}); +``` + +Here, `otel.config.mjs` registers your existing OpenTelemetry provider, context manager, propagator, and instrumentation. In frameworks with their own instrumentation entry point, initialize OpenTelemetry there before calling `Sentry.init()`. + +Keep `enableOpenTelemetrySetup` set to `false`. This is already the default except in `@sentry/nextjs` and `@sentry/sveltekit`. Leave `tracesSampleRate` and `tracesSampler` unset to keep Sentry tracing off. An active Sentry span takes precedence over the OpenTelemetry span. + +If there is no active OpenTelemetry span, or its span context is invalid, Sentry uses its own trace context. + +For exporter examples, sampling, and HTTP propagation settings, see Using Your Existing OpenTelemetry Setup. + +## `getOtlpTracesEndpoint` + +`Sentry.getOtlpTracesEndpoint(dsn)` converts a Sentry DSN into configuration for an OpenTelemetry HTTP trace exporter. It takes a DSN string and returns an object with these fields: + +| Field | Type | Description | +| --------- | ------------------------ | ------------------------------------------------------------------- | +| `url` | `string` | The project's Sentry OTLP traces endpoint. | +| `headers` | `Record` | Authentication headers for the endpoint, including `X-Sentry-Auth`. | + +If the DSN cannot be parsed, the helper returns `undefined`. The helper does not register a provider or send spans. + +Pass the result to `OTLPTraceExporter` from `@opentelemetry/exporter-trace-otlp-http`: + +```javascript +import * as Sentry from "___SDK_PACKAGE___"; +import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; + +const endpoint = Sentry.getOtlpTracesEndpoint("___PUBLIC_DSN___"); + +if (!endpoint) { + throw new Error("Invalid Sentry DSN"); +} + +const exporter = new OTLPTraceExporter(endpoint); +``` + +Add this exporter to your existing provider with a `BatchSpanProcessor`, as shown in the OTLP setup examples. If you only want to associate Sentry errors with traces exported elsewhere, keep your existing exporter and omit this helper. + +## Migrating from `otlpIntegration` + +In v11, `openTelemetryIntegration()` replaces `otlpIntegration()` from `@sentry/node-core/light/otlp`. Import it from your platform's Sentry SDK. The `setupOtlpTracesExporter` and `collectorUrl` options were removed. Configure the exporter in your OpenTelemetry setup instead. diff --git a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx index c03e674fe1882..4d83448ef1c65 100644 --- a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx +++ b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx @@ -1,48 +1,11 @@ -```javascript +```javascript {tabTitle: ESM} import * as Sentry from "@sentry/bun"; -import { SentryContextManager } from "@sentry/node-core"; -import { SentryPropagator, SentrySampler } from "@sentry/opentelemetry"; -import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; -import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; -import { OTLPTraceExporter } from "@opentelemetry/exporter-otlp-http"; -import { registerInstrumentations } from "@opentelemetry/instrumentation"; - -const sentryClient = Sentry.init({ - dsn: "___DSN___", +// Initialize your existing OpenTelemetry setup before calling Sentry.init(). +Sentry.init({ + dsn: "___PUBLIC_DSN___", enableOpenTelemetrySetup: false, - - // Important: We do not define a tracesSampleRate here at all! - // This leads to tracing being disabled - - integrations: (integrations) => - // Filter out the BunServer integration to avoid emitting spans from there - integrations.filter((i) => i.name !== "BunServer") -}); - -// Create and configure e.g. NodeTracerProvider -const provider = new NodeTracerProvider({ - // This ensures trace propagation works as expected - sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, -}); - -provider.addSpanProcessor( - new BatchSpanProcessor( - new OTLPTraceExporter({ - url: "http://OTLP-ENDPOINT.com/api", - }) - ) -); - -// Initialize the provider -provider.register({ - propagator: new SentryPropagator(), - contextManager: new SentryContextManager(), -}); - -registerInstrumentations({ - instrumentations: [ - // Add OTEL instrumentation here - ], + // Leave tracesSampleRate and tracesSampler unset. + integrations: [Sentry.openTelemetryIntegration()], }); ``` diff --git a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx index c2985e25fdfb0..a248c87f9c9a1 100644 --- a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx +++ b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx @@ -1,86 +1,23 @@ ```javascript {tabTitle: ESM} import * as Sentry from "@sentry/node"; -import { SentryPropagator, SentrySampler } from "@sentry/opentelemetry"; -import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; -import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; -import { OTLPTraceExporter } from "@opentelemetry/exporter-otlp-http"; -import { registerInstrumentations } from "@opentelemetry/instrumentation"; - -const sentryClient = Sentry.init({ - dsn: "___DSN___", +// Initialize your existing OpenTelemetry setup before calling Sentry.init(). +Sentry.init({ + dsn: "___PUBLIC_DSN___", enableOpenTelemetrySetup: false, - - // Important: We do not define a tracesSampleRate here at all! - // This leads to tracing being disabled -}); - -// Create and configure e.g. NodeTracerProvider -const provider = new NodeTracerProvider({ - // This ensures trace propagation works as expected - sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, -}); - -provider.addSpanProcessor( - new BatchSpanProcessor( - new OTLPTraceExporter({ - url: "http://OTLP-ENDPOINT.com/api", - }) - ) -); - -// Initialize the provider -provider.register({ - propagator: new SentryPropagator(), - contextManager: new Sentry.SentryContextManager(), -}); - -registerInstrumentations({ - instrumentations: [ - // Add OTEL instrumentation here - ], + // Leave tracesSampleRate and tracesSampler unset. + integrations: [Sentry.openTelemetryIntegration()], }); ``` + ```javascript {tabTitle: CJS} const Sentry = require("@sentry/node"); -const { SentryPropagator, SentrySampler } = require("@sentry/opentelemetry"); -const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); -const { BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base"); -const { OTLPTraceExporter } = require("@opentelemetry/exporter-otlp-http"); -const { registerInstrumentations } = require("@opentelemetry/instrumentation"); - -const sentryClient = Sentry.init({ - dsn: "___DSN___", +// Initialize your existing OpenTelemetry setup before calling Sentry.init(). +Sentry.init({ + dsn: "___PUBLIC_DSN___", enableOpenTelemetrySetup: false, - - // Important: We do not define a tracesSampleRate here at all! - // This leads to tracing being disabled -}); - -// Create and configure e.g. NodeTracerProvider -const provider = new NodeTracerProvider({ - // This ensures trace propagation works as expected - sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, -}); - -provider.addSpanProcessor( - new BatchSpanProcessor( - new OTLPTraceExporter({ - url: "http://OTLP-ENDPOINT.com/api", - }) - ) -); - -// Initialize the provider -provider.register({ - propagator: new SentryPropagator(), - contextManager: new Sentry.SentryContextManager(), -}); - -registerInstrumentations({ - instrumentations: [ - // Add OTEL instrumentation here - ], + // Leave tracesSampleRate and tracesSampler unset. + integrations: [Sentry.openTelemetryIntegration()], }); ``` diff --git a/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx b/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx index 4d1044bcb9bd8..7551d9900d9f7 100644 --- a/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx +++ b/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx @@ -1,86 +1,57 @@ -To use an existing OpenTelemetry setup, set `enableOpenTelemetrySetup: false` in your `init({})` config, then set up all the components that Sentry needs yourself. Finish by installing `@sentry/opentelemetry` and adding the following: +Add an OTLP trace exporter to your existing OpenTelemetry provider to send spans to Sentry. `Sentry.getOtlpTracesEndpoint()` returns the endpoint URL and authentication headers for your DSN. Keep your existing sampler, context manager, propagator, and instrumentation. + +The examples below show the Sentry-specific additions using `NodeTracerProvider` or `NodeSDK`. Install `@opentelemetry/exporter-trace-otlp-http` if you do not already use it. ```javascript {tabTitle: NodeTracerProvider} import * as Sentry from "@sentry/bun"; -import { SentryContextManager, validateOpenTelemetrySetup } from "@sentry/node-core"; -import { SentrySpanProcessor, SentryPropagator, SentrySampler } from "@sentry/opentelemetry"; - +import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; +import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; -const sentryClient = Sentry.init({ - dsn: "___DSN___", - enableOpenTelemetrySetup: false, - - // The SentrySampler will use this to determine which traces to sample - tracesSampleRate: 1.0, - // Filter out the BunServer integration in case you want to avoid sending spans from there: - // integrations: (integrations) => - // integrations.filter((i) => i.name !== "BunServer") -}); +const dsn = "___PUBLIC_DSN___"; -// Note: This could be BasicTracerProvider or any other provider depending on -// how you are using the OpenTelemetry SDK const provider = new NodeTracerProvider({ - // Ensure the correct subset of traces is sent to Sentry - // This also ensures trace propagation works as expected - sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, spanProcessors: [ - // Ensure spans are correctly linked & sent to Sentry - new SentrySpanProcessor(), - // Add additional processors here + new BatchSpanProcessor( + new OTLPTraceExporter(Sentry.getOtlpTracesEndpoint(dsn)) + ), + // Keep any other span processors you already use. ], }); -provider.register({ - // Ensure trace propagation works - // This relies on the SentrySampler for correct propagation - propagator: new SentryPropagator(), - // Ensure context & request isolation are correctly managed - contextManager: new SentryContextManager(), -}); +provider.register(); -// Validate that the setup is correct -validateOpenTelemetrySetup(); +Sentry.init({ + dsn, + enableOpenTelemetrySetup: false, + // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. + integrations: [Sentry.openTelemetryIntegration()], +}); ``` ```javascript {tabTitle: NodeSDK} import * as Sentry from "@sentry/bun"; -import { SentryContextManager, validateOpenTelemetrySetup } from "@sentry/node-core"; -import { SentryPropagator, SentrySampler } from "@sentry/opentelemetry"; - +import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; +import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; import { NodeSDK } from "@opentelemetry/sdk-node"; -const sentryClient = Sentry.init({ - dsn: "___PUBLIC_DSN___", - enableOpenTelemetrySetup: false, - - // The SentrySampler will use this to determine which traces to sample - tracesSampleRate: 1.0, - // Filter out the BunServer integration in case you want to avoid sending spans from there: - // integrations: (integrations) => - // integrations.filter((i) => i.name !== "BunServer") -}); +const dsn = "___PUBLIC_DSN___"; const sdk = new NodeSDK({ - // Ensure the correct subset of traces is sent to Sentry - // This also ensures trace propagation works as expected - sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, spanProcessors: [ - // Ensure spans are correctly linked & sent to Sentry - new SentrySpanProcessor(), - // Add additional processors here + new BatchSpanProcessor( + new OTLPTraceExporter(Sentry.getOtlpTracesEndpoint(dsn)) + ), + // Keep any other span processors you already use. ], - // Ensure trace propagation works - // This relies on the SentrySampler for correct propagation - textMapPropagator: new SentryPropagator(), - // Ensure context & request isolation are correctly managed - contextManager: new SentryContextManager() }); sdk.start(); -// Validate that the setup is correct -validateOpenTelemetrySetup(); +Sentry.init({ + dsn, + enableOpenTelemetrySetup: false, + // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. + integrations: [Sentry.openTelemetryIntegration()], +}); ``` - -Make sure that all [Required OpenTelemetry Instrumentation](./#required-instrumentation) is set up correctly. Otherwise, the Sentry SDK may not work as expected. diff --git a/platform-includes/performance/opentelemetry-setup/javascript.mdx b/platform-includes/performance/opentelemetry-setup/javascript.mdx index 2b2d1343e9dc9..cdde079095b56 100644 --- a/platform-includes/performance/opentelemetry-setup/javascript.mdx +++ b/platform-includes/performance/opentelemetry-setup/javascript.mdx @@ -1,78 +1,57 @@ -To use an existing OpenTelemetry setup, set `enableOpenTelemetrySetup: false` in your `init({})` config, then set up all the components that Sentry needs yourself. Finish by installing `@sentry/opentelemetry` and adding the following: +Add an OTLP trace exporter to your existing OpenTelemetry provider to send spans to Sentry. `Sentry.getOtlpTracesEndpoint()` returns the endpoint URL and authentication headers for your DSN. Keep your existing sampler, context manager, propagator, and instrumentation. -```javascript {tabTitle: NodeTracerProvider} -const Sentry = require("@sentry/node"); -const { SentrySpanProcessor, SentryPropagator, SentrySampler } = require("@sentry/opentelemetry"); - -const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); +The examples below show the Sentry-specific additions using `NodeTracerProvider` or `NodeSDK`. Install `@opentelemetry/exporter-trace-otlp-http` if you do not already use it. -const sentryClient = Sentry.init({ - dsn: "___DSN___", - enableOpenTelemetrySetup: false, +```javascript {tabTitle: NodeTracerProvider} +import * as Sentry from "@sentry/node"; +import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; +import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; +import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; - // The SentrySampler will use this to determine which traces to sample - tracesSampleRate: 1.0, -}); +const dsn = "___PUBLIC_DSN___"; -// Note: This could be BasicTracerProvider or any other provider depending on -// how you are using the OpenTelemetry SDK const provider = new NodeTracerProvider({ - // Ensure the correct subset of traces is sent to Sentry - // This also ensures trace propagation works as expected - sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, spanProcessors: [ - // Ensure spans are correctly linked & sent to Sentry - new SentrySpanProcessor(), - // Add additional processors here + new BatchSpanProcessor( + new OTLPTraceExporter(Sentry.getOtlpTracesEndpoint(dsn)) + ), + // Keep any other span processors you already use. ], }); -provider.register({ - // Ensure trace propagation works - // This relies on the SentrySampler for correct propagation - propagator: new SentryPropagator(), - // Ensure context & request isolation are correctly managed - contextManager: new Sentry.SentryContextManager(), -}); +provider.register(); -// Validate that the setup is correct -Sentry.validateOpenTelemetrySetup(); +Sentry.init({ + dsn, + enableOpenTelemetrySetup: false, + // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. + integrations: [Sentry.openTelemetryIntegration()], +}); ``` ```javascript {tabTitle: NodeSDK} -const Sentry = require("@sentry/node"); +import * as Sentry from "@sentry/node"; +import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; +import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; +import { NodeSDK } from "@opentelemetry/sdk-node"; -const { NodeSDK } = require("@opentelemetry/sdk-node") -const { SentrySpanProcessor, SentryPropagator, SentrySampler } = require("@sentry/opentelemetry"); - -const sentryClient = Sentry.init({ - dsn: "___PUBLIC_DSN___", - enableOpenTelemetrySetup: false, - - // The SentrySampler will use this to determine which traces to sample - tracesSampleRate: 1.0, -}); +const dsn = "___PUBLIC_DSN___"; const sdk = new NodeSDK({ - // Ensure the correct subset of traces is sent to Sentry - // This also ensures trace propagation works as expected - sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, spanProcessors: [ - // Ensure spans are correctly linked & sent to Sentry - new SentrySpanProcessor(), - // Add additional processors here + new BatchSpanProcessor( + new OTLPTraceExporter(Sentry.getOtlpTracesEndpoint(dsn)) + ), + // Keep any other span processors you already use. ], - // Ensure trace propagation works - // This relies on the SentrySampler for correct propagation - textMapPropagator: new SentryPropagator(), - // Ensure context & request isolation are correctly managed - contextManager: new Sentry.SentryContextManager() }); sdk.start(); -// Validate that the setup is correct -Sentry.validateOpenTelemetrySetup(); +Sentry.init({ + dsn, + enableOpenTelemetrySetup: false, + // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. + integrations: [Sentry.openTelemetryIntegration()], +}); ``` - -Make sure that all [Required OpenTelemetry Instrumentation](./#required-instrumentation) is set up correctly. Otherwise, the Sentry SDK may not work as expected. diff --git a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx index 4415967cbd31d..6a3a32727d268 100644 --- a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx +++ b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx @@ -1,43 +1,17 @@ ```javascript -import * as Sentry from "@sentry/bun"; -import { validateOpenTelemetrySetup } from "@sentry/node-core"; -import { wrapSamplingDecision } from "@sentry/opentelemetry"; +import { + ParentBasedSampler, + TraceIdRatioBasedSampler, +} from "@opentelemetry/sdk-trace-base"; import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; -// implements Sampler from "@opentelemetry/sdk-trace-node" -class CustomSampler { - shouldSample(context, _traceId, _spanName, _spanKind, attributes, _links) { - const decision = yourDecisionLogic(); - - // wrap the result - return wrapSamplingDecision({ - decision, - context, - spanAttributes: attributes, - }); - } - - toString() { - return CustomSampler.name; - } -} - -const sentryClient = Sentry.init({ - dsn: "___DSN___", - enableOpenTelemetrySetup: false, - - // By defining any sample rate, - // tracing integrations will be added by default - // omit this if you do not want any performance integrations to be added - tracesSampleRate: 0, -}); - const provider = new NodeTracerProvider({ - sampler: new CustomSampler(), + // Respect the parent's sampling decision, or sample 10% of new traces. + sampler: new ParentBasedSampler({ + root: new TraceIdRatioBasedSampler(0.1), + }), + // Keep your existing span processors, including the OTLP exporter to Sentry. }); -// ...rest of your setup - -// Validate that the setup is correct -validateOpenTelemetrySetup(); +provider.register(); ``` diff --git a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx index 0236197815566..6a3a32727d268 100644 --- a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx +++ b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx @@ -1,90 +1,17 @@ -```javascript {tabTitle: ESM} -import * as Sentry from "@sentry/node"; -import { wrapSamplingDecision } from "@sentry/opentelemetry"; +```javascript +import { + ParentBasedSampler, + TraceIdRatioBasedSampler, +} from "@opentelemetry/sdk-trace-base"; import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; -// implements Sampler from "@opentelemetry/sdk-trace-node" -class CustomSampler { - shouldSample(context, _traceId, _spanName, _spanKind, attributes, _links) { - const decision = yourDecisionLogic(); - - // wrap the result - return wrapSamplingDecision({ - decision, - context, - spanAttributes: attributes, - }); - } - - toString() { - return CustomSampler.name; - } -} - -const sentryClient = Sentry.init({ - dsn: "___DSN___", - enableOpenTelemetrySetup: false, - - // By defining any sample rate, - // tracing integrations will be added by default - // omit this if you do not want any performance integrations to be added - tracesSampleRate: 0, -}); - -const provider = new NodeTracerProvider({ - sampler: new CustomSampler(), -}); - -// ...rest of your setup - -// Validate that the setup is correct -Sentry.validateOpenTelemetrySetup(); -``` -```javascript {tabTitle: CJS} -const Sentry = require("@sentry/node"); -const { wrapSamplingDecision } = require("@sentry/opentelemetry"); -const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); - -// implements Sampler from "@opentelemetry/sdk-trace-node" -class CustomSampler { - shouldSample(context, _traceId, _spanName, _spanKind, attributes, _links) { - const decision = yourDecisionLogic(); - - // wrap the result - return wrapSamplingDecision({ - decision, - context, - spanAttributes: attributes, - }); - } - - toString() { - return CustomSampler.name; - } -} - -const sentryClient = Sentry.init({ - dsn: "___DSN___", - enableOpenTelemetrySetup: false, - - // By defining any sample rate, - // tracing integrations will be added by default - // omit this if you do not want any performance integrations to be added - tracesSampleRate: 0, -}); - const provider = new NodeTracerProvider({ - sampler: new CustomSampler(), + // Respect the parent's sampling decision, or sample 10% of new traces. + sampler: new ParentBasedSampler({ + root: new TraceIdRatioBasedSampler(0.1), + }), + // Keep your existing span processors, including the OTLP exporter to Sentry. }); -// ...rest of your setup - -// Validate that the setup is correct -Sentry.validateOpenTelemetrySetup(); +provider.register(); ``` - -## ESM Loaders - -If your application is running in ESM (`import`/`export` syntax), OpenTelemetry requires you to set up _ESM loader hooks_. - -The Sentry SDK does not register ESM loader hooks. [Register the hooks yourself](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm) for your OpenTelemetry instrumentation. From 3cf09b61c913c80fffe9a2a3c71fbff82bf78b9b Mon Sep 17 00:00:00 2001 From: Martin Sonnberger Date: Thu, 17 Sep 2026 14:18:23 +0200 Subject: [PATCH 03/10] docs(javascript): Consolidate OpenTelemetry interoperability guide Fold setup and API reference content into the OpenTelemetry landing page. Redirect old subpages and Markdown exports to the consolidated guide. Fixes SDK-1470 --- .../common/opentelemetry/custom-setup.mdx | 113 ---------- .../javascript/common/opentelemetry/index.mdx | 197 +++++++++++++++++- .../common/opentelemetry/integration.mdx | 93 --------- .../using-opentelemetry-apis.mdx | 153 -------------- .../error-monitoring-only/javascript.bun.mdx | 11 - .../error-monitoring-only/javascript.mdx | 23 -- .../opentelemetry-setup/javascript.bun.mdx | 57 ----- .../opentelemetry-setup/javascript.mdx | 57 ----- .../with-custom-sampler/javascript.bun.mdx | 17 -- .../with-custom-sampler/javascript.mdx | 17 -- redirects.js | 28 +++ 11 files changed, 218 insertions(+), 548 deletions(-) delete mode 100644 docs/platforms/javascript/common/opentelemetry/custom-setup.mdx delete mode 100644 docs/platforms/javascript/common/opentelemetry/integration.mdx delete mode 100644 docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx delete mode 100644 platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx delete mode 100644 platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx delete mode 100644 platform-includes/performance/opentelemetry-setup/javascript.bun.mdx delete mode 100644 platform-includes/performance/opentelemetry-setup/javascript.mdx delete mode 100644 platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx delete mode 100644 platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx diff --git a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx deleted file mode 100644 index 4b296b516379f..0000000000000 --- a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Using Your Existing OpenTelemetry Setup -description: "Learn how to use your existing custom OpenTelemetry setup with Sentry." -supported: - - javascript.nextjs - - javascript.node - - javascript.eve - - javascript.mastra - - javascript.aws-lambda - - javascript.azure-functions - - javascript.bun - - javascript.connect - - javascript.express - - javascript.fastify - - javascript.gcp-functions - - javascript.hapi - - javascript.hono - - javascript.koa - - javascript.nestjs - - javascript.nitro - - javascript.nuxt - - javascript.solidstart - - javascript.sveltekit - - javascript.astro - - javascript.remix - - javascript.react-router - - javascript.tanstackstart-react -notSupported: - - javascript -sidebar_order: 0 ---- - -Use this guide when your application already has an OpenTelemetry pipeline and you want to send its spans to Sentry or associate Sentry errors with its traces. - -In SDK v11, OpenTelemetry and Sentry use separate tracing pipelines. Your OpenTelemetry setup owns span creation, sampling, propagation, and export. Add `Sentry.openTelemetryIntegration()` to associate Sentry errors, logs, metrics, and crons with the active OpenTelemetry span. This integration does not export spans. - -Set `enableOpenTelemetrySetup: false` to keep your own OpenTelemetry provider. This is the default except in `@sentry/nextjs` and `@sentry/sveltekit`. Leave both `tracesSampleRate` and `tracesSampler` unset so Sentry does not create a second set of spans. - - - -Migrating from v10? Remove `SentryContextManager`, `SentryPropagator`, `SentrySampler`, `SentrySpanProcessor`, `wrapSamplingDecision`, and `validateOpenTelemetrySetup` from your setup. Use OpenTelemetry's context management, propagation, and sampling, and export spans over OTLP as shown below. - - - -## Sending OpenTelemetry Spans to Sentry - -Initialize your OpenTelemetry provider before calling `Sentry.init()`. Add the exporter to your existing provider rather than registering a second provider. - - - -## Using Sentry for Error Monitoring Only - -Keep your existing OpenTelemetry setup and exporter. Add `Sentry.openTelemetryIntegration()` to link Sentry errors to the active OpenTelemetry trace without exporting spans to Sentry. You do not need Sentry-specific span processors, samplers, or context managers. - - - -## Required Instrumentation - -Register the OpenTelemetry instrumentation you need to create spans for incoming requests, outgoing requests, database queries, and other operations. Sentry's instrumentation does not create OpenTelemetry spans in v11. - -With Sentry tracing disabled, Sentry's instrumentation still isolates requests and captures errors and breadcrumbs. Keep it enabled alongside your OpenTelemetry instrumentation. - -### Custom HTTP Instrumentation - -If your OpenTelemetry setup handles HTTP trace propagation, disable Sentry's outgoing HTTP trace headers to avoid duplicate headers. Keep `httpIntegration` enabled for request isolation and breadcrumbs: - - - -```javascript -Sentry.init({ - dsn: "___PUBLIC_DSN___", - enableOpenTelemetrySetup: false, - integrations: [ - Sentry.openTelemetryIntegration(), - Sentry.httpIntegration({ tracePropagation: false }), - ], -}); -``` - - - - - -Leave `tracesSampleRate` and `tracesSampler` unset to disable Sentry spans. You do not need to remove the `BunServer` integration to avoid duplicate spans. - - - -### Custom Node Fetch Instrumentation - -If your OpenTelemetry setup handles fetch trace propagation, disable Sentry's outgoing fetch trace headers: - -```javascript -Sentry.init({ - dsn: "___PUBLIC_DSN___", - enableOpenTelemetrySetup: false, - integrations: [ - Sentry.openTelemetryIntegration(), - Sentry.nativeNodeFetchIntegration({ tracePropagation: false }), - ], -}); -``` - -## Using a Custom Sampler - -Configure sampling on your OpenTelemetry provider. Sentry's `tracesSampleRate` and `tracesSampler` do not control spans exported over OTLP. - -You can use an OpenTelemetry sampler or your own implementation of its `Sampler` interface. Return an OpenTelemetry `SamplingResult` directly, without `wrapSamplingDecision`. For example, this sampler respects the parent's decision and samples 10% of new traces: - - - -## ESM Loaders - -The Sentry SDK does not register ESM loader hooks. If your OpenTelemetry instrumentation needs them, [register OpenTelemetry's ESM loader hooks](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm) before loading the modules you want to instrument. diff --git a/docs/platforms/javascript/common/opentelemetry/index.mdx b/docs/platforms/javascript/common/opentelemetry/index.mdx index fbde8fe769b4c..5c8cb6024862c 100644 --- a/docs/platforms/javascript/common/opentelemetry/index.mdx +++ b/docs/platforms/javascript/common/opentelemetry/index.mdx @@ -1,6 +1,6 @@ --- -title: OpenTelemetry Support -description: "Learn how to use OpenTelemetry with Sentry." +title: Sentry and OpenTelemetry Interoperability +description: "Choose between Sentry tracing, capturing OpenTelemetry API spans, and connecting your own OpenTelemetry pipeline to Sentry." sidebar_order: 14 sidebar_section: configuration supported: @@ -29,13 +29,196 @@ supported: - javascript.tanstackstart-react notSupported: - javascript -beta: true --- -The Sentry SDK uses [OpenTelemetry](https://opentelemetry.io/) under the hood. This means that any OpenTelemetry instrumentation that emits spans will automatically be picked up by Sentry without any further configuration. + -To start capturing traces and spans, set up Tracing and Performance Monitoring with your Sentry SDK. If you don't use tracing, Sentry still connects to OpenTelemetry under the hood to ensure that context isolation and trace propagation works correctly. +The Sentry JavaScript SDK creates and sends spans without an OpenTelemetry pipeline. If your application also uses OpenTelemetry, choose how the two should work together based on who manages tracing. -By default, Sentry will automatically set up OpenTelemetry for you, but you can also use your own OpenTelemetry setup. Read the guides below to learn how to use a custom OpenTelemetry setup or how to get the most out of the Sentry and OpenTelemetry integration. +| Your setup | Configuration | How spans reach Sentry | +| ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | +| You use Sentry's automatic instrumentation and tracing APIs. | Keep the SDK defaults and enable Sentry tracing. | The Sentry SDK creates and sends spans. | +| Your code or a library creates spans through `@opentelemetry/api`, without its own OpenTelemetry provider. | Set `enableOpenTelemetrySetup: true` and enable Sentry tracing. | The SDK converts OpenTelemetry API spans into Sentry spans. | +| You manage your own OpenTelemetry provider, instrumentation, and exporters. | Set `enableOpenTelemetrySetup: false`, disable Sentry tracing, and add `openTelemetryIntegration()`. | Your OpenTelemetry exporter sends spans over OTLP. | - +## Use Sentry Tracing + +Use the SDK defaults when you want Sentry to instrument your application and manage tracing. You can also create custom spans with `Sentry.startSpan()` and related APIs. + +```javascript +import * as Sentry from "___SDK_PACKAGE___"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + // Adjust the sample rate for production. + tracesSampleRate: 1.0, +}); +``` + +Most server SDKs leave `enableOpenTelemetrySetup` off by default. They do not register an OpenTelemetry tracer provider or capture spans created through `@opentelemetry/api`. + +The `@sentry/nextjs` and `@sentry/sveltekit` SDKs enable OpenTelemetry setup by default to capture spans emitted by those frameworks. Keep that default when using Sentry tracing. + +See Tracing for setup and sampling options. + +## Capture Spans from OpenTelemetry APIs + +Set `enableOpenTelemetrySetup: true` when your code or a library uses `@opentelemetry/api` and you want Sentry to capture those spans. Sentry registers its own OpenTelemetry tracer provider and converts API calls into Sentry spans. Sentry's tracing configuration controls sampling and export. + +```javascript +import * as Sentry from "___SDK_PACKAGE___"; +import { trace } from "@opentelemetry/api"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + enableOpenTelemetrySetup: true, + tracesSampleRate: 1.0, +}); + +const tracer = trace.getTracer("my-app"); + +tracer.startActiveSpan("process-order", (span) => { + try { + // Your synchronous work here. + } finally { + span.end(); + } +}); +``` + +Initialize Sentry before the application creates spans. This setup sends spans through Sentry's transport; it does not create an OTLP exporter. If your application already registers an OpenTelemetry provider, use the next setup instead. Sentry will not replace an existing provider. + +## Run Your Own OpenTelemetry Pipeline + +Keep your own provider, context manager, propagator, instrumentation, and exporters when OpenTelemetry manages tracing. Add `Sentry.openTelemetryIntegration()` to associate Sentry errors, logs, metrics, and cron check-ins with the active OpenTelemetry span. + +Set `enableOpenTelemetrySetup: false` and leave both `tracesSampleRate` and `tracesSampler` unset. This disables Sentry tracing and avoids creating a separate set of Sentry spans alongside your OpenTelemetry spans. Sentry's instrumentation still isolates requests and captures errors. + +Initialize your OpenTelemetry provider before calling `Sentry.init()`. If its configuration is in a separate file, import that file before initializing Sentry. Set `enableOpenTelemetrySetup: false` explicitly for Next.js and SvelteKit to override their defaults. + +### Send OpenTelemetry Spans to Sentry + +Add an OTLP exporter to your existing provider. Install `@opentelemetry/exporter-trace-otlp-http` if you do not already use it. `Sentry.getOtlpTracesEndpoint()` supplies the endpoint URL and authentication headers for your DSN. + +This example uses `NodeTracerProvider`. Add the same span processor to `spanProcessors` if you use `NodeSDK` instead. Keep your existing sampler, propagator, context manager, and instrumentation; do not register a second provider. + +```javascript {filename: instrument.mjs} +import * as Sentry from "___SDK_PACKAGE___"; +import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; +import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; +import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; + +const dsn = "___PUBLIC_DSN___"; +const endpoint = Sentry.getOtlpTracesEndpoint(dsn); + +if (!endpoint) { + throw new Error("Invalid Sentry DSN"); +} + +const provider = new NodeTracerProvider({ + spanProcessors: [ + new BatchSpanProcessor(new OTLPTraceExporter(endpoint)), + // Keep any other span processors you already use. + ], +}); + +provider.register(); + +Sentry.init({ + dsn, + enableOpenTelemetrySetup: false, + // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. + integrations: [Sentry.openTelemetryIntegration()], +}); +``` + +### Use Sentry for Error Monitoring Only + +If your traces go elsewhere, keep your existing OpenTelemetry exporter and omit the Sentry OTLP exporter from the example above. The `Sentry.init()` configuration stays the same. `openTelemetryIntegration()` links Sentry errors to the active OpenTelemetry trace without sending spans to Sentry. + +### Configure Sampling + +Configure sampling on your OpenTelemetry provider. Sentry's `tracesSampleRate` and `tracesSampler` do not control spans exported over OTLP. Use an OpenTelemetry sampler or your own implementation of its `Sampler` interface, without Sentry's former `wrapSamplingDecision` helper. + +For example, add this sampler to your provider configuration to respect the parent's sampling decision and sample 10% of new traces: + +```javascript +import { + ParentBasedSampler, + TraceIdRatioBasedSampler, +} from "@opentelemetry/sdk-trace-base"; + +const sampler = new ParentBasedSampler({ + root: new TraceIdRatioBasedSampler(0.1), +}); +``` + +### Configure Instrumentation and Propagation + +Register the OpenTelemetry instrumentation you need to create spans for incoming requests, outgoing requests, database queries, and other operations. Sentry's instrumentation does not create OpenTelemetry spans in v11. Keep Sentry's default integrations enabled for request isolation, errors, and breadcrumbs. + +If your OpenTelemetry setup handles outgoing trace propagation, disable Sentry's trace headers to avoid duplicate headers. Add the relevant integration settings to your existing `Sentry.init()` call: + + + +```javascript +Sentry.init({ + dsn: "___PUBLIC_DSN___", + enableOpenTelemetrySetup: false, + integrations: [ + Sentry.openTelemetryIntegration(), + Sentry.httpIntegration({ tracePropagation: false }), + Sentry.nativeNodeFetchIntegration({ tracePropagation: false }), + ], +}); +``` + + + + + +```javascript +Sentry.init({ + dsn: "___PUBLIC_DSN___", + enableOpenTelemetrySetup: false, + integrations: [ + Sentry.openTelemetryIntegration(), + Sentry.nativeNodeFetchIntegration({ tracePropagation: false }), + ], +}); +``` + +Keep the `BunServer` integration enabled. Leaving `tracesSampleRate` and `tracesSampler` unset prevents it from sending duplicate spans. + + + +### ESM Loaders + +The Sentry SDK does not register ESM loader hooks. If your OpenTelemetry instrumentation needs them, [register OpenTelemetry's ESM loader hooks](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm) before loading the modules you want to instrument. + +## API Reference + +These APIs are available from your platform's server-side Sentry SDK. + +### `openTelemetryIntegration()` + +This integration takes no options, reports its name as `OpenTelemetry`, and is not enabled by default. It attaches the active OpenTelemetry span's trace ID and span ID to Sentry errors, logs, metrics, and cron check-ins. It does not create or export spans. + +An active Sentry span takes precedence over the OpenTelemetry span. If there is no active OpenTelemetry span, or its span context is invalid, Sentry uses its own trace context. + +### `getOtlpTracesEndpoint(dsn)` + +Pass a Sentry DSN string to get configuration for an OpenTelemetry HTTP trace exporter: + +| Field | Type | Description | +| --------- | ------------------------ | -------------------------------------------------- | +| `url` | `string` | The project's Sentry OTLP traces endpoint. | +| `headers` | `Record` | Authentication headers, including `X-Sentry-Auth`. | + +The helper returns `undefined` if the DSN cannot be parsed. It does not register a provider or send spans. + +## Migrate from v10 + +Replace `skipOpenTelemetrySetup: true` with `enableOpenTelemetrySetup: false`. Remove `SentryContextManager`, `SentryPropagator`, `SentrySampler`, `SentrySpanProcessor`, `wrapSamplingDecision`, and `validateOpenTelemetrySetup` from your custom setup. Your OpenTelemetry pipeline now owns context management, propagation, sampling, and export. + +`openTelemetryIntegration()` replaces `otlpIntegration()` from `@sentry/node-core/light/otlp`. Import it from your platform's Sentry SDK. The `setupOtlpTracesExporter` and `collectorUrl` options were removed; configure your exporter directly instead. diff --git a/docs/platforms/javascript/common/opentelemetry/integration.mdx b/docs/platforms/javascript/common/opentelemetry/integration.mdx deleted file mode 100644 index 70c54eb834114..0000000000000 --- a/docs/platforms/javascript/common/opentelemetry/integration.mdx +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: OpenTelemetry Integration -description: "Connect Sentry errors, logs, metrics, and crons to your OpenTelemetry traces with openTelemetryIntegration, and configure OTLP export with getOtlpTracesEndpoint." -supported: - - javascript.nextjs - - javascript.node - - javascript.aws-lambda - - javascript.azure-functions - - javascript.bun - - javascript.connect - - javascript.express - - javascript.fastify - - javascript.gcp-functions - - javascript.hapi - - javascript.hono - - javascript.koa - - javascript.nestjs - - javascript.nitro - - javascript.nuxt - - javascript.solidstart - - javascript.sveltekit - - javascript.astro - - javascript.remix - - javascript.react-router - - javascript.tanstackstart-react -notSupported: - - javascript -sidebar_order: 1 ---- - - - -_Import name: `Sentry.openTelemetryIntegration`_ - -Use this integration when your application runs its own OpenTelemetry pipeline. It attaches the active OpenTelemetry span's trace ID and span ID to Sentry errors, logs, metrics, and cron check-ins. The integration reports its name as `OpenTelemetry` and takes no options. - -The integration does not create or export spans. Your OpenTelemetry SDK remains responsible for sampling, propagation, and export. To send those spans to Sentry, configure an OTLP exporter using [`getOtlpTracesEndpoint`](#getotlptracesendpoint). - -## Setup - -This integration runs on the server and is not enabled by default. Import your OpenTelemetry configuration before initializing Sentry: - -```javascript {filename: instrument.mjs} -import "./otel.config.mjs"; -import * as Sentry from "___SDK_PACKAGE___"; - -Sentry.init({ - dsn: "___PUBLIC_DSN___", - enableOpenTelemetrySetup: false, - // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. - integrations: [Sentry.openTelemetryIntegration()], -}); -``` - -Here, `otel.config.mjs` registers your existing OpenTelemetry provider, context manager, propagator, and instrumentation. In frameworks with their own instrumentation entry point, initialize OpenTelemetry there before calling `Sentry.init()`. - -Keep `enableOpenTelemetrySetup` set to `false`. This is already the default except in `@sentry/nextjs` and `@sentry/sveltekit`. Leave `tracesSampleRate` and `tracesSampler` unset to keep Sentry tracing off. An active Sentry span takes precedence over the OpenTelemetry span. - -If there is no active OpenTelemetry span, or its span context is invalid, Sentry uses its own trace context. - -For exporter examples, sampling, and HTTP propagation settings, see Using Your Existing OpenTelemetry Setup. - -## `getOtlpTracesEndpoint` - -`Sentry.getOtlpTracesEndpoint(dsn)` converts a Sentry DSN into configuration for an OpenTelemetry HTTP trace exporter. It takes a DSN string and returns an object with these fields: - -| Field | Type | Description | -| --------- | ------------------------ | ------------------------------------------------------------------- | -| `url` | `string` | The project's Sentry OTLP traces endpoint. | -| `headers` | `Record` | Authentication headers for the endpoint, including `X-Sentry-Auth`. | - -If the DSN cannot be parsed, the helper returns `undefined`. The helper does not register a provider or send spans. - -Pass the result to `OTLPTraceExporter` from `@opentelemetry/exporter-trace-otlp-http`: - -```javascript -import * as Sentry from "___SDK_PACKAGE___"; -import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; - -const endpoint = Sentry.getOtlpTracesEndpoint("___PUBLIC_DSN___"); - -if (!endpoint) { - throw new Error("Invalid Sentry DSN"); -} - -const exporter = new OTLPTraceExporter(endpoint); -``` - -Add this exporter to your existing provider with a `BatchSpanProcessor`, as shown in the OTLP setup examples. If you only want to associate Sentry errors with traces exported elsewhere, keep your existing exporter and omit this helper. - -## Migrating from `otlpIntegration` - -In v11, `openTelemetryIntegration()` replaces `otlpIntegration()` from `@sentry/node-core/light/otlp`. Import it from your platform's Sentry SDK. The `setupOtlpTracesExporter` and `collectorUrl` options were removed. Configure the exporter in your OpenTelemetry setup instead. diff --git a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx deleted file mode 100644 index 40bc8d5179743..0000000000000 --- a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: Using OpenTelemetry APIs -description: "Learn how to use OpenTelemetry APIs with Sentry." -supported: - - javascript.nextjs - - javascript.node - - javascript.eve - - javascript.mastra - - javascript.aws-lambda - - javascript.azure-functions - - javascript.bun - - javascript.connect - - javascript.express - - javascript.fastify - - javascript.gcp-functions - - javascript.hapi - - javascript.hono - - javascript.koa - - javascript.nestjs - - javascript.nitro - - javascript.nuxt - - javascript.solidstart - - javascript.sveltekit - - javascript.astro - - javascript.remix - - javascript.react-router - - javascript.tanstackstart-react -notSupported: - - javascript -sidebar_order: 1 ---- - -Sentry supports OpenTelemetry APIs out of the box. Any spans started using OpenTelemetry APIs will be automatically captured by Sentry, while any spans started using the Sentry SDK will be automatically propagated to OpenTelemetry. - -## Adding Additional OpenTelemetry Instrumentation - -While the Sentry SDK includes some OpenTelemetry instrumentation out of the box, you may want to add additional instrumentation to your application. This can be done by registering the instrumentation through OpenTelemetry like the example below: - -```javascript {tabTitle: ESM} {12-13} -import * as Sentry from "@sentry/node"; -import { - GenericPoolInstrumentation, -} from "@opentelemetry/instrumentation-generic-pool"; - -Sentry.init({ - dsn: "___DSN___", - - // The SentrySampler will use this to determine which traces to sample - tracesSampleRate: 1.0, - - // Add additional OpenTelemetry instrumentation: - openTelemetryInstrumentations: [new GenericPoolInstrumentation()], -}); -``` -```javascript {tabTitle: CJS} {12-13} -const Sentry = require("@sentry/node"); -const { - GenericPoolInstrumentation, -} = require("@opentelemetry/instrumentation-generic-pool"); - -Sentry.init({ - dsn: "___DSN___", - - // The SentrySampler will use this to determine which traces to sample - tracesSampleRate: 1.0, - - // Add additional OpenTelemetry instrumentation: - openTelemetryInstrumentations: [new GenericPoolInstrumentation()], -}); -``` - - - It is possible to add instrumentations via `registerInstrumentations()` from - `@opentelemetry/instrumentation`. However, with ESM (`import`/`export` syntax) - you need to be careful to do so before importing any modules that should be - instrumented. - -As a rule of thumb, `registerInstrumentations()` should be called right after, and in the same context as registering ESM Loaders. - - - -## Using an OpenTelemetry Tracer - -We recommend using `Sentry.startSpan()` and related APIs to create spans, but you can also create spans using native OpenTelemetry APIs. - -You can access the tracer Sentry uses via `client.tracer` and then create spans with OpenTelemetry APIs, as shown below: - -```javascript {tabTitle: ESM} -import * as Sentry from "@sentry/node"; - -const tracer = Sentry.getClient()?.tracer; -// Now you can use native APIs on the tracer: -tracer.startActiveSpan("span name", () => { - // measure something -}); -``` -```javascript {tabTitle: CJS} -const Sentry = require("@sentry/node"); - -const tracer = Sentry.getClient()?.tracer; -// Now you can use native APIs on the tracer: -tracer.startActiveSpan("span name", () => { - // measure something -}); -``` - -You can also use any other tracer. All OpenTelemetry spans will be picked up by Sentry automatically. - -## Modifying the default OpenTelemetry TracerProvider - -You can access the tracer provider set up by Sentry when using Sentry's default OpenTelemetry instrumentation. - -```javascript {tabTitle: ESM} -import * as Sentry from "@sentry/node"; - -const provider = Sentry.getClient()?.traceProvider; -``` -```javascript {tabTitle: CJS} -const Sentry = require("@sentry/node"); - -const provider = Sentry.getClient()?.traceProvider; -``` - -## Adding Additional Span Processors - -You can add additional span processors to the tracer provider set up by Sentry when using Sentry's default OpenTelemetry instrumentation. - -```javascript {tabTitle: ESM} -import * as Sentry from "@sentry/node"; - -Sentry.init({ - dsn: "___DSN___", - - // The SentrySampler will use this to determine which traces to sample - tracesSampleRate: 1.0, - - // Add additional OpenTelemetry SpanProcessors: - openTelemetrySpanProcessors: [new MySpanProcessor()], -}); -``` -```javascript {tabTitle: CJS} -const Sentry = require("@sentry/node"); - -Sentry.init({ - dsn: "___DSN___", - - // The SentrySampler will use this to determine which traces to sample - tracesSampleRate: 1.0, - - // Add additional OpenTelemetry SpanProcessors: - openTelemetrySpanProcessors: [new MySpanProcessor()], -}); -``` diff --git a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx deleted file mode 100644 index 4d83448ef1c65..0000000000000 --- a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun.mdx +++ /dev/null @@ -1,11 +0,0 @@ -```javascript {tabTitle: ESM} -import * as Sentry from "@sentry/bun"; - -// Initialize your existing OpenTelemetry setup before calling Sentry.init(). -Sentry.init({ - dsn: "___PUBLIC_DSN___", - enableOpenTelemetrySetup: false, - // Leave tracesSampleRate and tracesSampler unset. - integrations: [Sentry.openTelemetryIntegration()], -}); -``` diff --git a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx deleted file mode 100644 index a248c87f9c9a1..0000000000000 --- a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.mdx +++ /dev/null @@ -1,23 +0,0 @@ -```javascript {tabTitle: ESM} -import * as Sentry from "@sentry/node"; - -// Initialize your existing OpenTelemetry setup before calling Sentry.init(). -Sentry.init({ - dsn: "___PUBLIC_DSN___", - enableOpenTelemetrySetup: false, - // Leave tracesSampleRate and tracesSampler unset. - integrations: [Sentry.openTelemetryIntegration()], -}); -``` - -```javascript {tabTitle: CJS} -const Sentry = require("@sentry/node"); - -// Initialize your existing OpenTelemetry setup before calling Sentry.init(). -Sentry.init({ - dsn: "___PUBLIC_DSN___", - enableOpenTelemetrySetup: false, - // Leave tracesSampleRate and tracesSampler unset. - integrations: [Sentry.openTelemetryIntegration()], -}); -``` diff --git a/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx b/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx deleted file mode 100644 index 7551d9900d9f7..0000000000000 --- a/platform-includes/performance/opentelemetry-setup/javascript.bun.mdx +++ /dev/null @@ -1,57 +0,0 @@ -Add an OTLP trace exporter to your existing OpenTelemetry provider to send spans to Sentry. `Sentry.getOtlpTracesEndpoint()` returns the endpoint URL and authentication headers for your DSN. Keep your existing sampler, context manager, propagator, and instrumentation. - -The examples below show the Sentry-specific additions using `NodeTracerProvider` or `NodeSDK`. Install `@opentelemetry/exporter-trace-otlp-http` if you do not already use it. - -```javascript {tabTitle: NodeTracerProvider} -import * as Sentry from "@sentry/bun"; -import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; -import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; -import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; - -const dsn = "___PUBLIC_DSN___"; - -const provider = new NodeTracerProvider({ - spanProcessors: [ - new BatchSpanProcessor( - new OTLPTraceExporter(Sentry.getOtlpTracesEndpoint(dsn)) - ), - // Keep any other span processors you already use. - ], -}); - -provider.register(); - -Sentry.init({ - dsn, - enableOpenTelemetrySetup: false, - // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. - integrations: [Sentry.openTelemetryIntegration()], -}); -``` - -```javascript {tabTitle: NodeSDK} -import * as Sentry from "@sentry/bun"; -import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; -import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; -import { NodeSDK } from "@opentelemetry/sdk-node"; - -const dsn = "___PUBLIC_DSN___"; - -const sdk = new NodeSDK({ - spanProcessors: [ - new BatchSpanProcessor( - new OTLPTraceExporter(Sentry.getOtlpTracesEndpoint(dsn)) - ), - // Keep any other span processors you already use. - ], -}); - -sdk.start(); - -Sentry.init({ - dsn, - enableOpenTelemetrySetup: false, - // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. - integrations: [Sentry.openTelemetryIntegration()], -}); -``` diff --git a/platform-includes/performance/opentelemetry-setup/javascript.mdx b/platform-includes/performance/opentelemetry-setup/javascript.mdx deleted file mode 100644 index cdde079095b56..0000000000000 --- a/platform-includes/performance/opentelemetry-setup/javascript.mdx +++ /dev/null @@ -1,57 +0,0 @@ -Add an OTLP trace exporter to your existing OpenTelemetry provider to send spans to Sentry. `Sentry.getOtlpTracesEndpoint()` returns the endpoint URL and authentication headers for your DSN. Keep your existing sampler, context manager, propagator, and instrumentation. - -The examples below show the Sentry-specific additions using `NodeTracerProvider` or `NodeSDK`. Install `@opentelemetry/exporter-trace-otlp-http` if you do not already use it. - -```javascript {tabTitle: NodeTracerProvider} -import * as Sentry from "@sentry/node"; -import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; -import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; -import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; - -const dsn = "___PUBLIC_DSN___"; - -const provider = new NodeTracerProvider({ - spanProcessors: [ - new BatchSpanProcessor( - new OTLPTraceExporter(Sentry.getOtlpTracesEndpoint(dsn)) - ), - // Keep any other span processors you already use. - ], -}); - -provider.register(); - -Sentry.init({ - dsn, - enableOpenTelemetrySetup: false, - // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. - integrations: [Sentry.openTelemetryIntegration()], -}); -``` - -```javascript {tabTitle: NodeSDK} -import * as Sentry from "@sentry/node"; -import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; -import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; -import { NodeSDK } from "@opentelemetry/sdk-node"; - -const dsn = "___PUBLIC_DSN___"; - -const sdk = new NodeSDK({ - spanProcessors: [ - new BatchSpanProcessor( - new OTLPTraceExporter(Sentry.getOtlpTracesEndpoint(dsn)) - ), - // Keep any other span processors you already use. - ], -}); - -sdk.start(); - -Sentry.init({ - dsn, - enableOpenTelemetrySetup: false, - // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. - integrations: [Sentry.openTelemetryIntegration()], -}); -``` diff --git a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx deleted file mode 100644 index 6a3a32727d268..0000000000000 --- a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun.mdx +++ /dev/null @@ -1,17 +0,0 @@ -```javascript -import { - ParentBasedSampler, - TraceIdRatioBasedSampler, -} from "@opentelemetry/sdk-trace-base"; -import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; - -const provider = new NodeTracerProvider({ - // Respect the parent's sampling decision, or sample 10% of new traces. - sampler: new ParentBasedSampler({ - root: new TraceIdRatioBasedSampler(0.1), - }), - // Keep your existing span processors, including the OTLP exporter to Sentry. -}); - -provider.register(); -``` diff --git a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx deleted file mode 100644 index 6a3a32727d268..0000000000000 --- a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.mdx +++ /dev/null @@ -1,17 +0,0 @@ -```javascript -import { - ParentBasedSampler, - TraceIdRatioBasedSampler, -} from "@opentelemetry/sdk-trace-base"; -import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; - -const provider = new NodeTracerProvider({ - // Respect the parent's sampling decision, or sample 10% of new traces. - sampler: new ParentBasedSampler({ - root: new TraceIdRatioBasedSampler(0.1), - }), - // Keep your existing span processors, including the OTLP exporter to Sentry. -}); - -provider.register(); -``` diff --git a/redirects.js b/redirects.js index ce4a3cae7c455..e8050a4173383 100644 --- a/redirects.js +++ b/redirects.js @@ -588,6 +588,34 @@ const developerDocsRedirects = [ /** @type {import('next/dist/lib/load-custom-routes').Redirect[]} */ const userDocsRedirects = [ + { + source: '/platforms/javascript/guides/:guide/opentelemetry/custom-setup/', + destination: + '/platforms/javascript/guides/:guide/opentelemetry/#run-your-own-opentelemetry-pipeline', + }, + { + source: '/platforms/javascript/guides/:guide/opentelemetry/custom-setup.md', + destination: '/platforms/javascript/guides/:guide/opentelemetry.md', + }, + { + source: '/platforms/javascript/guides/:guide/opentelemetry/using-opentelemetry-apis/', + destination: + '/platforms/javascript/guides/:guide/opentelemetry/#capture-spans-from-opentelemetry-apis', + }, + { + source: '/platforms/javascript/guides/:guide/opentelemetry/using-opentelemetry-apis.md', + destination: '/platforms/javascript/guides/:guide/opentelemetry.md', + }, + { + source: '/platforms/javascript/guides/:guide/opentelemetry/integration/', + destination: + '/platforms/javascript/guides/:guide/opentelemetry/#api-reference', + }, + { + source: '/platforms/javascript/guides/:guide/opentelemetry/integration.md', + destination: '/platforms/javascript/guides/:guide/opentelemetry.md', + }, + // Guides → Get Started restructure { source: '/guides/', From 3f9a587e34f0aa6d9bc66ee981b0e0fddfe5c6d3 Mon Sep 17 00:00:00 2001 From: Martin Sonnberger Date: Thu, 17 Sep 2026 16:00:02 +0200 Subject: [PATCH 04/10] docs(javascript): Preserve v10 OpenTelemetry docs alongside v11 Add the integration reference and wrap the setup comparison table. Align propagation guidance with the v11 SDK. Refs SDK-1470, SDK-1471, SDK-1490 --- .../configuration/integrations/http.mdx | 2 +- .../configuration/integrations/nodefetch.mdx | 2 +- .../integrations/opentelemetry.mdx | 91 ++++++++ .../opentelemetry/custom-setup__v10.x.mdx | 210 ++++++++++++++++++ .../javascript/common/opentelemetry/index.mdx | 86 ++----- .../common/opentelemetry/index__v10.x.mdx | 41 ++++ .../using-opentelemetry-apis__v10.x.mdx | 152 +++++++++++++ .../javascript.bun__v10.x.mdx | 49 ++++ .../javascript__v10.x.mdx | 88 ++++++++ .../javascript.bun__v10.x.mdx | 86 +++++++ .../opentelemetry-setup/javascript__v10.x.mdx | 78 +++++++ .../javascript.bun__v10.x.mdx | 43 ++++ .../with-custom-sampler/javascript__v10.x.mdx | 100 +++++++++ redirects.js | 5 +- src/components/docPage/type.scss | 17 ++ 15 files changed, 974 insertions(+), 76 deletions(-) create mode 100644 docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx create mode 100644 docs/platforms/javascript/common/opentelemetry/custom-setup__v10.x.mdx create mode 100644 docs/platforms/javascript/common/opentelemetry/index__v10.x.mdx create mode 100644 docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis__v10.x.mdx create mode 100644 platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun__v10.x.mdx create mode 100644 platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript__v10.x.mdx create mode 100644 platform-includes/performance/opentelemetry-setup/javascript.bun__v10.x.mdx create mode 100644 platform-includes/performance/opentelemetry-setup/javascript__v10.x.mdx create mode 100644 platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun__v10.x.mdx create mode 100644 platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript__v10.x.mdx diff --git a/docs/platforms/javascript/common/configuration/integrations/http.mdx b/docs/platforms/javascript/common/configuration/integrations/http.mdx index 00eb0ae99c224..31c73e77d9f6e 100644 --- a/docs/platforms/javascript/common/configuration/integrations/http.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/http.mdx @@ -93,7 +93,7 @@ The callback function receives two arguments: _Type: `boolean`_ (Defaults to `true`) -Whether to inject trace propagation headers (`sentry-trace`, `baggage`, `traceparent`) into outgoing HTTP requests. When set to `false`, Sentry will not inject any trace propagation headers but will still create breadcrumbs (if `breadcrumbs` is enabled). This is useful when `enableOpenTelemetrySetup: false` is configured and your external OpenTelemetry setup already handles trace propagation, to avoid duplicate headers. +Whether to inject trace propagation headers (`sentry-trace`, `baggage`, `traceparent`) into outgoing HTTP requests. When set to `false`, Sentry will not inject any trace propagation headers but will still create breadcrumbs (if `breadcrumbs` is enabled). With `openTelemetryIntegration()` enabled and Sentry tracing off, your OpenTelemetry propagator already handles outgoing trace propagation. ### `ignoreOutgoingRequests` diff --git a/docs/platforms/javascript/common/configuration/integrations/nodefetch.mdx b/docs/platforms/javascript/common/configuration/integrations/nodefetch.mdx index 1ecfe131d0ac5..1314528f41519 100644 --- a/docs/platforms/javascript/common/configuration/integrations/nodefetch.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/nodefetch.mdx @@ -61,7 +61,7 @@ If set to false, no breadcrumbs will be captured. _Type: `boolean`_ (Defaults to `true`) -Whether to inject trace propagation headers (`sentry-trace`, `baggage`, `traceparent`) into outgoing fetch requests. When set to `false`, Sentry will not inject any trace propagation headers but will still create breadcrumbs (if `breadcrumbs` is enabled). This is useful when `enableOpenTelemetrySetup: false` is configured and your external OpenTelemetry setup already handles trace propagation, to avoid duplicate headers. +Whether to inject trace propagation headers (`sentry-trace`, `baggage`, `traceparent`) into outgoing fetch requests. When set to `false`, Sentry will not inject any trace propagation headers but will still create breadcrumbs (if `breadcrumbs` is enabled). With `openTelemetryIntegration()` enabled and Sentry tracing off, your OpenTelemetry propagator already handles outgoing trace propagation. ### `ignoreOutgoingRequests` diff --git a/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx b/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx new file mode 100644 index 0000000000000..884265525596f --- /dev/null +++ b/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx @@ -0,0 +1,91 @@ +--- +title: OpenTelemetry +description: "Connect Sentry errors, logs, metrics, and crons to your OpenTelemetry traces with openTelemetryIntegration, and configure OTLP export with getOtlpTracesEndpoint." +supported: + - javascript.nextjs + - javascript.node + - javascript.eve + - javascript.aws-lambda + - javascript.azure-functions + - javascript.bun + - javascript.connect + - javascript.express + - javascript.fastify + - javascript.gcp-functions + - javascript.hapi + - javascript.hono + - javascript.koa + - javascript.nestjs + - javascript.nitro + - javascript.nuxt + - javascript.solidstart + - javascript.sveltekit + - javascript.astro + - javascript.remix + - javascript.react-router + - javascript.tanstackstart-react +notSupported: + - javascript +--- + + + +_Import name: `Sentry.openTelemetryIntegration`_ + +Use this integration when your application runs its own OpenTelemetry pipeline. It attaches the active OpenTelemetry span's trace ID and span ID to Sentry errors, logs, metrics, and cron check-ins. The integration reports its name as `OpenTelemetry` and takes no options. + +The integration does not create or export spans. Your OpenTelemetry SDK handles sampling, propagation, and export. To send those spans to Sentry, configure an OTLP exporter using [`getOtlpTracesEndpoint`](#getotlptracesendpoint). + +## Setup + +This integration runs on the server and is not enabled by default. Import your OpenTelemetry configuration before initializing Sentry: + +```javascript {filename: instrument.mjs} +import "./otel.config.mjs"; +import * as Sentry from "___SDK_PACKAGE___"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + enableOpenTelemetrySetup: false, + // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. + integrations: [Sentry.openTelemetryIntegration()], +}); +``` + +In this example, `otel.config.mjs` registers your existing OpenTelemetry provider, context manager, propagator, and instrumentation. In frameworks with their own instrumentation entry point, initialize OpenTelemetry there before calling `Sentry.init()`. + +Keep `enableOpenTelemetrySetup` set to `false`. This is already the default except in `@sentry/nextjs` and `@sentry/sveltekit`. Leave `tracesSampleRate` and `tracesSampler` unset to keep Sentry tracing off. Your OpenTelemetry propagator handles outgoing trace propagation. + +An active Sentry span takes precedence over the OpenTelemetry span. + +If there is no active OpenTelemetry span, or its span context is invalid, Sentry uses its own trace context. + +For exporter examples, sampling, and trace propagation, see the OpenTelemetry setup guide. + +## `getOtlpTracesEndpoint` + +`Sentry.getOtlpTracesEndpoint(dsn)` converts a Sentry DSN into configuration for an OpenTelemetry HTTP trace exporter. It takes a DSN string and returns an object with these fields: + +| Field | Type | Description | +| --------- | ------------------------ | ------------------------------------------------------------------- | +| `url` | `string` | The project's Sentry OTLP traces endpoint. | +| `headers` | `Record` | Authentication headers for the endpoint, including `X-Sentry-Auth`. | + +If the helper cannot parse the DSN, it returns `undefined`. The helper does not register a provider or send spans. + +Pass the result to `OTLPTraceExporter` from `@opentelemetry/exporter-trace-otlp-http`: + +```javascript +import * as Sentry from "___SDK_PACKAGE___"; +import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; + +const endpoint = Sentry.getOtlpTracesEndpoint("___PUBLIC_DSN___"); + +if (!endpoint) { + throw new Error("Could not parse the Sentry DSN"); +} + +const exporter = new OTLPTraceExporter(endpoint); +``` + +Add this exporter to your existing provider with a `BatchSpanProcessor`, as shown in the OTLP setup examples. If you only want to associate Sentry errors with traces exported elsewhere, keep your existing exporter and omit this helper. diff --git a/docs/platforms/javascript/common/opentelemetry/custom-setup__v10.x.mdx b/docs/platforms/javascript/common/opentelemetry/custom-setup__v10.x.mdx new file mode 100644 index 0000000000000..0499cec6813aa --- /dev/null +++ b/docs/platforms/javascript/common/opentelemetry/custom-setup__v10.x.mdx @@ -0,0 +1,210 @@ +--- +title: Using Your Existing OpenTelemetry Setup +description: "Learn how to use your existing custom OpenTelemetry setup with Sentry." +supported: + - javascript.nextjs + - javascript.node + - javascript.eve + - javascript.aws-lambda + - javascript.azure-functions + - javascript.bun + - javascript.connect + - javascript.express + - javascript.fastify + - javascript.gcp-functions + - javascript.hapi + - javascript.hono + - javascript.koa + - javascript.nestjs + - javascript.nitro + - javascript.nuxt + - javascript.solidstart + - javascript.sveltekit + - javascript.astro + - javascript.remix + - javascript.react-router + - javascript.tanstackstart-react +notSupported: + - javascript +sidebar_order: 0 +--- + + + +Use this guide when you already have a completely custom OpenTelemetry setup or when you intend to add a custom OpenTelemetry setup next to the Sentry SDK. + +Setting `skipOpenTelemetrySetup: true` disables the Sentry SDK's automatic OpenTelemetry configuration, **requiring** you to perform the setup manually. For example, to ensure errors are correctly associated with their scope, you must add the `SentryContextManager` to your OpenTelemetry setup. You can find details on the required manual setup further down on this page. + +If you are looking to simply add individual OpenTelemetry instrumentation to your Sentry setup, you should read Adding Additional OpenTelemetry Instrumentation instead. + + + + + + +If you don't need the full `@sentry/node` SDK and want a simpler way to bridge your existing OpenTelemetry setup with Sentry, consider using lightweight mode with the OTLP integration instead. It requires significantly less manual wiring. + + + + + + + + + + + + +## Using Sentry for Error Monitoring Only + +If you have a custom OpenTelemetry setup and only want to use Sentry for error monitoring, you can skip adding the `SentrySpanProcessor`. You'll still need to add the `SentryContextManager`, `SentryPropagator`, and `SentrySampler` to your setup even if you don't want to send any tracing data to Sentry. Read on to learn why this is needed. + +In order for the Sentry SDK to work as expected, and for it to be in sync with OpenTelemetry, we need a few components to be in place. + +**Components needed for Sentry to work correctly:** + +- **SentryContextManager**: Ensures that the OpenTelemetry context is in sync with Sentry, for example to correctly isolate data between simultaneous requests. +- **SentrySampler**: Ensures that the Sentry `tracesSampleRate` is respected. Even if you don't use Sentry for tracing, you'll still need this in order for trace propagation to work as expected. Read [Using a Custom Sampler](#using-a-custom-sampler) if you want to use a custom sampler. +- **SentryPropagator**: Ensures that trace propagation works correctly. +- [Required Instrumentation](#required-instrumentation): Ensures that trace propagation works correctly. + +**Additional components needed to also use Sentry for tracing:** + +- **SentrySpanProcessor**: Ensures that spans are correctly sent to Sentry. + + + Trace propagation is needed for Sentry to automatically connect services + together. (For example, if you want to connect the frontend and backend, or + different backend services.) This makes it possible to see related errors + across services.{" "} + + Learn more about Trace Propagation. + + + +The following code snippet shows how to set up Sentry for error monitoring only: + + + + + + + + + +## Required Instrumentation + +By default, Sentry will register OpenTelemetry instrumentation to automatically capture spans for traces spanning incoming and outgoing HTTP requests, DB queries, and more. + +If tracing is not enabled (no `tracesSampleRate` is defined in the SDK configuration), only a minimal amount of OpenTelemetry instrumentation will be registered. This includes the following: + +{/* prettier-ignore-start */} + +- A Sentry-specific HTTP instrumentation that handles request isolation and trace propagation. This can work in parallel with [@opentelemetry/instrumentation-http](https://www.npmjs.com/package/@opentelemetry/instrumentation-http), if you register it. +- [nativeNodeFetchIntegration](/platforms/javascript/guides/node/configuration/integrations/nodefetch/) registers [opentelemetry-instrumentation-fetch-node](https://www.npmjs.com/package/opentelemetry-instrumentation-fetch-node) which is needed for trace propagation. + +{/* prettier-ignore-end */} + + + + If tracing is not enabled, performance instrumentations will not be + registered but they will still be included in the bundle. If you want to + reduce the bundle size or used dependencies, you can also{" "} + + Set up Sentry without Performance Integrations + + + + +These are needed to make sure that trace propagation works correctly. + +If you want to add your own http/node-fetch instrumentation, you have to follow the following steps: + +### Custom HTTP Instrumentation + + + +You can add your own `@opentelemetry/instrumentation-http` instance in your OpenTelemetry setup. However, in this case, you need to disable span creation in Sentry's `httpIntegration`. You can also set `tracePropagation: false` to prevent Sentry from injecting trace headers, letting your OpenTelemetry setup handle propagation instead: + + + ```javascript + const sentryClient = Sentry.init({ + dsn: "___DSN___", + skipOpenTelemetrySetup: true, + integrations: [Sentry.httpIntegration({ spans: false, tracePropagation: false })], +}); + ``` + + + +```javascript + const sentryClient = Sentry.init({ + dsn: "___DSN___", + skipOpenTelemetrySetup: true, + integrations: (integrations) => + // Also filter out the BunServer integration to avoid emitting duplicated spans from Sentry AND your custom OTel instrumentation + integrations.filter((i) => i.name !== "BunServer") +}); +``` + + +It's important that `httpIntegration` is still registered this way to ensure that the Sentry SDK can correctly isolate requests, for example when capturing errors. + +### Custom Node Fetch Instrumentation + +If tracing is disabled, the Node Fetch instrumentation will not emit any spans. In this scenario, it will only inject sentry-specific trace propagation headers. You are free to add your own Node Fetch instrumentation on top of this which may emit spans as you like. + +If your OpenTelemetry setup already handles trace propagation for fetch requests, you can set `tracePropagation: false` to prevent Sentry from injecting duplicate trace headers: + +```javascript +const sentryClient = Sentry.init({ + dsn: "___DSN___", + skipOpenTelemetrySetup: true, + integrations: [ + Sentry.nativeNodeFetchIntegration({ tracePropagation: false }), + ], +}); +``` + +## Using a Custom Sampler + +While you can use your own sampler, we recommend that you use the `SentrySampler`. This will ensure that the correct subset of traces will be sent to Sentry, based on your `tracesSampleRate`. It will also ensure that all other Sentry features like trace propagation work as expected. If you do need to use your own sampler, make sure to wrap your `SamplingResult` with our `wrapSamplingDecision` method like in the example below: + + + + + + + + + + + +It is recommended registering your own ESM loader hooks when you have a complete custom OpenTelemetry setup, first and foremost because it makes the most sense architecturally. +You likely went through the effort to set up OpenTelemetry by itself and now you want to add Sentry to your application without messing with your OpenTelemetry setup. + +Additionally, there are a few pitfalls that can very simply be avoided by registering your own hooks: + +- Registering loader hooks multiple times might result in duplicated spans being created. [More details.](https://github.com/getsentry/sentry-javascript/issues/14065#issuecomment-2435546961) +- OpenTelemetry instrumentation in ESM is very sensitive as to _when_ it is added relative to _when_ the loader hooks are registered. + The control over this should stay with the owner of the OpenTelemetry setup and not the Sentry SDK. + + + + + + + Learn more about ESM installation methods. + + + diff --git a/docs/platforms/javascript/common/opentelemetry/index.mdx b/docs/platforms/javascript/common/opentelemetry/index.mdx index 5c8cb6024862c..4c710df276206 100644 --- a/docs/platforms/javascript/common/opentelemetry/index.mdx +++ b/docs/platforms/javascript/common/opentelemetry/index.mdx @@ -1,6 +1,6 @@ --- -title: Sentry and OpenTelemetry Interoperability -description: "Choose between Sentry tracing, capturing OpenTelemetry API spans, and connecting your own OpenTelemetry pipeline to Sentry." +title: OpenTelemetry Interoperability +description: "Learn how to use OpenTelemetry with Sentry." sidebar_order: 14 sidebar_section: configuration supported: @@ -31,9 +31,9 @@ notSupported: - javascript --- - +The Sentry JavaScript SDK creates and sends spans without an OpenTelemetry pipeline. If your application also uses OpenTelemetry, choose a setup based on which SDK manages tracing. -The Sentry JavaScript SDK creates and sends spans without an OpenTelemetry pipeline. If your application also uses OpenTelemetry, choose how the two should work together based on who manages tracing. +
| Your setup | Configuration | How spans reach Sentry | | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | @@ -41,9 +41,11 @@ The Sentry JavaScript SDK creates and sends spans without an OpenTelemetry pipel | Your code or a library creates spans through `@opentelemetry/api`, without its own OpenTelemetry provider. | Set `enableOpenTelemetrySetup: true` and enable Sentry tracing. | The SDK converts OpenTelemetry API spans into Sentry spans. | | You manage your own OpenTelemetry provider, instrumentation, and exporters. | Set `enableOpenTelemetrySetup: false`, disable Sentry tracing, and add `openTelemetryIntegration()`. | Your OpenTelemetry exporter sends spans over OTLP. | +
+ ## Use Sentry Tracing -Use the SDK defaults when you want Sentry to instrument your application and manage tracing. You can also create custom spans with `Sentry.startSpan()` and related APIs. +Use the SDK defaults when you want Sentry to instrument your application and manage tracing. Create custom spans with `Sentry.startSpan()` and related APIs. ```javascript import * as Sentry from "___SDK_PACKAGE___"; @@ -63,7 +65,7 @@ See Tracing for setup and sampling o ## Capture Spans from OpenTelemetry APIs -Set `enableOpenTelemetrySetup: true` when your code or a library uses `@opentelemetry/api` and you want Sentry to capture those spans. Sentry registers its own OpenTelemetry tracer provider and converts API calls into Sentry spans. Sentry's tracing configuration controls sampling and export. +To capture spans that your code or a library creates through `@opentelemetry/api`, set `enableOpenTelemetrySetup: true`. Sentry registers an OpenTelemetry-compatible tracer provider, context manager, and propagator. Spans created through `@opentelemetry/api` become native Sentry spans. Sentry's tracing configuration controls sampling and export. ```javascript import * as Sentry from "___SDK_PACKAGE___"; @@ -90,9 +92,9 @@ Initialize Sentry before the application creates spans. This setup sends spans t ## Run Your Own OpenTelemetry Pipeline -Keep your own provider, context manager, propagator, instrumentation, and exporters when OpenTelemetry manages tracing. Add `Sentry.openTelemetryIntegration()` to associate Sentry errors, logs, metrics, and cron check-ins with the active OpenTelemetry span. +Keep your own provider, context manager, propagator, instrumentation, and exporters when OpenTelemetry manages tracing. Add `Sentry.openTelemetryIntegration()` to associate Sentry errors, logs, metrics, and cron check-ins with the active OpenTelemetry span. -Set `enableOpenTelemetrySetup: false` and leave both `tracesSampleRate` and `tracesSampler` unset. This disables Sentry tracing and avoids creating a separate set of Sentry spans alongside your OpenTelemetry spans. Sentry's instrumentation still isolates requests and captures errors. +Set `enableOpenTelemetrySetup: false` and leave both `tracesSampleRate` and `tracesSampler` unset. This disables Sentry tracing and prevents duplicate spans for the same operations. Sentry's instrumentation still isolates requests and captures errors. Initialize your OpenTelemetry provider before calling `Sentry.init()`. If its configuration is in a separate file, import that file before initializing Sentry. Set `enableOpenTelemetrySetup: false` explicitly for Next.js and SvelteKit to override their defaults. @@ -112,7 +114,7 @@ const dsn = "___PUBLIC_DSN___"; const endpoint = Sentry.getOtlpTracesEndpoint(dsn); if (!endpoint) { - throw new Error("Invalid Sentry DSN"); + throw new Error("Could not parse the Sentry DSN"); } const provider = new NodeTracerProvider({ @@ -138,7 +140,7 @@ If your traces go elsewhere, keep your existing OpenTelemetry exporter and omit ### Configure Sampling -Configure sampling on your OpenTelemetry provider. Sentry's `tracesSampleRate` and `tracesSampler` do not control spans exported over OTLP. Use an OpenTelemetry sampler or your own implementation of its `Sampler` interface, without Sentry's former `wrapSamplingDecision` helper. +Configure sampling on your OpenTelemetry provider. Sentry's `tracesSampleRate` and `tracesSampler` do not control spans exported over OTLP. Use an OpenTelemetry sampler or your own implementation of its `Sampler` interface. For example, add this sampler to your provider configuration to respect the parent's sampling decision and sample 10% of new traces: @@ -157,68 +159,8 @@ const sampler = new ParentBasedSampler({ Register the OpenTelemetry instrumentation you need to create spans for incoming requests, outgoing requests, database queries, and other operations. Sentry's instrumentation does not create OpenTelemetry spans in v11. Keep Sentry's default integrations enabled for request isolation, errors, and breadcrumbs. -If your OpenTelemetry setup handles outgoing trace propagation, disable Sentry's trace headers to avoid duplicate headers. Add the relevant integration settings to your existing `Sentry.init()` call: - - - -```javascript -Sentry.init({ - dsn: "___PUBLIC_DSN___", - enableOpenTelemetrySetup: false, - integrations: [ - Sentry.openTelemetryIntegration(), - Sentry.httpIntegration({ tracePropagation: false }), - Sentry.nativeNodeFetchIntegration({ tracePropagation: false }), - ], -}); -``` - - - - - -```javascript -Sentry.init({ - dsn: "___PUBLIC_DSN___", - enableOpenTelemetrySetup: false, - integrations: [ - Sentry.openTelemetryIntegration(), - Sentry.nativeNodeFetchIntegration({ tracePropagation: false }), - ], -}); -``` - -Keep the `BunServer` integration enabled. Leaving `tracesSampleRate` and `tracesSampler` unset prevents it from sending duplicate spans. - - +With `openTelemetryIntegration()` enabled and Sentry tracing off, your OpenTelemetry propagator handles outgoing trace propagation. ### ESM Loaders -The Sentry SDK does not register ESM loader hooks. If your OpenTelemetry instrumentation needs them, [register OpenTelemetry's ESM loader hooks](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm) before loading the modules you want to instrument. - -## API Reference - -These APIs are available from your platform's server-side Sentry SDK. - -### `openTelemetryIntegration()` - -This integration takes no options, reports its name as `OpenTelemetry`, and is not enabled by default. It attaches the active OpenTelemetry span's trace ID and span ID to Sentry errors, logs, metrics, and cron check-ins. It does not create or export spans. - -An active Sentry span takes precedence over the OpenTelemetry span. If there is no active OpenTelemetry span, or its span context is invalid, Sentry uses its own trace context. - -### `getOtlpTracesEndpoint(dsn)` - -Pass a Sentry DSN string to get configuration for an OpenTelemetry HTTP trace exporter: - -| Field | Type | Description | -| --------- | ------------------------ | -------------------------------------------------- | -| `url` | `string` | The project's Sentry OTLP traces endpoint. | -| `headers` | `Record` | Authentication headers, including `X-Sentry-Auth`. | - -The helper returns `undefined` if the DSN cannot be parsed. It does not register a provider or send spans. - -## Migrate from v10 - -Replace `skipOpenTelemetrySetup: true` with `enableOpenTelemetrySetup: false`. Remove `SentryContextManager`, `SentryPropagator`, `SentrySampler`, `SentrySpanProcessor`, `wrapSamplingDecision`, and `validateOpenTelemetrySetup` from your custom setup. Your OpenTelemetry pipeline now owns context management, propagation, sampling, and export. - -`openTelemetryIntegration()` replaces `otlpIntegration()` from `@sentry/node-core/light/otlp`. Import it from your platform's Sentry SDK. The `setupOtlpTracesExporter` and `collectorUrl` options were removed; configure your exporter directly instead. +The Sentry SDK does not register OpenTelemetry ESM loader hooks. If your OpenTelemetry instrumentation needs them, [register OpenTelemetry's ESM loader hooks](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm) before loading the modules you want to instrument. diff --git a/docs/platforms/javascript/common/opentelemetry/index__v10.x.mdx b/docs/platforms/javascript/common/opentelemetry/index__v10.x.mdx new file mode 100644 index 0000000000000..57eb7542bc1b9 --- /dev/null +++ b/docs/platforms/javascript/common/opentelemetry/index__v10.x.mdx @@ -0,0 +1,41 @@ +--- +title: OpenTelemetry Support +description: "Learn how to use OpenTelemetry with Sentry." +sidebar_order: 14 +sidebar_section: configuration +supported: + - javascript.nextjs + - javascript.node + - javascript.eve + - javascript.aws-lambda + - javascript.azure-functions + - javascript.bun + - javascript.connect + - javascript.express + - javascript.fastify + - javascript.gcp-functions + - javascript.hapi + - javascript.hono + - javascript.koa + - javascript.nestjs + - javascript.nitro + - javascript.nuxt + - javascript.solidstart + - javascript.sveltekit + - javascript.astro + - javascript.remix + - javascript.react-router + - javascript.tanstackstart-react +notSupported: + - javascript +beta: true +--- + +The Sentry SDK uses [OpenTelemetry](https://opentelemetry.io/) under the hood. This means that any OpenTelemetry instrumentation that emits spans will automatically be picked up by Sentry without any further configuration. + +To start capturing traces and spans, set up Tracing and Performance Monitoring with your Sentry SDK. If you don't use tracing, Sentry still connects to OpenTelemetry under the hood to ensure that context isolation and trace propagation works correctly. + +By default, Sentry will automatically set up OpenTelemetry for you, but you can also use your own OpenTelemetry setup. Read the guides below to learn how to use a custom OpenTelemetry setup or how to get the most out of the Sentry and OpenTelemetry integration. + +- Using Your Existing OpenTelemetry Setup +- Using OpenTelemetry APIs diff --git a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis__v10.x.mdx b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis__v10.x.mdx new file mode 100644 index 0000000000000..d114441401a19 --- /dev/null +++ b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis__v10.x.mdx @@ -0,0 +1,152 @@ +--- +title: Using OpenTelemetry APIs +description: "Learn how to use OpenTelemetry APIs with Sentry." +supported: + - javascript.nextjs + - javascript.node + - javascript.eve + - javascript.aws-lambda + - javascript.azure-functions + - javascript.bun + - javascript.connect + - javascript.express + - javascript.fastify + - javascript.gcp-functions + - javascript.hapi + - javascript.hono + - javascript.koa + - javascript.nestjs + - javascript.nitro + - javascript.nuxt + - javascript.solidstart + - javascript.sveltekit + - javascript.astro + - javascript.remix + - javascript.react-router + - javascript.tanstackstart-react +notSupported: + - javascript +sidebar_order: 1 +--- + +Sentry supports OpenTelemetry APIs out of the box. Any spans started using OpenTelemetry APIs will be automatically captured by Sentry, while any spans started using the Sentry SDK will be automatically propagated to OpenTelemetry. + +## Adding Additional OpenTelemetry Instrumentation + +While the Sentry SDK includes some OpenTelemetry instrumentation out of the box, you may want to add additional instrumentation to your application. This can be done by registering the instrumentation through OpenTelemetry like the example below: + +```javascript {tabTitle: ESM} {12-13} +import * as Sentry from "@sentry/node"; +import { + GenericPoolInstrumentation, +} from "@opentelemetry/instrumentation-generic-pool"; + +Sentry.init({ + dsn: "___DSN___", + + // The SentrySampler will use this to determine which traces to sample + tracesSampleRate: 1.0, + + // Add additional OpenTelemetry instrumentation: + openTelemetryInstrumentations: [new GenericPoolInstrumentation()], +}); +``` +```javascript {tabTitle: CJS} {12-13} +const Sentry = require("@sentry/node"); +const { + GenericPoolInstrumentation, +} = require("@opentelemetry/instrumentation-generic-pool"); + +Sentry.init({ + dsn: "___DSN___", + + // The SentrySampler will use this to determine which traces to sample + tracesSampleRate: 1.0, + + // Add additional OpenTelemetry instrumentation: + openTelemetryInstrumentations: [new GenericPoolInstrumentation()], +}); +``` + + + It is possible to add instrumentations via `registerInstrumentations()` from + `@opentelemetry/instrumentation`. However, with ESM (`import`/`export` syntax) + you need to be careful to do so before importing any modules that should be + instrumented. + +As a rule of thumb, `registerInstrumentations()` should be called right after, and in the same context as registering ESM Loaders. + + + +## Using an OpenTelemetry Tracer + +We recommend using `Sentry.startSpan()` and related APIs to create spans, but you can also create spans using native OpenTelemetry APIs. + +You can access the tracer Sentry uses via `client.tracer` and then create spans with OpenTelemetry APIs, as shown below: + +```javascript {tabTitle: ESM} +import * as Sentry from "@sentry/node"; + +const tracer = Sentry.getClient()?.tracer; +// Now you can use native APIs on the tracer: +tracer.startActiveSpan("span name", () => { + // measure something +}); +``` +```javascript {tabTitle: CJS} +const Sentry = require("@sentry/node"); + +const tracer = Sentry.getClient()?.tracer; +// Now you can use native APIs on the tracer: +tracer.startActiveSpan("span name", () => { + // measure something +}); +``` + +You can also use any other tracer. All OpenTelemetry spans will be picked up by Sentry automatically. + +## Modifying the default OpenTelemetry TracerProvider + +You can access the tracer provider set up by Sentry when using Sentry's default OpenTelemetry instrumentation. + +```javascript {tabTitle: ESM} +import * as Sentry from "@sentry/node"; + +const provider = Sentry.getClient()?.traceProvider; +``` +```javascript {tabTitle: CJS} +const Sentry = require("@sentry/node"); + +const provider = Sentry.getClient()?.traceProvider; +``` + +## Adding Additional Span Processors + +You can add additional span processors to the tracer provider set up by Sentry when using Sentry's default OpenTelemetry instrumentation. + +```javascript {tabTitle: ESM} +import * as Sentry from "@sentry/node"; + +Sentry.init({ + dsn: "___DSN___", + + // The SentrySampler will use this to determine which traces to sample + tracesSampleRate: 1.0, + + // Add additional OpenTelemetry SpanProcessors: + openTelemetrySpanProcessors: [new MySpanProcessor()], +}); +``` +```javascript {tabTitle: CJS} +const Sentry = require("@sentry/node"); + +Sentry.init({ + dsn: "___DSN___", + + // The SentrySampler will use this to determine which traces to sample + tracesSampleRate: 1.0, + + // Add additional OpenTelemetry SpanProcessors: + openTelemetrySpanProcessors: [new MySpanProcessor()], +}); +``` diff --git a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun__v10.x.mdx b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun__v10.x.mdx new file mode 100644 index 0000000000000..6119cfb7459cf --- /dev/null +++ b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript.bun__v10.x.mdx @@ -0,0 +1,49 @@ +```javascript +import * as Sentry from "@sentry/bun"; +import { SentryContextManager } from "@sentry/node-core"; +import { SentryPropagator, SentrySampler } from "@sentry/opentelemetry"; + +import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; +import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; +import { OTLPTraceExporter } from "@opentelemetry/exporter-otlp-http"; +import { registerInstrumentations } from "@opentelemetry/instrumentation"; + +const sentryClient = Sentry.init({ + dsn: "___DSN___", + // Skipping the OpenTelemetry setup automatically disables emitting spans in the httpIntegration with `spans: false` + skipOpenTelemetrySetup: true, + + // Important: We do not define a tracesSampleRate here at all! + // This leads to tracing being disabled + + integrations: (integrations) => + // Filter out the BunServer integration to avoid emitting spans from there + integrations.filter((i) => i.name !== "BunServer") +}); + +// Create and configure e.g. NodeTracerProvider +const provider = new NodeTracerProvider({ + // This ensures trace propagation works as expected + sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, +}); + +provider.addSpanProcessor( + new BatchSpanProcessor( + new OTLPTraceExporter({ + url: "http://OTLP-ENDPOINT.com/api", + }) + ) +); + +// Initialize the provider +provider.register({ + propagator: new SentryPropagator(), + contextManager: new SentryContextManager(), +}); + +registerInstrumentations({ + instrumentations: [ + // Add OTEL instrumentation here + ], +}); +``` diff --git a/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript__v10.x.mdx b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript__v10.x.mdx new file mode 100644 index 0000000000000..5f03de4bd1cab --- /dev/null +++ b/platform-includes/performance/opentelemetry-setup/error-monitoring-only/javascript__v10.x.mdx @@ -0,0 +1,88 @@ +```javascript {tabTitle: ESM} +import * as Sentry from "@sentry/node"; +import { SentryPropagator, SentrySampler } from "@sentry/opentelemetry"; + +import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; +import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; +import { OTLPTraceExporter } from "@opentelemetry/exporter-otlp-http"; +import { registerInstrumentations } from "@opentelemetry/instrumentation"; + +const sentryClient = Sentry.init({ + dsn: "___DSN___", + // Skipping the OpenTelemetry setup automatically disables emitting spans in the httpIntegration with `spans: false` + skipOpenTelemetrySetup: true, + + // Important: We do not define a tracesSampleRate here at all! + // This leads to tracing being disabled +}); + +// Create and configure e.g. NodeTracerProvider +const provider = new NodeTracerProvider({ + // This ensures trace propagation works as expected + sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, +}); + +provider.addSpanProcessor( + new BatchSpanProcessor( + new OTLPTraceExporter({ + url: "http://OTLP-ENDPOINT.com/api", + }) + ) +); + +// Initialize the provider +provider.register({ + propagator: new SentryPropagator(), + contextManager: new Sentry.SentryContextManager(), +}); + +registerInstrumentations({ + instrumentations: [ + // Add OTEL instrumentation here + ], +}); +``` +```javascript {tabTitle: CJS} +const Sentry = require("@sentry/node"); +const { SentryPropagator, SentrySampler } = require("@sentry/opentelemetry"); + +const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); +const { BatchSpanProcessor } = require("@opentelemetry/sdk-trace-base"); +const { OTLPTraceExporter } = require("@opentelemetry/exporter-otlp-http"); +const { registerInstrumentations } = require("@opentelemetry/instrumentation"); + +const sentryClient = Sentry.init({ + dsn: "___DSN___", + // Skipping the OpenTelemetry setup automatically disables emitting spans in the httpIntegration with `spans: false` + skipOpenTelemetrySetup: true, + + // Important: We do not define a tracesSampleRate here at all! + // This leads to tracing being disabled +}); + +// Create and configure e.g. NodeTracerProvider +const provider = new NodeTracerProvider({ + // This ensures trace propagation works as expected + sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, +}); + +provider.addSpanProcessor( + new BatchSpanProcessor( + new OTLPTraceExporter({ + url: "http://OTLP-ENDPOINT.com/api", + }) + ) +); + +// Initialize the provider +provider.register({ + propagator: new SentryPropagator(), + contextManager: new Sentry.SentryContextManager(), +}); + +registerInstrumentations({ + instrumentations: [ + // Add OTEL instrumentation here + ], +}); +``` diff --git a/platform-includes/performance/opentelemetry-setup/javascript.bun__v10.x.mdx b/platform-includes/performance/opentelemetry-setup/javascript.bun__v10.x.mdx new file mode 100644 index 0000000000000..8a9c210fb0eba --- /dev/null +++ b/platform-includes/performance/opentelemetry-setup/javascript.bun__v10.x.mdx @@ -0,0 +1,86 @@ +To use an existing OpenTelemetry setup, set `skipOpenTelemetrySetup: true` in your `init({})` config, then set up all the components that Sentry needs yourself. Finish by installing `@sentry/opentelemetry` and adding the following: + +```javascript {tabTitle: NodeTracerProvider} +import * as Sentry from "@sentry/bun"; +import { SentryContextManager, validateOpenTelemetrySetup } from "@sentry/node-core"; +import { SentrySpanProcessor, SentryPropagator, SentrySampler } from "@sentry/opentelemetry"; + +import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; + +const sentryClient = Sentry.init({ + dsn: "___DSN___", + skipOpenTelemetrySetup: true, + + // The SentrySampler will use this to determine which traces to sample + tracesSampleRate: 1.0, + // Filter out the BunServer integration in case you want to avoid sending spans from there: + // integrations: (integrations) => + // integrations.filter((i) => i.name !== "BunServer") +}); + +// Note: This could be BasicTracerProvider or any other provider depending on +// how you are using the OpenTelemetry SDK +const provider = new NodeTracerProvider({ + // Ensure the correct subset of traces is sent to Sentry + // This also ensures trace propagation works as expected + sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, + spanProcessors: [ + // Ensure spans are correctly linked & sent to Sentry + new SentrySpanProcessor(), + // Add additional processors here + ], +}); + +provider.register({ + // Ensure trace propagation works + // This relies on the SentrySampler for correct propagation + propagator: new SentryPropagator(), + // Ensure context & request isolation are correctly managed + contextManager: new SentryContextManager(), +}); + +// Validate that the setup is correct +validateOpenTelemetrySetup(); +``` + +```javascript {tabTitle: NodeSDK} +import * as Sentry from "@sentry/bun"; +import { SentryContextManager, validateOpenTelemetrySetup } from "@sentry/node-core"; +import { SentryPropagator, SentrySampler } from "@sentry/opentelemetry"; + +import { NodeSDK } from "@opentelemetry/sdk-node"; + +const sentryClient = Sentry.init({ + dsn: "___PUBLIC_DSN___", + skipOpenTelemetrySetup: true, + + // The SentrySampler will use this to determine which traces to sample + tracesSampleRate: 1.0, + // Filter out the BunServer integration in case you want to avoid sending spans from there: + // integrations: (integrations) => + // integrations.filter((i) => i.name !== "BunServer") +}); + +const sdk = new NodeSDK({ + // Ensure the correct subset of traces is sent to Sentry + // This also ensures trace propagation works as expected + sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, + spanProcessors: [ + // Ensure spans are correctly linked & sent to Sentry + new SentrySpanProcessor(), + // Add additional processors here + ], + // Ensure trace propagation works + // This relies on the SentrySampler for correct propagation + textMapPropagator: new SentryPropagator(), + // Ensure context & request isolation are correctly managed + contextManager: new SentryContextManager() +}); + +sdk.start(); + +// Validate that the setup is correct +validateOpenTelemetrySetup(); +``` + +Make sure that all [Required OpenTelemetry Instrumentation](#required-instrumentation) is set up correctly. Otherwise, the Sentry SDK may not work as expected. diff --git a/platform-includes/performance/opentelemetry-setup/javascript__v10.x.mdx b/platform-includes/performance/opentelemetry-setup/javascript__v10.x.mdx new file mode 100644 index 0000000000000..70515a91aa4d2 --- /dev/null +++ b/platform-includes/performance/opentelemetry-setup/javascript__v10.x.mdx @@ -0,0 +1,78 @@ +To use an existing OpenTelemetry setup, set `skipOpenTelemetrySetup: true` in your `init({})` config, then set up all the components that Sentry needs yourself. Finish by installing `@sentry/opentelemetry` and adding the following: + +```javascript {tabTitle: NodeTracerProvider} +const Sentry = require("@sentry/node"); +const { SentrySpanProcessor, SentryPropagator, SentrySampler } = require("@sentry/opentelemetry"); + +const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); + +const sentryClient = Sentry.init({ + dsn: "___DSN___", + skipOpenTelemetrySetup: true, + + // The SentrySampler will use this to determine which traces to sample + tracesSampleRate: 1.0, +}); + +// Note: This could be BasicTracerProvider or any other provider depending on +// how you are using the OpenTelemetry SDK +const provider = new NodeTracerProvider({ + // Ensure the correct subset of traces is sent to Sentry + // This also ensures trace propagation works as expected + sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, + spanProcessors: [ + // Ensure spans are correctly linked & sent to Sentry + new SentrySpanProcessor(), + // Add additional processors here + ], +}); + +provider.register({ + // Ensure trace propagation works + // This relies on the SentrySampler for correct propagation + propagator: new SentryPropagator(), + // Ensure context & request isolation are correctly managed + contextManager: new Sentry.SentryContextManager(), +}); + +// Validate that the setup is correct +Sentry.validateOpenTelemetrySetup(); +``` + +```javascript {tabTitle: NodeSDK} +const Sentry = require("@sentry/node"); + +const { NodeSDK } = require("@opentelemetry/sdk-node") +const { SentrySpanProcessor, SentryPropagator, SentrySampler } = require("@sentry/opentelemetry"); + +const sentryClient = Sentry.init({ + dsn: "___PUBLIC_DSN___", + skipOpenTelemetrySetup: true, + + // The SentrySampler will use this to determine which traces to sample + tracesSampleRate: 1.0, +}); + +const sdk = new NodeSDK({ + // Ensure the correct subset of traces is sent to Sentry + // This also ensures trace propagation works as expected + sampler: sentryClient ? new SentrySampler(sentryClient) : undefined, + spanProcessors: [ + // Ensure spans are correctly linked & sent to Sentry + new SentrySpanProcessor(), + // Add additional processors here + ], + // Ensure trace propagation works + // This relies on the SentrySampler for correct propagation + textMapPropagator: new SentryPropagator(), + // Ensure context & request isolation are correctly managed + contextManager: new Sentry.SentryContextManager() +}); + +sdk.start(); + +// Validate that the setup is correct +Sentry.validateOpenTelemetrySetup(); +``` + +Make sure that all [Required OpenTelemetry Instrumentation](#required-instrumentation) is set up correctly. Otherwise, the Sentry SDK may not work as expected. diff --git a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun__v10.x.mdx b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun__v10.x.mdx new file mode 100644 index 0000000000000..5604a57c79512 --- /dev/null +++ b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript.bun__v10.x.mdx @@ -0,0 +1,43 @@ +```javascript +import * as Sentry from "@sentry/bun"; +import { validateOpenTelemetrySetup } from "@sentry/node-core"; +import { wrapSamplingDecision } from "@sentry/opentelemetry"; +import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; + +// implements Sampler from "@opentelemetry/sdk-trace-node" +class CustomSampler { + shouldSample(context, _traceId, _spanName, _spanKind, attributes, _links) { + const decision = yourDecisionLogic(); + + // wrap the result + return wrapSamplingDecision({ + decision, + context, + spanAttributes: attributes, + }); + } + + toString() { + return CustomSampler.name; + } +} + +const sentryClient = Sentry.init({ + dsn: "___DSN___", + skipOpenTelemetrySetup: true, + + // By defining any sample rate, + // tracing integrations will be added by default + // omit this if you do not want any performance integrations to be added + tracesSampleRate: 0, +}); + +const provider = new NodeTracerProvider({ + sampler: new CustomSampler(), +}); + +// ...rest of your setup + +// Validate that the setup is correct +validateOpenTelemetrySetup(); +``` diff --git a/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript__v10.x.mdx b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript__v10.x.mdx new file mode 100644 index 0000000000000..af76cec370154 --- /dev/null +++ b/platform-includes/performance/opentelemetry-setup/with-custom-sampler/javascript__v10.x.mdx @@ -0,0 +1,100 @@ +```javascript {tabTitle: ESM} +import * as Sentry from "@sentry/node"; +import { wrapSamplingDecision } from "@sentry/opentelemetry"; +import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; + +// implements Sampler from "@opentelemetry/sdk-trace-node" +class CustomSampler { + shouldSample(context, _traceId, _spanName, _spanKind, attributes, _links) { + const decision = yourDecisionLogic(); + + // wrap the result + return wrapSamplingDecision({ + decision, + context, + spanAttributes: attributes, + }); + } + + toString() { + return CustomSampler.name; + } +} + +const sentryClient = Sentry.init({ + dsn: "___DSN___", + skipOpenTelemetrySetup: true, + + // By defining any sample rate, + // tracing integrations will be added by default + // omit this if you do not want any performance integrations to be added + tracesSampleRate: 0, +}); + +const provider = new NodeTracerProvider({ + sampler: new CustomSampler(), +}); + +// ...rest of your setup + +// Validate that the setup is correct +Sentry.validateOpenTelemetrySetup(); +``` +```javascript {tabTitle: CJS} +const Sentry = require("@sentry/node"); +const { wrapSamplingDecision } = require("@sentry/opentelemetry"); +const { NodeTracerProvider } = require("@opentelemetry/sdk-trace-node"); + +// implements Sampler from "@opentelemetry/sdk-trace-node" +class CustomSampler { + shouldSample(context, _traceId, _spanName, _spanKind, attributes, _links) { + const decision = yourDecisionLogic(); + + // wrap the result + return wrapSamplingDecision({ + decision, + context, + spanAttributes: attributes, + }); + } + + toString() { + return CustomSampler.name; + } +} + +const sentryClient = Sentry.init({ + dsn: "___DSN___", + skipOpenTelemetrySetup: true, + + // By defining any sample rate, + // tracing integrations will be added by default + // omit this if you do not want any performance integrations to be added + tracesSampleRate: 0, +}); + +const provider = new NodeTracerProvider({ + sampler: new CustomSampler(), +}); + +// ...rest of your setup + +// Validate that the setup is correct +Sentry.validateOpenTelemetrySetup(); +``` + +## ESM Loaders + +If your application is running in ESM (`import`/`export` syntax), OpenTelemetry requires you to set up _ESM loader hooks_. + +The Sentry SDK will automatically register ESM loader hooks by default. +However, if you have your own OpenTelemetry setup, it is recommended to configure the Sentry SDK to not register these hooks and instead register them yourself. +You can do so by setting `registerEsmLoaderHooks` to `false` and [setting up ESM loader hooks](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm): + +```javascript +Sentry.init({ + dsn: "___DSN___", + skipOpenTelemetrySetup: true, + registerEsmLoaderHooks: false, +}); +``` diff --git a/redirects.js b/redirects.js index e8050a4173383..92e00e978c72c 100644 --- a/redirects.js +++ b/redirects.js @@ -609,11 +609,12 @@ const userDocsRedirects = [ { source: '/platforms/javascript/guides/:guide/opentelemetry/integration/', destination: - '/platforms/javascript/guides/:guide/opentelemetry/#api-reference', + '/platforms/javascript/guides/:guide/configuration/integrations/opentelemetry/', }, { source: '/platforms/javascript/guides/:guide/opentelemetry/integration.md', - destination: '/platforms/javascript/guides/:guide/opentelemetry.md', + destination: + '/platforms/javascript/guides/:guide/configuration/integrations/opentelemetry.md', }, // Guides → Get Started restructure diff --git a/src/components/docPage/type.scss b/src/components/docPage/type.scss index 93bf779ebd626..cebbf6c628349 100644 --- a/src/components/docPage/type.scss +++ b/src/components/docPage/type.scss @@ -218,6 +218,23 @@ } + // Opt in when all columns contain prose and need to share the available width. + .table-wrap table { + display: table; + table-layout: fixed; + + td, + th { + min-width: 0; + white-space: normal; + overflow-wrap: anywhere; + + code { + white-space: normal; + } + } + } + // Override for compact tables that don't need min-width .table-fit-content table { td:last-child, From b88e22bfed6909be25d269f20a17cee3a49d2c17 Mon Sep 17 00:00:00 2001 From: Martin Sonnberger Date: Tue, 22 Sep 2026 11:29:49 +0200 Subject: [PATCH 05/10] docs(javascript): Split OpenTelemetry guides by tracing setup --- .../integrations/opentelemetry.mdx | 4 +- .../common/opentelemetry/custom-setup.mdx | 104 ++++++++++++++ .../javascript/common/opentelemetry/index.mdx | 136 +----------------- .../using-opentelemetry-apis.mdx | 58 ++++++++ redirects.js | 18 --- src/components/docPage/type.scss | 17 --- 6 files changed, 168 insertions(+), 169 deletions(-) create mode 100644 docs/platforms/javascript/common/opentelemetry/custom-setup.mdx create mode 100644 docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx diff --git a/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx b/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx index 884265525596f..5d4c656e5c384 100644 --- a/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx @@ -60,7 +60,7 @@ An active Sentry span takes precedence over the OpenTelemetry span. If there is no active OpenTelemetry span, or its span context is invalid, Sentry uses its own trace context. -For exporter examples, sampling, and trace propagation, see the OpenTelemetry setup guide. +For exporter examples, sampling, and trace propagation, see the OpenTelemetry setup guide. ## `getOtlpTracesEndpoint` @@ -88,4 +88,4 @@ if (!endpoint) { const exporter = new OTLPTraceExporter(endpoint); ``` -Add this exporter to your existing provider with a `BatchSpanProcessor`, as shown in the OTLP setup examples. If you only want to associate Sentry errors with traces exported elsewhere, keep your existing exporter and omit this helper. +Add this exporter to your existing provider with a `BatchSpanProcessor`, as shown in the OTLP setup examples. If you only want to associate Sentry errors with traces exported elsewhere, keep your existing exporter and omit this helper. diff --git a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx new file mode 100644 index 0000000000000..fefc54627e1d5 --- /dev/null +++ b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx @@ -0,0 +1,104 @@ +--- +title: Use Your Own OpenTelemetry Pipeline +description: "For applications that manage their own OpenTelemetry provider, instrumentation, and exporters. Set enableOpenTelemetrySetup to false, leave Sentry tracing off, add openTelemetryIntegration for trace correlation, and use your exporter to send spans to Sentry over OTLP." +sidebar_order: 1 +supported: + - javascript.nextjs + - javascript.node + - javascript.eve + - javascript.mastra + - javascript.aws-lambda + - javascript.azure-functions + - javascript.bun + - javascript.connect + - javascript.express + - javascript.fastify + - javascript.gcp-functions + - javascript.hapi + - javascript.hono + - javascript.koa + - javascript.nestjs + - javascript.nitro + - javascript.nuxt + - javascript.solidstart + - javascript.sveltekit + - javascript.astro + - javascript.remix + - javascript.react-router + - javascript.tanstackstart-react +notSupported: + - javascript +--- + +Keep your own provider, context manager, propagator, instrumentation, and exporters when OpenTelemetry manages tracing. Add `Sentry.openTelemetryIntegration()` to associate Sentry errors, logs, metrics, and cron check-ins with the active OpenTelemetry span. + +Set `enableOpenTelemetrySetup: false` and leave both `tracesSampleRate` and `tracesSampler` unset. This disables Sentry tracing and prevents duplicate spans for the same operations. Sentry's instrumentation still isolates requests and captures errors. + +Initialize your OpenTelemetry provider before calling `Sentry.init()`. If its configuration is in a separate file, import that file before initializing Sentry. Set `enableOpenTelemetrySetup: false` explicitly for Next.js and SvelteKit to override their defaults. + +## Send OpenTelemetry Spans to Sentry + +Add an OTLP exporter to your existing provider. Install `@opentelemetry/exporter-trace-otlp-http` if you do not already use it. `Sentry.getOtlpTracesEndpoint()` supplies the endpoint URL and authentication headers for your DSN. + +This example uses `NodeTracerProvider`. Add the same span processor to `spanProcessors` if you use `NodeSDK` instead. Keep your existing sampler, propagator, context manager, and instrumentation; do not register a second provider. + +```javascript {filename: instrument.mjs} +import * as Sentry from "___SDK_PACKAGE___"; +import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; +import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; +import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; + +const dsn = "___PUBLIC_DSN___"; +const endpoint = Sentry.getOtlpTracesEndpoint(dsn); + +if (!endpoint) { + throw new Error("Could not parse the Sentry DSN"); +} + +const provider = new NodeTracerProvider({ + spanProcessors: [ + new BatchSpanProcessor(new OTLPTraceExporter(endpoint)), + // Keep any other span processors you already use. + ], +}); + +provider.register(); + +Sentry.init({ + dsn, + enableOpenTelemetrySetup: false, + // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. + integrations: [Sentry.openTelemetryIntegration()], +}); +``` + +## Use Sentry for Error Monitoring Only + +If your traces go elsewhere, keep your existing OpenTelemetry exporter and omit the Sentry OTLP exporter from the example above. The `Sentry.init()` configuration stays the same. `openTelemetryIntegration()` links Sentry errors to the active OpenTelemetry trace without sending spans to Sentry. + +## Configure Sampling + +Configure sampling on your OpenTelemetry provider. Sentry's `tracesSampleRate` and `tracesSampler` do not control spans exported over OTLP. Use an OpenTelemetry sampler or your own implementation of its `Sampler` interface. + +For example, add this sampler to your provider configuration to respect the parent's sampling decision and sample 10% of new traces: + +```javascript +import { + ParentBasedSampler, + TraceIdRatioBasedSampler, +} from "@opentelemetry/sdk-trace-base"; + +const sampler = new ParentBasedSampler({ + root: new TraceIdRatioBasedSampler(0.1), +}); +``` + +## Configure Instrumentation and Propagation + +Register the OpenTelemetry instrumentation you need to create spans for incoming requests, outgoing requests, database queries, and other operations. Sentry's instrumentation does not create OpenTelemetry spans in v11. Keep Sentry's default integrations enabled for request isolation, errors, and breadcrumbs. + +With `openTelemetryIntegration()` enabled and Sentry tracing off, your OpenTelemetry propagator handles outgoing trace propagation. + +## ESM Loaders + +The Sentry SDK does not register OpenTelemetry ESM loader hooks. If your OpenTelemetry instrumentation needs them, [register OpenTelemetry's ESM loader hooks](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm) before loading the modules you want to instrument. diff --git a/docs/platforms/javascript/common/opentelemetry/index.mdx b/docs/platforms/javascript/common/opentelemetry/index.mdx index 4c710df276206..9416efde7d57a 100644 --- a/docs/platforms/javascript/common/opentelemetry/index.mdx +++ b/docs/platforms/javascript/common/opentelemetry/index.mdx @@ -1,5 +1,5 @@ --- -title: OpenTelemetry Interoperability +title: OpenTelemetry Support description: "Learn how to use OpenTelemetry with Sentry." sidebar_order: 14 sidebar_section: configuration @@ -31,136 +31,8 @@ notSupported: - javascript --- -The Sentry JavaScript SDK creates and sends spans without an OpenTelemetry pipeline. If your application also uses OpenTelemetry, choose a setup based on which SDK manages tracing. +The Sentry JavaScript SDK creates and sends spans without an OpenTelemetry pipeline. For the default setup, see Tracing. -
+If your application also uses OpenTelemetry, choose a setup based on which SDK manages tracing: -| Your setup | Configuration | How spans reach Sentry | -| ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | -| You use Sentry's automatic instrumentation and tracing APIs. | Keep the SDK defaults and enable Sentry tracing. | The Sentry SDK creates and sends spans. | -| Your code or a library creates spans through `@opentelemetry/api`, without its own OpenTelemetry provider. | Set `enableOpenTelemetrySetup: true` and enable Sentry tracing. | The SDK converts OpenTelemetry API spans into Sentry spans. | -| You manage your own OpenTelemetry provider, instrumentation, and exporters. | Set `enableOpenTelemetrySetup: false`, disable Sentry tracing, and add `openTelemetryIntegration()`. | Your OpenTelemetry exporter sends spans over OTLP. | - -
- -## Use Sentry Tracing - -Use the SDK defaults when you want Sentry to instrument your application and manage tracing. Create custom spans with `Sentry.startSpan()` and related APIs. - -```javascript -import * as Sentry from "___SDK_PACKAGE___"; - -Sentry.init({ - dsn: "___PUBLIC_DSN___", - // Adjust the sample rate for production. - tracesSampleRate: 1.0, -}); -``` - -Most server SDKs leave `enableOpenTelemetrySetup` off by default. They do not register an OpenTelemetry tracer provider or capture spans created through `@opentelemetry/api`. - -The `@sentry/nextjs` and `@sentry/sveltekit` SDKs enable OpenTelemetry setup by default to capture spans emitted by those frameworks. Keep that default when using Sentry tracing. - -See Tracing for setup and sampling options. - -## Capture Spans from OpenTelemetry APIs - -To capture spans that your code or a library creates through `@opentelemetry/api`, set `enableOpenTelemetrySetup: true`. Sentry registers an OpenTelemetry-compatible tracer provider, context manager, and propagator. Spans created through `@opentelemetry/api` become native Sentry spans. Sentry's tracing configuration controls sampling and export. - -```javascript -import * as Sentry from "___SDK_PACKAGE___"; -import { trace } from "@opentelemetry/api"; - -Sentry.init({ - dsn: "___PUBLIC_DSN___", - enableOpenTelemetrySetup: true, - tracesSampleRate: 1.0, -}); - -const tracer = trace.getTracer("my-app"); - -tracer.startActiveSpan("process-order", (span) => { - try { - // Your synchronous work here. - } finally { - span.end(); - } -}); -``` - -Initialize Sentry before the application creates spans. This setup sends spans through Sentry's transport; it does not create an OTLP exporter. If your application already registers an OpenTelemetry provider, use the next setup instead. Sentry will not replace an existing provider. - -## Run Your Own OpenTelemetry Pipeline - -Keep your own provider, context manager, propagator, instrumentation, and exporters when OpenTelemetry manages tracing. Add `Sentry.openTelemetryIntegration()` to associate Sentry errors, logs, metrics, and cron check-ins with the active OpenTelemetry span. - -Set `enableOpenTelemetrySetup: false` and leave both `tracesSampleRate` and `tracesSampler` unset. This disables Sentry tracing and prevents duplicate spans for the same operations. Sentry's instrumentation still isolates requests and captures errors. - -Initialize your OpenTelemetry provider before calling `Sentry.init()`. If its configuration is in a separate file, import that file before initializing Sentry. Set `enableOpenTelemetrySetup: false` explicitly for Next.js and SvelteKit to override their defaults. - -### Send OpenTelemetry Spans to Sentry - -Add an OTLP exporter to your existing provider. Install `@opentelemetry/exporter-trace-otlp-http` if you do not already use it. `Sentry.getOtlpTracesEndpoint()` supplies the endpoint URL and authentication headers for your DSN. - -This example uses `NodeTracerProvider`. Add the same span processor to `spanProcessors` if you use `NodeSDK` instead. Keep your existing sampler, propagator, context manager, and instrumentation; do not register a second provider. - -```javascript {filename: instrument.mjs} -import * as Sentry from "___SDK_PACKAGE___"; -import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; -import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; -import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; - -const dsn = "___PUBLIC_DSN___"; -const endpoint = Sentry.getOtlpTracesEndpoint(dsn); - -if (!endpoint) { - throw new Error("Could not parse the Sentry DSN"); -} - -const provider = new NodeTracerProvider({ - spanProcessors: [ - new BatchSpanProcessor(new OTLPTraceExporter(endpoint)), - // Keep any other span processors you already use. - ], -}); - -provider.register(); - -Sentry.init({ - dsn, - enableOpenTelemetrySetup: false, - // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. - integrations: [Sentry.openTelemetryIntegration()], -}); -``` - -### Use Sentry for Error Monitoring Only - -If your traces go elsewhere, keep your existing OpenTelemetry exporter and omit the Sentry OTLP exporter from the example above. The `Sentry.init()` configuration stays the same. `openTelemetryIntegration()` links Sentry errors to the active OpenTelemetry trace without sending spans to Sentry. - -### Configure Sampling - -Configure sampling on your OpenTelemetry provider. Sentry's `tracesSampleRate` and `tracesSampler` do not control spans exported over OTLP. Use an OpenTelemetry sampler or your own implementation of its `Sampler` interface. - -For example, add this sampler to your provider configuration to respect the parent's sampling decision and sample 10% of new traces: - -```javascript -import { - ParentBasedSampler, - TraceIdRatioBasedSampler, -} from "@opentelemetry/sdk-trace-base"; - -const sampler = new ParentBasedSampler({ - root: new TraceIdRatioBasedSampler(0.1), -}); -``` - -### Configure Instrumentation and Propagation - -Register the OpenTelemetry instrumentation you need to create spans for incoming requests, outgoing requests, database queries, and other operations. Sentry's instrumentation does not create OpenTelemetry spans in v11. Keep Sentry's default integrations enabled for request isolation, errors, and breadcrumbs. - -With `openTelemetryIntegration()` enabled and Sentry tracing off, your OpenTelemetry propagator handles outgoing trace propagation. - -### ESM Loaders - -The Sentry SDK does not register OpenTelemetry ESM loader hooks. If your OpenTelemetry instrumentation needs them, [register OpenTelemetry's ESM loader hooks](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm) before loading the modules you want to instrument. + diff --git a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx new file mode 100644 index 0000000000000..7445605d3dd91 --- /dev/null +++ b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx @@ -0,0 +1,58 @@ +--- +title: Capture Spans from OpenTelemetry APIs +description: "For code or libraries that use OpenTelemetry APIs without their own provider. Set enableOpenTelemetrySetup to true and enable Sentry tracing to capture these spans and send them through Sentry." +sidebar_order: 0 +supported: + - javascript.nextjs + - javascript.node + - javascript.eve + - javascript.mastra + - javascript.aws-lambda + - javascript.azure-functions + - javascript.bun + - javascript.connect + - javascript.express + - javascript.fastify + - javascript.gcp-functions + - javascript.hapi + - javascript.hono + - javascript.koa + - javascript.nestjs + - javascript.nitro + - javascript.nuxt + - javascript.solidstart + - javascript.sveltekit + - javascript.astro + - javascript.remix + - javascript.react-router + - javascript.tanstackstart-react +notSupported: + - javascript +--- + +To capture spans that your code or a library creates through `@opentelemetry/api`, set `enableOpenTelemetrySetup: true`. Sentry registers an OpenTelemetry-compatible tracer provider, context manager, and propagator. Spans created through `@opentelemetry/api` become native Sentry spans. Sentry's tracing configuration controls sampling and export. + +```javascript +import * as Sentry from "___SDK_PACKAGE___"; +import { trace } from "@opentelemetry/api"; + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + enableOpenTelemetrySetup: true, + tracesSampleRate: 1.0, +}); + +const tracer = trace.getTracer("my-app"); + +tracer.startActiveSpan("process-order", (span) => { + try { + // Your synchronous work here. + } finally { + span.end(); + } +}); +``` + +Initialize Sentry before the application creates spans. This setup sends spans through Sentry's transport; it does not create an OTLP exporter. If your application already registers an OpenTelemetry provider, use your own OpenTelemetry pipeline instead. Sentry will not replace an existing provider. + +Most server SDKs leave `enableOpenTelemetrySetup` off by default. The `@sentry/nextjs` and `@sentry/sveltekit` SDKs enable it by default to capture spans emitted by those frameworks. diff --git a/redirects.js b/redirects.js index 92e00e978c72c..c886196053f4d 100644 --- a/redirects.js +++ b/redirects.js @@ -588,24 +588,6 @@ const developerDocsRedirects = [ /** @type {import('next/dist/lib/load-custom-routes').Redirect[]} */ const userDocsRedirects = [ - { - source: '/platforms/javascript/guides/:guide/opentelemetry/custom-setup/', - destination: - '/platforms/javascript/guides/:guide/opentelemetry/#run-your-own-opentelemetry-pipeline', - }, - { - source: '/platforms/javascript/guides/:guide/opentelemetry/custom-setup.md', - destination: '/platforms/javascript/guides/:guide/opentelemetry.md', - }, - { - source: '/platforms/javascript/guides/:guide/opentelemetry/using-opentelemetry-apis/', - destination: - '/platforms/javascript/guides/:guide/opentelemetry/#capture-spans-from-opentelemetry-apis', - }, - { - source: '/platforms/javascript/guides/:guide/opentelemetry/using-opentelemetry-apis.md', - destination: '/platforms/javascript/guides/:guide/opentelemetry.md', - }, { source: '/platforms/javascript/guides/:guide/opentelemetry/integration/', destination: diff --git a/src/components/docPage/type.scss b/src/components/docPage/type.scss index cebbf6c628349..93bf779ebd626 100644 --- a/src/components/docPage/type.scss +++ b/src/components/docPage/type.scss @@ -218,23 +218,6 @@ } - // Opt in when all columns contain prose and need to share the available width. - .table-wrap table { - display: table; - table-layout: fixed; - - td, - th { - min-width: 0; - white-space: normal; - overflow-wrap: anywhere; - - code { - white-space: normal; - } - } - } - // Override for compact tables that don't need min-width .table-fit-content table { td:last-child, From f729eb4a10818ad825d9b6c0746c5f9a425ab2cf Mon Sep 17 00:00:00 2001 From: Martin Sonnberger Date: Tue, 22 Sep 2026 11:41:35 +0200 Subject: [PATCH 06/10] docs(javascript): Shorten OpenTelemetry setup descriptions --- docs/platforms/javascript/common/opentelemetry/custom-setup.mdx | 2 +- .../common/opentelemetry/using-opentelemetry-apis.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx index fefc54627e1d5..f262f389c9a89 100644 --- a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx +++ b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx @@ -1,6 +1,6 @@ --- title: Use Your Own OpenTelemetry Pipeline -description: "For applications that manage their own OpenTelemetry provider, instrumentation, and exporters. Set enableOpenTelemetrySetup to false, leave Sentry tracing off, add openTelemetryIntegration for trace correlation, and use your exporter to send spans to Sentry over OTLP." +description: "Connect your existing OpenTelemetry pipeline to Sentry while keeping control of tracing." sidebar_order: 1 supported: - javascript.nextjs diff --git a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx index 7445605d3dd91..0a1db82c1b4f7 100644 --- a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx +++ b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx @@ -1,6 +1,6 @@ --- title: Capture Spans from OpenTelemetry APIs -description: "For code or libraries that use OpenTelemetry APIs without their own provider. Set enableOpenTelemetrySetup to true and enable Sentry tracing to capture these spans and send them through Sentry." +description: "Let Sentry capture and send spans created by OpenTelemetry APIs." sidebar_order: 0 supported: - javascript.nextjs From 1e8c39482cd3a9e604d47ad771c2ed5176f09440 Mon Sep 17 00:00:00 2001 From: Martin Sonnberger Date: Tue, 22 Sep 2026 12:01:27 +0200 Subject: [PATCH 07/10] docs(javascript): Explain OpenTelemetry instrumentation registration --- .../common/opentelemetry/using-opentelemetry-apis.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx index 0a1db82c1b4f7..c5ff80ccc6f71 100644 --- a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx +++ b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx @@ -56,3 +56,7 @@ tracer.startActiveSpan("process-order", (span) => { Initialize Sentry before the application creates spans. This setup sends spans through Sentry's transport; it does not create an OTLP exporter. If your application already registers an OpenTelemetry provider, use your own OpenTelemetry pipeline instead. Sentry will not replace an existing provider. Most server SDKs leave `enableOpenTelemetrySetup` off by default. The `@sentry/nextjs` and `@sentry/sveltekit` SDKs enable it by default to capture spans emitted by those frameworks. + +## Add OpenTelemetry Instrumentation + +To capture spans from additional libraries, register their instrumentation with `registerInstrumentations()` from `@opentelemetry/instrumentation`. With ESM, register instrumentation before importing the modules you want to instrument. From 6a7835e25318a1c321e9ad5561b21cc014f677d5 Mon Sep 17 00:00:00 2001 From: Martin Sonnberger Date: Tue, 22 Sep 2026 13:46:33 +0200 Subject: [PATCH 08/10] improve opentelemetryIntegration guide --- .../integrations/opentelemetry.mdx | 67 ++++++++++--------- 1 file changed, 36 insertions(+), 31 deletions(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx b/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx index 5d4c656e5c384..30d4efd757427 100644 --- a/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx @@ -1,6 +1,6 @@ --- title: OpenTelemetry -description: "Connect Sentry errors, logs, metrics, and crons to your OpenTelemetry traces with openTelemetryIntegration, and configure OTLP export with getOtlpTracesEndpoint." +description: "Connect Sentry to an OpenTelemetry setup that owns tracing." supported: - javascript.nextjs - javascript.node @@ -32,35 +32,55 @@ notSupported: _Import name: `Sentry.openTelemetryIntegration`_ -Use this integration when your application runs its own OpenTelemetry pipeline. It attaches the active OpenTelemetry span's trace ID and span ID to Sentry errors, logs, metrics, and cron check-ins. The integration reports its name as `OpenTelemetry` and takes no options. +This integration is not enabled by default. Use it when OpenTelemetry owns tracing in your application and you want Sentry's errors, logs, metrics, and check-ins to land on the same traces. -The integration does not create or export spans. Your OpenTelemetry SDK handles sampling, propagation, and export. To send those spans to Sentry, configure an OTLP exporter using [`getOtlpTracesEndpoint`](#getotlptracesendpoint). +Everything Sentry sends that carries trace information is attached to the OpenTelemetry span that's active when it happens, so it shows up on the same trace as the spans your OpenTelemetry SDK exports. Outgoing request propagation is left to your OpenTelemetry propagator. -## Setup +An active Sentry span still takes precedence, so this only changes what happens when Sentry has no span of its own. If there is no active OpenTelemetry span, or its span context is invalid, Sentry uses its own trace context. -This integration runs on the server and is not enabled by default. Import your OpenTelemetry configuration before initializing Sentry: + + +This integration sends no spans. To get your OpenTelemetry spans into Sentry, point your own exporter at Sentry's OTLP endpoint with `getOtlpTracesEndpoint()`, as shown below. + + + +## Configure + +This integration runs on the server and takes no options. Leave Sentry tracing off so the two pipelines stay separate. `getOtlpTracesEndpoint()` turns your DSN into the URL and authentication headers of Sentry's OTLP endpoint: ```javascript {filename: instrument.mjs} -import "./otel.config.mjs"; +import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http"; +import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base"; +import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; import * as Sentry from "___SDK_PACKAGE___"; +const dsn = "___PUBLIC_DSN___"; +const endpoint = Sentry.getOtlpTracesEndpoint(dsn); + +if (!endpoint) { + throw new Error("Could not parse the Sentry DSN"); +} + +const provider = new NodeTracerProvider({ + spanProcessors: [new BatchSpanProcessor(new OTLPTraceExporter(endpoint))], +}); + +provider.register(); + Sentry.init({ - dsn: "___PUBLIC_DSN___", + dsn, + // Leave the OpenTelemetry setup to your own provider. enableOpenTelemetrySetup: false, - // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns tracing. + // Leave tracesSampleRate and tracesSampler unset. OpenTelemetry owns spans. integrations: [Sentry.openTelemetryIntegration()], }); ``` -In this example, `otel.config.mjs` registers your existing OpenTelemetry provider, context manager, propagator, and instrumentation. In frameworks with their own instrumentation entry point, initialize OpenTelemetry there before calling `Sentry.init()`. +If you already have a provider, add the exporter to that provider instead of registering a second one. Initialize OpenTelemetry before calling `Sentry.init()`. In frameworks with their own instrumentation entry point, initialize both there in that order. -Keep `enableOpenTelemetrySetup` set to `false`. This is already the default except in `@sentry/nextjs` and `@sentry/sveltekit`. Leave `tracesSampleRate` and `tracesSampler` unset to keep Sentry tracing off. Your OpenTelemetry propagator handles outgoing trace propagation. +Keep `enableOpenTelemetrySetup` set to `false`. This is already the default except in `@sentry/nextjs` and `@sentry/sveltekit`. Leave `tracesSampleRate` and `tracesSampler` unset to keep Sentry tracing off. -An active Sentry span takes precedence over the OpenTelemetry span. - -If there is no active OpenTelemetry span, or its span context is invalid, Sentry uses its own trace context. - -For exporter examples, sampling, and trace propagation, see the OpenTelemetry setup guide. +For sampling and instrumentation guidance, see the OpenTelemetry setup guide. ## `getOtlpTracesEndpoint` @@ -73,19 +93,4 @@ For exporter examples, sampling, and trace propagation, see OTLP setup examples. If you only want to associate Sentry errors with traces exported elsewhere, keep your existing exporter and omit this helper. +Pass the result to `OTLPTraceExporter` and add it to your provider with a `BatchSpanProcessor`, as shown in the [configuration example](#configure). If you only want to associate Sentry errors with traces exported elsewhere, keep your existing exporter and omit this helper. From 4f65aaa09ea124e31e940d1bf503ade8865fd1d6 Mon Sep 17 00:00:00 2001 From: Martin Sonnberger Date: Tue, 22 Sep 2026 14:39:18 +0200 Subject: [PATCH 09/10] trim stuff --- .../integrations/opentelemetry.mdx | 4 +-- .../common/opentelemetry/custom-setup.mdx | 25 +------------------ .../using-opentelemetry-apis.mdx | 4 --- 3 files changed, 3 insertions(+), 30 deletions(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx b/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx index 30d4efd757427..5c38402902538 100644 --- a/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx @@ -78,9 +78,9 @@ Sentry.init({ If you already have a provider, add the exporter to that provider instead of registering a second one. Initialize OpenTelemetry before calling `Sentry.init()`. In frameworks with their own instrumentation entry point, initialize both there in that order. -Keep `enableOpenTelemetrySetup` set to `false`. This is already the default except in `@sentry/nextjs` and `@sentry/sveltekit`. Leave `tracesSampleRate` and `tracesSampler` unset to keep Sentry tracing off. +Set `enableOpenTelemetrySetup: false`. Leave `tracesSampleRate` and `tracesSampler` unset to keep Sentry tracing off. -For sampling and instrumentation guidance, see the OpenTelemetry setup guide. +For sampling guidance, see the OpenTelemetry setup guide. ## `getOtlpTracesEndpoint` diff --git a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx index f262f389c9a89..1ddb0459b298e 100644 --- a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx +++ b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx @@ -34,7 +34,7 @@ Keep your own provider, context manager, propagator, instrumentation, and export Set `enableOpenTelemetrySetup: false` and leave both `tracesSampleRate` and `tracesSampler` unset. This disables Sentry tracing and prevents duplicate spans for the same operations. Sentry's instrumentation still isolates requests and captures errors. -Initialize your OpenTelemetry provider before calling `Sentry.init()`. If its configuration is in a separate file, import that file before initializing Sentry. Set `enableOpenTelemetrySetup: false` explicitly for Next.js and SvelteKit to override their defaults. +Initialize your OpenTelemetry provider before calling `Sentry.init()`. If your OpenTelemetry configuration is in a separate file, import it before initializing Sentry. ## Send OpenTelemetry Spans to Sentry @@ -79,26 +79,3 @@ If your traces go elsewhere, keep your existing OpenTelemetry exporter and omit ## Configure Sampling Configure sampling on your OpenTelemetry provider. Sentry's `tracesSampleRate` and `tracesSampler` do not control spans exported over OTLP. Use an OpenTelemetry sampler or your own implementation of its `Sampler` interface. - -For example, add this sampler to your provider configuration to respect the parent's sampling decision and sample 10% of new traces: - -```javascript -import { - ParentBasedSampler, - TraceIdRatioBasedSampler, -} from "@opentelemetry/sdk-trace-base"; - -const sampler = new ParentBasedSampler({ - root: new TraceIdRatioBasedSampler(0.1), -}); -``` - -## Configure Instrumentation and Propagation - -Register the OpenTelemetry instrumentation you need to create spans for incoming requests, outgoing requests, database queries, and other operations. Sentry's instrumentation does not create OpenTelemetry spans in v11. Keep Sentry's default integrations enabled for request isolation, errors, and breadcrumbs. - -With `openTelemetryIntegration()` enabled and Sentry tracing off, your OpenTelemetry propagator handles outgoing trace propagation. - -## ESM Loaders - -The Sentry SDK does not register OpenTelemetry ESM loader hooks. If your OpenTelemetry instrumentation needs them, [register OpenTelemetry's ESM loader hooks](https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/esm-support.md#instrumentation-hook-required-for-esm) before loading the modules you want to instrument. diff --git a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx index c5ff80ccc6f71..0a1db82c1b4f7 100644 --- a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx +++ b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx @@ -56,7 +56,3 @@ tracer.startActiveSpan("process-order", (span) => { Initialize Sentry before the application creates spans. This setup sends spans through Sentry's transport; it does not create an OTLP exporter. If your application already registers an OpenTelemetry provider, use your own OpenTelemetry pipeline instead. Sentry will not replace an existing provider. Most server SDKs leave `enableOpenTelemetrySetup` off by default. The `@sentry/nextjs` and `@sentry/sveltekit` SDKs enable it by default to capture spans emitted by those frameworks. - -## Add OpenTelemetry Instrumentation - -To capture spans from additional libraries, register their instrumentation with `registerInstrumentations()` from `@opentelemetry/instrumentation`. With ESM, register instrumentation before importing the modules you want to instrument. From 155f8aab8fbb6ce64082e570ae05fc0db12f4147 Mon Sep 17 00:00:00 2001 From: Martin Sonnberger Date: Tue, 22 Sep 2026 14:51:10 +0200 Subject: [PATCH 10/10] more --- docs/platforms/javascript/common/opentelemetry/custom-setup.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx index 1ddb0459b298e..67d971413573a 100644 --- a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx +++ b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx @@ -34,7 +34,7 @@ Keep your own provider, context manager, propagator, instrumentation, and export Set `enableOpenTelemetrySetup: false` and leave both `tracesSampleRate` and `tracesSampler` unset. This disables Sentry tracing and prevents duplicate spans for the same operations. Sentry's instrumentation still isolates requests and captures errors. -Initialize your OpenTelemetry provider before calling `Sentry.init()`. If your OpenTelemetry configuration is in a separate file, import it before initializing Sentry. +Initialize your OpenTelemetry provider before calling `Sentry.init()`. ## Send OpenTelemetry Spans to Sentry