From 907549facc819628f9b39df00bf47aec48b51482 Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Thu, 17 Sep 2026 16:27:01 +0200 Subject: [PATCH 1/2] docs(js): Remove the lightweight mode page, document openTelemetryIntegration v11 has no lightweight mode. `@sentry/node-core` was merged back into `@sentry/node`, so `@sentry/node-core/light` no longer exists and the whole page described a setup that cannot be followed. The OTLP half of that page survives in a different form. The integration moved to the main export of every server SDK and was renamed to `openTelemetryIntegration()`, because it sends nothing over OTLP. Give it its own integration page covering what it does, the exporter wiring through `getOtlpTracesEndpoint()`, and the `enableOpenTelemetrySetup` caveat for `@sentry/nextjs` and `@sentry/sveltekit`. The removed `setupOtlpTracesExporter` and `collectorUrl` options are not carried over: you configure the exporter yourself now. - Drop the lightweight entry from the installation methods page. - Point the "simpler way to bridge your existing setup" line on the custom OpenTelemetry setup page at the new integration. - Point the Node.js card on the OTLP concepts page there too. - Redirect `/install/lightweight/` to the new page for the seven guides that served it. Refs SDK-1352 Co-Authored-By: Claude Opus 5 --- docs/concepts/otlp/sentry-with-otel.mdx | 2 +- .../integrations/opentelemetry.mdx | 88 ++++++++ .../javascript/common/install/index.mdx | 4 - .../javascript/common/install/lightweight.mdx | 211 ------------------ .../common/opentelemetry/custom-setup.mdx | 2 +- redirects.js | 44 +++- 6 files changed, 128 insertions(+), 223 deletions(-) create mode 100644 docs/platforms/javascript/common/configuration/integrations/opentelemetry.mdx delete mode 100644 docs/platforms/javascript/common/install/lightweight.mdx diff --git a/docs/concepts/otlp/sentry-with-otel.mdx b/docs/concepts/otlp/sentry-with-otel.mdx index 7553d9655aeb2c..4e07fd25d68fb7 100644 --- a/docs/concepts/otlp/sentry-with-otel.mdx +++ b/docs/concepts/otlp/sentry-with-otel.mdx @@ -87,7 +87,7 @@ If you're running both a Sentry SDK and OTel instrumentation in the same backend - - + +_Import name: `Sentry.openTelemetryIntegration`_ + +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. + +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. + +An active Sentry span still takes precedence, so this only changes what happens when Sentry has no span of its own. + + + +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. + + + +## Install + +Install the OpenTelemetry packages you need alongside the Sentry SDK: + +```bash {tabTitle:npm} +npm install @opentelemetry/api @opentelemetry/sdk-trace-node @opentelemetry/sdk-trace-base @opentelemetry/exporter-trace-otlp-http +``` + +```bash {tabTitle:yarn} +yarn add @opentelemetry/api @opentelemetry/sdk-trace-node @opentelemetry/sdk-trace-base @opentelemetry/exporter-trace-otlp-http +``` + +```bash {tabTitle:pnpm} +pnpm add @opentelemetry/api @opentelemetry/sdk-trace-node @opentelemetry/sdk-trace-base @opentelemetry/exporter-trace-otlp-http +``` + +## Configure + +Leave Sentry tracing off so the two pipelines stay separate. `getOtlpTracesEndpoint()` turns your DSN into the URL and auth headers of Sentry's OTLP endpoint: + +```javascript +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 "@sentry/node"; + +const provider = new NodeTracerProvider({ + spanProcessors: [ + new BatchSpanProcessor( + new OTLPTraceExporter(Sentry.getOtlpTracesEndpoint("___PUBLIC_DSN___")) + ), + ], +}); + +provider.register(); + +Sentry.init({ + dsn: "___PUBLIC_DSN___", + // Leave the OpenTelemetry setup to your own provider + enableOpenTelemetrySetup: false, + // No `tracesSampleRate`: OpenTelemetry owns spans, Sentry owns errors and logs + integrations: [Sentry.openTelemetryIntegration()], +}); +``` + +Sentry sends no spans with this setup, and no Sentry span reaches your OpenTelemetry pipeline. + +If you'd rather have Sentry own tracing and add your own instrumentation on top, see Using Your Existing OpenTelemetry Setup instead. diff --git a/docs/platforms/javascript/common/install/index.mdx b/docs/platforms/javascript/common/install/index.mdx index 890fe54413bc7a..c171573bed1ecf 100644 --- a/docs/platforms/javascript/common/install/index.mdx +++ b/docs/platforms/javascript/common/install/index.mdx @@ -57,10 +57,6 @@ If you are using `import` in your application, your installation method depends If you do not compile your code, you'll need to follow the [ESM instructions](./esm). -### I don't need automatic spans/transactions - -If you don't need spans emitted by OpenTelemetry instrumentation, you can use `@sentry/node-core` in [Lightweight Mode](./lightweight) without OpenTelemetry dependencies. You still get errors, logs, metrics, breadcrumbs, and more. This mode is experimental. - diff --git a/docs/platforms/javascript/common/install/lightweight.mdx b/docs/platforms/javascript/common/install/lightweight.mdx deleted file mode 100644 index dd87680c2cc5ba..00000000000000 --- a/docs/platforms/javascript/common/install/lightweight.mdx +++ /dev/null @@ -1,211 +0,0 @@ ---- -title: Lightweight Mode -sidebar_order: 15 -description: "Learn about running Sentry in lightweight mode without OpenTelemetry, or with optional OTLP integration for existing OTel setups." -supported: - - javascript.node - - javascript.connect - - javascript.express - - javascript.fastify - - javascript.hapi - - javascript.hono - - javascript.koa ---- - - - Lightweight mode is experimental and may have breaking changes in minor or - patch releases. - - - - Are you unsure if you should use this installation method? Review our - [installation methods](../). - - -If you don't need automatic spans/transactions, you can use `@sentry/node-core/light` which doesn't require OpenTelemetry dependencies. This mode is ideal when: - -- You only need error tracking, logs, or metrics without tracing data (no automatic span creation) -- You want to minimize bundle size and runtime overhead -- You don't need spans emitted by OpenTelemetry instrumentation - -You still get error tracking, logs, metrics, breadcrumbs, context/user data, local variables capture, distributed tracing (via `sentry-trace` and `baggage` headers), and automatic request isolation (Node.js 22+). - -If needed, you can still manually create spans by using Sentry's custom instrumentation APIs like `startSpan`. - -If you already have your own OpenTelemetry setup, you can also use the [OTLP integration](#using-with-opentelemetry-otlp) to link Sentry errors to your OTel traces and export spans to Sentry. - -## Prerequisites - -- **Node.js 22.12.0+** is recommended for full functionality (automatic request isolation) -- Lower Node.js versions work but with limited capabilities (see [Request Isolation](#request-isolation) below) - -## Step 1: Install - -```bash {tabTitle:npm} -npm install @sentry/node-core --save -``` - -```bash {tabTitle:yarn} -yarn add @sentry/node-core -``` - -```bash {tabTitle:pnpm} -pnpm add @sentry/node-core -``` - -## Step 2: Configure - -Import from `@sentry/node-core/light` and call `Sentry.init()` as early as possible in your application lifecycle: - -```javascript {tabTitle:ESM} -import * as Sentry from "@sentry/node-core/light"; - -Sentry.init({ - dsn: "___PUBLIC_DSN___", -}); - -// Now create your HTTP server or framework app -``` - -```javascript {tabTitle:CJS} -const Sentry = require("@sentry/node-core/light"); - -Sentry.init({ - dsn: "___PUBLIC_DSN___", -}); - -// Now create your HTTP server or framework app -``` - -## Step 3: Verify - -To verify that Sentry is working, capture a test error: - -```javascript -Sentry.captureException(new Error("Sentry lightweight mode test")); -``` - -After running your application, you should see this error appear in your [Sentry dashboard](https://sentry.io). - -## Request Isolation - -Request isolation ensures that errors, breadcrumbs, and context are correctly scoped to individual requests. - -### Node.js 22.12.0+ - -Request isolation works automatically. No additional setup is needed — just make sure `Sentry.init()` is called before you create your HTTP server. - -### Node.js < 22 - -You need to manually wrap your request handler with `Sentry.withIsolationScope()`: - -```javascript -import * as Sentry from "@sentry/node-core/light"; -import http from "http"; - -const server = http.createServer((req, res) => { - Sentry.withIsolationScope(() => { - // Your request handling code - Sentry.setUser({ id: "user-id" }); - res.end("OK"); - }); -}); -``` - - - When using manual isolation on Node.js < 22, distributed tracing will not - work correctly. - - -## Conversation IDs - -To group AI spans in [Conversations](/product/agents/conversations/), add -`conversationIdIntegration` and call `setConversationId`. Neither is included in -lightweight mode by default: - -```javascript -import * as Sentry from "@sentry/node-core/light"; -import { conversationIdIntegration, setConversationId } from "@sentry/core"; - -Sentry.init({ - dsn: "___PUBLIC_DSN___", - integrations: [ - ...Sentry.getDefaultIntegrations(), - conversationIdIntegration(), - ], -}); - -setConversationId("conv_abc123"); -``` - -## When to Use Lightweight Mode vs `@sentry/node` - -| | `@sentry/node` | `@sentry/node-core/light` | -| ------------------------------- | ------------------- | ---------------------------------------------- | -| **Error tracking** | Yes | Yes | -| **Logs and metrics** | Yes | Yes | -| **Automatic spans** | Yes | No | -| **OpenTelemetry auto-included** | Yes | No | -| **Dependency footprint** | Larger | Minimal | -| **Best for** | Full observability | No auto-instrumentation, manual tracing setup | - -If you need automatic spans for HTTP requests, database queries, and other operations, use `@sentry/node` (the default). If you don't need automatically created spans and want minimal dependencies, use lightweight mode. - -## Using with OpenTelemetry (OTLP) - - - -If you already have your own OpenTelemetry setup and want to bridge it with Sentry, you can use the `otlpIntegration` from `@sentry/node-core/light/otlp`. This integration: - -- Links Sentry errors and logs to the active OpenTelemetry trace context -- Exports OpenTelemetry spans to Sentry via [OTLP](/concepts/otlp/) - -### Install OpenTelemetry Dependencies - -In addition to `@sentry/node-core`, install the OpenTelemetry packages you need: - -```bash {tabTitle:npm} -npm install @opentelemetry/api @opentelemetry/sdk-trace-node @opentelemetry/exporter-trace-otlp-http -``` - -```bash {tabTitle:yarn} -yarn add @opentelemetry/api @opentelemetry/sdk-trace-node @opentelemetry/exporter-trace-otlp-http -``` - -```bash {tabTitle:pnpm} -pnpm add @opentelemetry/api @opentelemetry/sdk-trace-node @opentelemetry/exporter-trace-otlp-http -``` - -### Configure - -Set up your OpenTelemetry `TracerProvider` first, then initialize Sentry with the `otlpIntegration`: - -```javascript -import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node"; -import * as Sentry from "@sentry/node-core/light"; -import { otlpIntegration } from "@sentry/node-core/light/otlp"; - -// Set up your OpenTelemetry TracerProvider as usual -const provider = new NodeTracerProvider(); -provider.register(); - -Sentry.init({ - dsn: "___PUBLIC_DSN___", - integrations: [otlpIntegration()], -}); -``` - -The integration automatically derives the OTLP endpoint from your DSN. To send traces to your own collector instead, pass a `collectorUrl`: - -```javascript -otlpIntegration({ - collectorUrl: "https://my-collector.example.com/v1/traces", -}); -``` - -### Options - -| Option | Type | Default | Description | -|---|---|---|---| -| `setupOtlpTracesExporter` | `boolean` | `true` | Automatically configure an exporter to send OTLP traces to the right project from the DSN or `collectorUrl`. Set to `false` to set up the `TracerProvider` manually. | -| `collectorUrl` | `string` | `undefined` | URL of your own OpenTelemetry collector. When set, traces are sent here instead of the Sentry OTLP endpoint derived from the DSN. | diff --git a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx index a294374981683e..9731ee23ff3c69 100644 --- a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx +++ b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx @@ -42,7 +42,7 @@ If you are looking to simply add individual OpenTelemetry instrumentation to you -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. +If OpenTelemetry owns tracing in your application and you only want Sentry's errors, logs and metrics on the same traces, use `openTelemetryIntegration` instead. It requires significantly less manual wiring. diff --git a/redirects.js b/redirects.js index 788d5d4a203f11..5664b5e1995b6e 100644 --- a/redirects.js +++ b/redirects.js @@ -970,6 +970,41 @@ const userDocsRedirects = [ source: '/platforms/javascript/guides/aws-lambda/cjs-npm__v9.x/', destination: '/platforms/javascript/guides/aws-lambda/install/cjs-npm__v9.x/', }, + { + source: '/platforms/javascript/guides/node/install/lightweight/', + destination: + '/platforms/javascript/guides/node/configuration/integrations/opentelemetry/', + }, + { + source: '/platforms/javascript/guides/connect/install/lightweight/', + destination: + '/platforms/javascript/guides/connect/configuration/integrations/opentelemetry/', + }, + { + source: '/platforms/javascript/guides/express/install/lightweight/', + destination: + '/platforms/javascript/guides/express/configuration/integrations/opentelemetry/', + }, + { + source: '/platforms/javascript/guides/fastify/install/lightweight/', + destination: + '/platforms/javascript/guides/fastify/configuration/integrations/opentelemetry/', + }, + { + source: '/platforms/javascript/guides/hapi/install/lightweight/', + destination: + '/platforms/javascript/guides/hapi/configuration/integrations/opentelemetry/', + }, + { + source: '/platforms/javascript/guides/hono/install/lightweight/', + destination: + '/platforms/javascript/guides/hono/configuration/integrations/opentelemetry/', + }, + { + source: '/platforms/javascript/guides/koa/install/lightweight/', + destination: + '/platforms/javascript/guides/koa/configuration/integrations/opentelemetry/', + }, { source: '/platforms/javascript/guides/react-router/features/instrumentation-api/', destination: '/platforms/javascript/guides/react-router/manual-setup/', @@ -2296,14 +2331,11 @@ const userDocsRedirects = [ // Cloudflare setup pages moved from Features to Installation Methods. { source: '/platforms/javascript/guides/cloudflare/features/vite-plugin.md', - destination: - '/platforms/javascript/guides/cloudflare/install/vite-plugin.md', + destination: '/platforms/javascript/guides/cloudflare/install/vite-plugin.md', }, { - source: - '/platforms/javascript/guides/cloudflare/features/vite-plugin/:path*', - destination: - '/platforms/javascript/guides/cloudflare/install/vite-plugin/:path*', + source: '/platforms/javascript/guides/cloudflare/features/vite-plugin/:path*', + destination: '/platforms/javascript/guides/cloudflare/install/vite-plugin/:path*', }, // Cloudflare AI pages moved from Features to Agent Tracing. { From 4cdfb28c1d0e08e901ee9b58ee8f6bc09bf0cb8d Mon Sep 17 00:00:00 2001 From: JPeer264 Date: Fri, 18 Sep 2026 10:36:49 +0200 Subject: [PATCH 2/2] docs(js): Update the OpenTelemetry pages for v11, keep v10 versions Every page in the OpenTelemetry section documented APIs that v11 removed: - `skipOpenTelemetrySetup` was replaced by `enableOpenTelemetrySetup`. - `SentryContextManager`, `SentrySampler`, `SentrySpanProcessor` and `validateOpenTelemetrySetup` were removed, so wiring Sentry's components into a provider you own is no longer possible. - The `openTelemetryInstrumentations` and `openTelemetrySpanProcessors` options were removed. Snapshot all three pages as `__v10.x` so readers on v10 keep working instructions, since every one of those APIs is valid there, and rewrite the current pages around what v11 ships. - The landing page claimed OpenTelemetry instrumentation is picked up "without any further configuration". It isn't: the SDK registers no tracer provider by default, so spans from `@opentelemetry/api` are not captured. Describe the two ways to connect the pipelines instead. - "Using Your Existing OpenTelemetry Setup" was built end to end on the removed components. It now covers the two setups that exist, and says what happened to the components it used to document. - "Using OpenTelemetry APIs" loses the two sections built on the removed options. Adding instrumentation goes through OpenTelemetry's own `registerInstrumentations()`, and the page states that it assumes `enableOpenTelemetrySetup: true`. The `performance/opentelemetry-setup` includes are left alone: only the v10 page renders them now, and they document v10 correctly. Refs SDK-1351 Co-Authored-By: Claude Opus 5 --- .../common/opentelemetry/custom-setup.mdx | 161 ++------------- .../opentelemetry/custom-setup__v10.x.mdx | 191 ++++++++++++++++++ .../javascript/common/opentelemetry/index.mdx | 11 +- .../common/opentelemetry/index__v10.x.mdx | 41 ++++ .../using-opentelemetry-apis.mdx | 86 +------- .../using-opentelemetry-apis__v10.x.mdx | 153 ++++++++++++++ 6 files changed, 420 insertions(+), 223 deletions(-) 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 diff --git a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx index 9731ee23ff3c69..a77f7d8cf5d713 100644 --- a/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx +++ b/docs/platforms/javascript/common/opentelemetry/custom-setup.mdx @@ -29,164 +29,43 @@ 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. - -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 OpenTelemetry owns tracing in your application and you only want Sentry's errors, logs and metrics on the same traces, use `openTelemetryIntegration` instead. It requires significantly less manual wiring. - - - +Sentry and OpenTelemetry are separate pipelines. The SDK doesn't register an OpenTelemetry tracer provider by default, and it no longer routes spans from a provider you own into Sentry as Sentry spans. - - -## 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. - - +That leaves two setups, depending on which side owns tracing. -The following code snippet shows how to set up Sentry for error monitoring only: +## OpenTelemetry Owns Tracing - +Keep your own tracer provider and add `openTelemetryIntegration`. Sentry's errors, logs, metrics and check-ins attach to the OpenTelemetry span that's active when they happen, so they land on your traces. -## 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") +Sentry.init({ + dsn: "___PUBLIC_DSN___", + // No `tracesSampleRate`: OpenTelemetry owns spans + enableOpenTelemetrySetup: false, + integrations: [Sentry.openTelemetryIntegration()], }); ``` - - -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 +Sentry emits no spans in this setup. To get your OpenTelemetry spans into Sentry, point your own exporter at Sentry's OTLP endpoint with `getOtlpTracesEndpoint()`, which that page shows in full. -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. +## Sentry Owns Tracing -If your OpenTelemetry setup already handles trace propagation for fetch requests, you can set `tracePropagation: false` to prevent Sentry from injecting duplicate trace headers: +Set `enableOpenTelemetrySetup: true` and the SDK registers its own tracer provider and propagator. Spans created through `@opentelemetry/api` become Sentry spans, alongside the spans the SDK creates itself: ```javascript -const sentryClient = Sentry.init({ - dsn: "___DSN___", - skipOpenTelemetrySetup: true, - integrations: [ - Sentry.nativeNodeFetchIntegration({ tracePropagation: false }), - ], +Sentry.init({ + dsn: "___PUBLIC_DSN___", + tracesSampleRate: 1.0, + enableOpenTelemetrySetup: true, }); ``` -## Using a Custom Sampler +This is already the default on `@sentry/nextjs` and `@sentry/sveltekit`, which need it to capture the spans those frameworks emit. -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: +For working with the OpenTelemetry APIs in this setup, see Using OpenTelemetry APIs. - - - - -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. +`SentryContextManager`, `SentrySampler` and `SentrySpanProcessor` were removed, so wiring Sentry's components into a provider you own is no longer possible. If you were doing that, pick one of the two setups above. - - - - - Learn more about ESM installation methods. - - - 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 00000000000000..8e5f273f85b976 --- /dev/null +++ b/docs/platforms/javascript/common/opentelemetry/custom-setup__v10.x.mdx @@ -0,0 +1,191 @@ +--- +title: Using Your Existing OpenTelemetry Setup +description: "Learn how to use your existing custom OpenTelemetry setup with Sentry." +noindex: true # Not indexed because it is a versioned docs page +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. + + + + + + + + + + + +## 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 468373c3a60254..41fad1b314b54e 100644 --- a/docs/platforms/javascript/common/opentelemetry/index.mdx +++ b/docs/platforms/javascript/common/opentelemetry/index.mdx @@ -31,10 +31,15 @@ notSupported: 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. +Sentry and [OpenTelemetry](https://opentelemetry.io/) are separate pipelines, and you choose how they connect. -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 SDK emits its own spans and isolates scopes on its own, so tracing works without any OpenTelemetry setup. What it doesn't do by default is register an OpenTelemetry tracer provider, so spans created through `@opentelemetry/api` aren't captured. To start capturing traces and spans from the SDK itself, set up Tracing and Performance Monitoring. -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. +There are two ways to connect the two: + +- **OpenTelemetry owns tracing.** Keep your own tracer provider and add `openTelemetryIntegration`, so Sentry's errors, logs, metrics and check-ins land on your OpenTelemetry traces. Export your spans to Sentry over OTLP. +- **Sentry owns tracing.** Set `enableOpenTelemetrySetup: true` and the SDK registers its own tracer provider, so spans created through `@opentelemetry/api` become Sentry spans. This is the default on `@sentry/nextjs` and `@sentry/sveltekit`. + +Read the guides below for either setup. 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 00000000000000..af988e4926e3a8 --- /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." +noindex: true # Not indexed because it is a versioned docs page +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. + + diff --git a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx index 8d0aaa5120a4a3..b763658e363296 100644 --- a/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx +++ b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis.mdx @@ -29,60 +29,17 @@ notSupported: 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. +These APIs work with either OpenTelemetry setup. What changes is where the spans go. With `enableOpenTelemetrySetup: true`, the SDK registers its own tracer provider, so spans started through OpenTelemetry APIs become Sentry spans and spans started with the Sentry SDK are propagated to OpenTelemetry. With a tracer provider of your own, the spans go to your pipeline and reach Sentry through your OTLP exporter. ## 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. - - +Register instrumentation through OpenTelemetry's own `registerInstrumentations()` from `@opentelemetry/instrumentation`. With ESM, call it before importing any module that should be instrumented. ## 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: +You can access the tracer via `client.tracer` and then create spans with OpenTelemetry APIs, as shown below. It reads the globally registered tracer provider, so it gives you Sentry's tracer or your own, depending on the setup: ```javascript {tabTitle: ESM} import * as Sentry from "@sentry/node"; @@ -93,6 +50,7 @@ tracer.startActiveSpan("span name", () => { // measure something }); ``` + ```javascript {tabTitle: CJS} const Sentry = require("@sentry/node"); @@ -103,50 +61,20 @@ tracer.startActiveSpan("span name", () => { }); ``` -You can also use any other tracer. All OpenTelemetry spans will be picked up by Sentry automatically. +You can also use any other tracer. With `enableOpenTelemetrySetup: true`, every OpenTelemetry span is 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. +This is the one part of this page that needs `enableOpenTelemetrySetup: true`. `client.traceProvider` holds the tracer provider the SDK registered, and it stays `undefined` when you register a provider of your own, where you already have a reference to it. ```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()], -}); +const provider = Sentry.getClient()?.traceProvider; ``` 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 00000000000000..1e978433e61cce --- /dev/null +++ b/docs/platforms/javascript/common/opentelemetry/using-opentelemetry-apis__v10.x.mdx @@ -0,0 +1,153 @@ +--- +title: Using OpenTelemetry APIs +description: "Learn how to use OpenTelemetry APIs with Sentry." +noindex: true # Not indexed because it is a versioned docs page +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()], +}); +```