Skip to content

feat(server-utils): Add otlpIntegration to connect Sentry to an existing OpenTelemetry setup - #23099

Open
andreiborza wants to merge 5 commits into
developfrom
ab/js-3291-otlp-integration
Open

feat(server-utils): Add otlpIntegration to connect Sentry to an existing OpenTelemetry setup#23099
andreiborza wants to merge 5 commits into
developfrom
ab/js-3291-otlp-integration

Conversation

@andreiborza

@andreiborza andreiborza commented Aug 6, 2026

Copy link
Copy Markdown
Member

What

Adds otlpIntegration() to @sentry/server-utils, re-exported from the server SDKs so it works with no extra install and no extra import.

  • Sentry.otlpIntegration() takes no options. Everything Sentry sends that carries trace information (errors, logs, metrics, check-ins) is attached to whatever OpenTelemetry span is active, so it lands on the same trace as the spans your own OpenTelemetry SDK exports.
  • Sentry.getOtlpTracesEndpoint(dsn) returns the URL and auth headers for Sentry's OTLP traces endpoint, to configure your own OTLPTraceExporter with.
  • Exported from node, bun, deno, cloudflare, vercel-edge, aws-serverless and google-cloud-serverless. The meta-framework SDKs inherit it through their existing export * from '@sentry/node'.
  • Adds a node-express-otlp E2E app covering a real OpenTelemetry Node SDK setup end to end.

The integration does not set up a span exporter, span processor, or tracer provider. Users keep full ownership of their OpenTelemetry pipeline. Outgoing request propagation is left to their OpenTelemetry propagator, and an active Sentry span still takes precedence, so this only changes behavior when Sentry has no span of its own.

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('__DSN__')))],
});
provider.register();

Sentry.init({
  dsn: '__DSN__',
  integrations: [Sentry.otlpIntegration()],
});

Why

Users running their own OpenTelemetry setup had no supported way to correlate Sentry telemetry with their OpenTelemetry traces. The integration lives in @sentry/server-utils because it is the shared base for every server SDK and no browser SDK, so @opentelemetry/api reaches exactly the packages that can use it and never @sentry/browser. Putting it in @sentry/core was rejected: core is not a package users depend on directly, so @sentry/core/otlp would not resolve under pnpm, and core would own an @opentelemetry/api version range on behalf of every browser and edge user.

Closes: #23082

…sting OpenTelemetry setup

Adds `otlpIntegration()` and `getOtlpTracesEndpoint()` to `@sentry/server-utils`, re-exported
from the server SDKs so no extra install or import is needed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Aug 6, 2026

Copy link
Copy Markdown

JS-3291

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

Path Size % Change Change
@sentry/browser 30.15 kB - -
@sentry/browser - with treeshaking flags 28.35 kB - -
@sentry/browser - with treeshaking flags tracing without tracing 26.66 kB - -
@sentry/browser (incl. Tracing) 47.56 kB - -
@sentry/browser (incl. Tracing + Span Streaming) 47.57 kB - -
@sentry/browser (incl. Tracing, Profiling) 52.31 kB - -
@sentry/browser (incl. Tracing, Replay) 86.93 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 76.36 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 91.66 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 104.29 kB - -
@sentry/browser (incl. Feedback) 47.48 kB - -
@sentry/browser (incl. sendFeedback) 34.98 kB - -
@sentry/browser (incl. FeedbackAsync) 40.13 kB - -
@sentry/browser (incl. Metrics) 31.22 kB - -
@sentry/browser (incl. Logs) 31.44 kB - -
@sentry/browser (incl. Metrics & Logs) 32.13 kB - -
@sentry/react 31.95 kB - -
@sentry/react (incl. Tracing) 49.81 kB - -
@sentry/vue 35.25 kB - -
@sentry/vue (incl. Tracing) 49.57 kB - -
@sentry/svelte 30.17 kB - -
CDN Bundle 32.16 kB - -
CDN Bundle (incl. Tracing) 47.83 kB - -
CDN Bundle (incl. Logs, Metrics) 33.7 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) 49.21 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) 73.03 kB - -
CDN Bundle (incl. Tracing, Replay) 85.47 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 86.79 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 91.29 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 92.61 kB - -
CDN Bundle - uncompressed 95.33 kB - -
CDN Bundle (incl. Tracing) - uncompressed 142.84 kB - -
CDN Bundle (incl. Logs, Metrics) - uncompressed 99.96 kB - -
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 146.82 kB - -
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 224.66 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 262.09 kB - -
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 266.06 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 275.8 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 279.75 kB - -
@sentry/nextjs (client) 52.39 kB - -
@sentry/sveltekit (client) 48.01 kB - -
@sentry/core/server 65.58 kB - -
@sentry/core/browser 51.82 kB - -
@sentry/node 119.28 kB - -
@sentry/node/import (ESM hook with diagnostics-channel injection) 0 B added added
@sentry/node - without tracing 83.3 kB - -
@sentry/aws-serverless 92.61 kB - -
@sentry/cloudflare (withSentry) - minified 212.61 kB - -
@sentry/cloudflare (withSentry) 524.89 kB - -

View base workflow run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d4fb98a. Configure here.

Comment thread packages/server-utils/src/otlp.ts
Logs, metrics and check-ins already flow through the same trace context as errors. Assert it
end-to-end and say so in the integration's docs.
OpenTelemetry returns a span wrapping INVALID_SPAN_CONTEXT when tracing is suppressed or when a
span is started before a tracer provider is registered. Its all-zero ids were being stamped onto
everything Sentry sends, breaking trace linkage instead of falling back to the Sentry scope.
Astro's server entry cannot `export * from '@sentry/node'` (Vite moves the exports onto `default`
in prod builds), so it enumerates them. The node-exports-test-app E2E check caught the gap.
@andreiborza
andreiborza marked this pull request as ready for review August 6, 2026 14:41
@andreiborza
andreiborza requested review from a team as code owners August 6, 2026 14:41
@andreiborza
andreiborza requested review from JPeer264, Lms24, chargome, isaacs, mydea, nicohrubec and s1gr1d and removed request for a team, isaacs, mydea and s1gr1d August 6, 2026 14:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add otlpIntegration to @sentry/server-utils

1 participant