Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Spans go to Sentry. This is not a general OpenTelemetry pipeline: there is no ex

##### 3. Your own OpenTelemetry, Sentry linked to it

Turn Sentry tracing off, run your own OpenTelemetry setup, and add the Sentry `otlpIntegration()`. Leave `enableOpenTelemetrySetup` unset or set it to `false`:
Turn Sentry tracing off, run your own OpenTelemetry setup, and add the Sentry `openTelemetryIntegration()`. Leave `enableOpenTelemetrySetup` unset or set it to `false`:

```js
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
Expand All @@ -136,13 +136,13 @@ provider.register();
Sentry.init({
dsn: '__DSN__',
// no tracesSampleRate: OpenTelemetry owns spans, Sentry owns errors and logs
integrations: [Sentry.otlpIntegration()],
integrations: [Sentry.openTelemetryIntegration()],
});
```

`enableOpenTelemetrySetup` already defaults to `false` on most server SDKs, so there is nothing to set. On `@sentry/nextjs` and `@sentry/sveltekit` it defaults to `true`, so you have to set it to `false` explicitly. Otherwise Sentry registers its own tracer provider and you end up in setup 2 rather than this one.

Spans are completely managed by your OpenTelemetry setup and the two pipelines stay separate: Sentry sends no spans, and no Sentry span is exported to your OpenTelemetry pipeline. Sentry captures errors and logs, and the Sentry `otlpIntegration()` attaches them to the active OpenTelemetry span so all your telemetry is connected in one trace. `getOtlpTracesEndpoint()` turns your DSN into the URL and auth headers for Sentry's OTLP endpoint, so you can point your own exporter at Sentry, at your own collector, or at both.
Spans are completely managed by your OpenTelemetry setup and the two pipelines stay separate: Sentry sends no spans, and no Sentry span is exported to your OpenTelemetry pipeline. Sentry captures errors and logs, and the Sentry `openTelemetryIntegration()` attaches them to the active OpenTelemetry span so all your telemetry is connected in one trace. `getOtlpTracesEndpoint()` turns your DSN into the URL and auth headers for Sentry's OTLP endpoint, so you can point your own exporter at Sentry, at your own collector, or at both.

Sentry does not touch your pipeline: no exporter, no span processor, no tracer provider, and outgoing trace propagation is left to your propagator. See [Connecting Sentry to your OpenTelemetry traces](#connecting-sentry-to-your-opentelemetry-traces) for the details, including what changed if you used the v10 integration.

Expand All @@ -158,13 +158,13 @@ In v10, running your own OpenTelemetry setup meant registering Sentry's own comp

#### Connecting Sentry to your OpenTelemetry traces

`Sentry.otlpIntegration()` attaches everything Sentry sends that carries trace information (errors, logs, metrics and crons) to the OpenTelemetry span that is active when it happens. It takes no options, and is available from every server-side SDK, so there is nothing extra to install or import. See [setup 3](#3-your-own-opentelemetry-sentry-linked-to-it) above for a complete example.
`Sentry.openTelemetryIntegration()` attaches everything Sentry sends that carries trace information (errors, logs, metrics and crons) to the OpenTelemetry span that is active when it happens. It takes no options, and is available from every server-side SDK, so there is nothing extra to install or import. See [setup 3](#3-your-own-opentelemetry-sentry-linked-to-it) above for a complete example.

It does not set up a span exporter, span processor, or tracer provider. You keep full ownership of your OpenTelemetry pipeline, and outgoing request propagation is left to your OpenTelemetry propagator. To send your spans to Sentry, point your own exporter at the URL and auth headers that `Sentry.getOtlpTracesEndpoint()` derives from your DSN.

An active Sentry span still takes precedence, so this only changes what happens when Sentry has no span of its own, which is the usual setup when OpenTelemetry owns tracing.

If you used the v10 integration from `@sentry/node-core/light/otlp`, three things changed: it moved to the main export of every server SDK, it [no longer sets up an exporter for you and lost its options](#3-removed-apis), and it [reports itself as `Otlp` rather than `OtlpIntegration`](#otlpintegration-integration-renamed-to-otlp). Configure your own exporter as shown in setup 3, pointing it at your collector's URL if you route through one.
If you used the v10 integration from `@sentry/node-core/light/otlp`, three things changed: it moved to the main export of every server SDK, it [no longer sets up an exporter for you and lost its options](#3-removed-apis), and it [was renamed to `openTelemetryIntegration()`](#otlpintegration-renamed-to-opentelemetryintegration). Configure your own exporter as shown in setup 3, pointing it at your collector's URL if you route through one.

### `sendDefaultPii` is replaced by `dataCollection`

Expand Down Expand Up @@ -1334,8 +1334,8 @@ The `idleTimeout`, `finalTimeout` and `childSpanTimeout` options of interaction
- (Express) The `shouldHandleError` option was removed from `setupExpressErrorHandler` and `expressErrorHandler`, along with the `ExpressHandlerOptions` type. Configure it on `expressIntegration()` instead. See [Express: errors are captured automatically](#express-errors-are-captured-automatically).
- (Express) `ExpressIntegrationOptions` is no longer exported from `@sentry/core`. Import it from `@sentry/node` instead — that version is the one `expressIntegration()` accepts, and it carries `shouldHandleError`.
- (Fastify) The deprecated `instrumentFastify` and `handleFastifyError` exports were removed. `fastifyIntegration` now instruments Fastify (v3.21–v5) and captures errors on its own, so neither export is needed. See [Fastify: `setupFastifyErrorHandler` is deprecated](#fastify-setupfastifyerrorhandler-is-deprecated).
- The `@sentry/node-core/light/otlp` entry point was removed, along with its optional `@opentelemetry/exporter-trace-otlp-http` peer dependency. `otlpIntegration` is now exported directly from every server-side SDK, so `Sentry.otlpIntegration()` needs no extra import or install.
- The `otlpIntegration` options `setupOtlpTracesExporter` and `collectorUrl` were removed, and the integration no longer sets up a span exporter, span processor, or tracer provider. Configure your own exporter and point it at `Sentry.getOtlpTracesEndpoint(dsn)`, or at your collector's URL if you route through one. See [Connecting Sentry to your OpenTelemetry traces](#connecting-sentry-to-your-opentelemetry-traces).
- The `@sentry/node-core/light/otlp` entry point was removed, along with its optional `@opentelemetry/exporter-trace-otlp-http` peer dependency. `openTelemetryIntegration` is now exported directly from every server-side SDK, so `Sentry.openTelemetryIntegration()` needs no extra import or install.
- The `setupOtlpTracesExporter` and `collectorUrl` options were removed, and the integration no longer sets up a span exporter, span processor, or tracer provider. Configure your own exporter and point it at `Sentry.getOtlpTracesEndpoint(dsn)`, or at your collector's URL if you route through one. See [Connecting Sentry to your OpenTelemetry traces](#connecting-sentry-to-your-opentelemetry-traces).
- The deprecated `httpServerSpansIntegration` `instrumentation.{requestHook,responseHook,applyCustomAttributesOnSpan}` option was removed. Use `onSpanCreated` instead. `httpServerSpansIntegration` only covers incoming requests; the outgoing hooks (`outgoingRequestHook`, `outgoingResponseHook`, `outgoingRequestApplyCustomAttributes`) are on `httpIntegration`.

#### `httpIntegration` options were consolidated
Expand Down Expand Up @@ -1930,11 +1930,27 @@ Sentry.denoHttpIntegration({
});
```

### `OtlpIntegration` integration renamed to `Otlp`
### `otlpIntegration` renamed to `openTelemetryIntegration`

Affected SDKs: Server-side SDKs (`@sentry/node` and all dependents).

The OTLP integration reports itself as `Otlp` rather than `OtlpIntegration`, matching every other integration in the SDKs, none of which carry an `Integration` suffix in their name. The `otlpIntegration()` export itself is unchanged. This only matters if you reference the integration by name:
The old name was misleading: the integration sends nothing over OTLP. It sets up no exporter, no span processor and no tracer provider, and only connects what Sentry sends to your OpenTelemetry traces.

```js
// before
Sentry.init({
integrations: [Sentry.otlpIntegration()],
});

// after
Sentry.init({
integrations: [Sentry.openTelemetryIntegration()],
});
```

`getOtlpTracesEndpoint()` keeps its name. That helper really is about OTLP: it derives the URL and auth headers of Sentry's OTLP traces endpoint from your DSN.

The integration also reports itself as `OpenTelemetry` rather than `OtlpIntegration`, which matters if you reference it by name:

```js
// before
Expand All @@ -1944,7 +1960,7 @@ Sentry.init({

// after
Sentry.init({
integrations: integrations => integrations.filter(integration => integration.name !== 'Otlp'),
integrations: integrations => integrations.filter(integration => integration.name !== 'OpenTelemetry'),
});
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ Sentry.init({
enableOpenTelemetrySetup: false,

// Puts the active OpenTelemetry span's trace on everything Sentry sends.
integrations: [Sentry.otlpIntegration()],
integrations: [Sentry.openTelemetryIntegration()],
});
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Sentry.init({
dsn,
debug: !!process.env.DEBUG,
tunnel: `http://localhost:3031/`, // proxy server
integrations: [Sentry.otlpIntegration()],
integrations: [Sentry.openTelemetryIntegration()],
});

interface ExportedTrace {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ Sentry.init({
debug: !!process.env.DEBUG,
tunnel: `http://localhost:3031/`, // proxy server
// no tracesSampleRate: OpenTelemetry owns spans, Sentry owns errors and logs
integrations: [Sentry.otlpIntegration()],
integrations: [Sentry.openTelemetryIntegration()],
});
2 changes: 1 addition & 1 deletion packages/astro/src/index.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ export {
postgresIntegration,
postgresJsIntegration,
prismaIntegration,
otlpIntegration,
openTelemetryIntegration,
getOtlpTracesEndpoint,
processSessionIntegration,
childProcessIntegration,
Expand Down
2 changes: 1 addition & 1 deletion packages/aws-serverless/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ export {
postgresJsIntegration,
processSessionIntegration,
prismaIntegration,
otlpIntegration,
openTelemetryIntegration,
getOtlpTracesEndpoint,
childProcessIntegration,
workerThreadsIntegration,
Expand Down
2 changes: 1 addition & 1 deletion packages/bun/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export {
postgresIntegration,
postgresJsIntegration,
prismaIntegration,
otlpIntegration,
openTelemetryIntegration,
getOtlpTracesEndpoint,
processSessionIntegration,
hapiIntegration,
Expand Down
2 changes: 1 addition & 1 deletion packages/cloudflare/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export { httpServerIntegration } from './integrations/httpServer';
export { fetchIntegration } from './integrations/fetch';
export { spotlightIntegration } from './integrations/spotlight';
export {
otlpIntegration,
openTelemetryIntegration,
getOtlpTracesEndpoint,
prismaIntegration,
instrumentOpenAiClient,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/carrier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export interface SentryCarrier {
/** Strategy for assembling segment spans into transactions; set by SDKs that defer capture. */
segmentSpanCaptureStrategy?: SegmentSpanCaptureStrategy;

/** Supplies trace context from a non-Sentry source (e.g. OpenTelemetry); set by `otlpIntegration`. */
/** Supplies trace context from a non-Sentry source (e.g. OpenTelemetry); set by `openTelemetryIntegration`. */
externalPropagationContextProvider?: () => { traceId: string; spanId: string } | undefined;

/** Overwrites TextEncoder used in `@sentry/core`, need for `react-native@0.73` and older */
Expand Down
2 changes: 1 addition & 1 deletion packages/deno/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ export {
postgresJsIntegration,
tediousIntegration,
} from '@sentry/server-utils';
export { otlpIntegration, getOtlpTracesEndpoint } from '@sentry/server-utils/no-diagnostic-channels';
export { openTelemetryIntegration, getOtlpTracesEndpoint } from '@sentry/server-utils/no-diagnostic-channels';
// Deprecated aliases kept for back-compat. Each forwards to the shared
// integration above, so its name is the shared name (e.g. `Mysql`), not the old
// `Deno*` name. See each alias's `@deprecated` note.
Expand Down
2 changes: 1 addition & 1 deletion packages/google-cloud-serverless/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ export {
postgresIntegration,
postgresJsIntegration,
prismaIntegration,
otlpIntegration,
openTelemetryIntegration,
getOtlpTracesEndpoint,
processSessionIntegration,
hapiIntegration,
Expand Down
2 changes: 1 addition & 1 deletion packages/node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export {
vercelAIIntegration,
} from '@sentry/server-utils';
export {
otlpIntegration,
openTelemetryIntegration,
getOtlpTracesEndpoint,
prismaIntegration,
instrumentOpenAiClient,
Expand Down
2 changes: 1 addition & 1 deletion packages/server-utils/src/exports.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Shared exports not using diagnostics channels
export { setHttpServerSpanRouteAttribute } from './utils/setHttpServerSpanRouteAttribute';
export { setAsyncLocalStorageAsyncContextStrategy } from './async-context';
export { otlpIntegration, getOtlpTracesEndpoint } from './otlp';
export { openTelemetryIntegration, getOtlpTracesEndpoint } from './opentelemetry';
export * from './ai';
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { isSpanContextValid, trace } from '@opentelemetry/api';
import type { IntegrationFn } from '@sentry/core';
import { defineIntegration, dsnFromString, SENTRY_API_VERSION, registerExternalPropagationContext } from '@sentry/core';

const INTEGRATION_NAME = 'Otlp' as const;
const INTEGRATION_NAME = 'OpenTelemetry' as const;

const _otlpIntegration = (() => {
const _openTelemetryIntegration = (() => {
return {
name: INTEGRATION_NAME,

Expand Down Expand Up @@ -44,7 +44,7 @@ const _otlpIntegration = (() => {
* This does not export any spans. Configure your own span exporter and point it at Sentry using
* {@link getOtlpTracesEndpoint}.
*/
export const otlpIntegration = defineIntegration(_otlpIntegration);
export const openTelemetryIntegration = defineIntegration(_openTelemetryIntegration);

/**
* Builds the URL and auth headers for Sentry's OTLP traces endpoint, to configure an
Expand All @@ -69,7 +69,7 @@ export const otlpIntegration = defineIntegration(_otlpIntegration);
*
* Sentry.init({
* dsn: '__DSN__',
* integrations: [Sentry.otlpIntegration()],
* integrations: [Sentry.openTelemetryIntegration()],
* });
* ```
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { context, INVALID_SPAN_CONTEXT, ROOT_CONTEXT, trace, TraceFlags } from '
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import type { Envelope } from '@sentry/core';
import { getCurrentScope, getMainCarrier, registerExternalPropagationContext, setCurrentClient } from '@sentry/core';
import { getOtlpTracesEndpoint, otlpIntegration } from '../src/otlp';
import { getOtlpTracesEndpoint, openTelemetryIntegration } from '../src/opentelemetry';
import { getDefaultTestClientOptions, TestClient } from './mocks/client';

const DSN = 'https://public@dsn.ingest.sentry.io/1337';
Expand Down Expand Up @@ -61,9 +61,9 @@ function withActiveOtelSpan<T>(callback: () => T): T {
return context.with(trace.setSpan(context.active(), otelSpan), callback);
}

function setupClientWithOtlpIntegration(): TestClient {
function setupClientWithOpenTelemetryIntegration(): TestClient {
const client = new TestClient(
getDefaultTestClientOptions({ dsn: DSN, integrations: [otlpIntegration()], stackParser: () => [] }),
getDefaultTestClientOptions({ dsn: DSN, integrations: [openTelemetryIntegration()], stackParser: () => [] }),
);
setCurrentClient(client);
client.init();
Expand All @@ -76,7 +76,7 @@ function setupClientCapturingEnvelopes(): { client: TestClient; envelopes: Envel
const client = new TestClient(
getDefaultTestClientOptions({
dsn: DSN,
integrations: [otlpIntegration()],
integrations: [openTelemetryIntegration()],
stackParser: () => [],
enableSend: true,
}),
Expand All @@ -87,7 +87,7 @@ function setupClientCapturingEnvelopes(): { client: TestClient; envelopes: Envel
return { client, envelopes };
}

describe('otlpIntegration', () => {
describe('openTelemetryIntegration', () => {
beforeEach(() => {
getMainCarrier().__SENTRY__ = undefined;
context.setGlobalContextManager(new SyncContextManager());
Expand All @@ -99,7 +99,7 @@ describe('otlpIntegration', () => {
});

it('links captured errors to the active OpenTelemetry span', async () => {
const client = setupClientWithOtlpIntegration();
const client = setupClientWithOpenTelemetryIntegration();

withActiveOtelSpan(() => {
client.captureException(new Error('boom'));
Expand Down Expand Up @@ -140,7 +140,7 @@ describe('otlpIntegration', () => {
});

it('ignores an active span with an invalid span context', async () => {
const client = setupClientWithOtlpIntegration();
const client = setupClientWithOpenTelemetryIntegration();
getCurrentScope().setPropagationContext({ traceId: 'cccccccccccccccccccccccccccccccc', sampleRand: 0.5 });

// OpenTelemetry hands out a span wrapping `INVALID_SPAN_CONTEXT` when tracing is suppressed, or
Expand All @@ -154,7 +154,7 @@ describe('otlpIntegration', () => {
});

it('falls back to the Sentry propagation context when no OpenTelemetry span is active', async () => {
const client = setupClientWithOtlpIntegration();
const client = setupClientWithOpenTelemetryIntegration();
getCurrentScope().setPropagationContext({ traceId: 'cccccccccccccccccccccccccccccccc', sampleRand: 0.5 });

client.captureException(new Error('boom'));
Expand Down
2 changes: 1 addition & 1 deletion packages/vercel-edge/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export {
} from '@sentry/core';
export { trpcMiddleware, wrapMcpServerWithSentry } from '@sentry/core/server';
export {
otlpIntegration,
openTelemetryIntegration,
getOtlpTracesEndpoint,
instrumentOpenAiClient,
instrumentAnthropicAiClient,
Expand Down
Loading