Skip to content

feat(node-core): Add OTLP integration for node-core/light#19729

Open
andreiborza wants to merge 5 commits intodevelopfrom
ab/otlp-integration
Open

feat(node-core): Add OTLP integration for node-core/light#19729
andreiborza wants to merge 5 commits intodevelopfrom
ab/otlp-integration

Conversation

@andreiborza
Copy link
Member

@andreiborza andreiborza commented Mar 10, 2026

Added otlpIntegration at @sentry/node-core/light/otlp for users who manage their own OpenTelemetry setup and want to send trace data to Sentry without adopting the full @sentry/node SDK.

import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import * as Sentry from '@sentry/node-core/light';
import { otlpIntegration } from '@sentry/node-core/light/otlp';

const provider = new NodeTracerProvider();
provider.register();

Sentry.init({
  dsn: '__DSN__',
  integrations: [
    otlpIntegration({
      // Export OTel spans to Sentry via OTLP (default: true)
      setupOtlpTracesExporter: true,

      // Propagate sentry-trace/baggage headers (default: true)
      setupPropagator: true,

      // Capture span.recordException() as Sentry errors (default: false)
      captureExceptions: false,
    }),
  ],
});

Split up for easier reviewing:

  • functionality to register a function to get the propagation context from OTel: 17736bb
  • OTLP integration: 0191639
  • e2e tests: 0b797ce
  • CHANGELOG entry: c2dc1b5

@andreiborza andreiborza changed the title Ab/otlp integration feat(node-core): Add OTLP integration for node-core/light Mar 10, 2026
Copy link

@cursor cursor bot left a comment

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 2 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: Stray backtick fences break entire CHANGELOG rendering
    • Removed the stray 4-backtick sequences at lines 64 and 3802 that were creating an unintended code block wrapping the entire CHANGELOG content.
  • ✅ Fixed: getTraceData checks registration instead of actual context value
    • Changed from hasExternalPropagationContext() to getExternalPropagationContext() to check for actual context value, ensuring proper fallback to Sentry's scope-based propagation when no OTel span is active.

Create PR

Or push these changes by commenting:

@cursor push c64695209a
Preview (c64695209a)
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -61,8 +61,6 @@
   });

-````

Other Changes

  • "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott
    @@ -3799,4 +3797,3 @@

4.x

A full list of changes in the 4.x release of the SDK can be found in the 4.x Changelog.
-````

diff --git a/packages/core/src/utils/traceData.ts b/packages/core/src/utils/traceData.ts
--- a/packages/core/src/utils/traceData.ts
+++ b/packages/core/src/utils/traceData.ts
@@ -1,7 +1,7 @@
import { getAsyncContextStrategy } from '../asyncContext';
import { getMainCarrier } from '../carrier';
import type { Client } from '../client';
-import { getClient, getCurrentScope, hasExternalPropagationContext } from '../currentScopes';
+import { getClient, getCurrentScope, getExternalPropagationContext } from '../currentScopes';
import { isEnabled } from '../exports';
import type { Scope } from '../scope';
import { getDynamicSamplingContextFromScope, getDynamicSamplingContextFromSpan } from '../tracing';
@@ -49,7 +49,7 @@

// When no active span and external propagation context is registered (e.g. OTLP integration),
// return empty to let the OTel propagator handle outgoing request propagation.

  • if (!span && hasExternalPropagationContext()) {
  • if (!span && getExternalPropagationContext()) {
    return {};
    }

</details>
<sub>This Bugbot Autofix run was free. To enable autofix for future PRs, go to the <a href="https://www.cursor.com/dashboard?tab=bugbot">Cursor dashboard</a>.</sub>

</details>

@andreiborza andreiborza force-pushed the ab/otlp-integration branch 2 times, most recently from 5f20150 to e1f9019 Compare March 10, 2026 09:54
@andreiborza andreiborza force-pushed the ab/otlp-integration branch from e1f9019 to 9e9c617 Compare March 10, 2026 10:05
@github-actions
Copy link
Contributor

github-actions bot commented Mar 10, 2026

size-limit report 📦

⚠️ Warning: Base artifact is not the latest one, because the latest workflow run is not done yet. This may lead to incorrect results. Try to re-run all tests to get up to date results.

Path Size % Change Change
@sentry/browser 25.64 kB +0.07% +16 B 🔺
@sentry/browser - with treeshaking flags 24.14 kB +0.06% +13 B 🔺
@sentry/browser (incl. Tracing) 42.63 kB +0.47% +198 B 🔺
@sentry/browser (incl. Tracing, Profiling) 47.29 kB +0.43% +199 B 🔺
@sentry/browser (incl. Tracing, Replay) 81.44 kB +0.24% +193 B 🔺
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 71.02 kB +0.21% +148 B 🔺
@sentry/browser (incl. Tracing, Replay with Canvas) 86.14 kB +0.24% +199 B 🔺
@sentry/browser (incl. Tracing, Replay, Feedback) 98.4 kB +0.2% +193 B 🔺
@sentry/browser (incl. Feedback) 42.45 kB +0.04% +14 B 🔺
@sentry/browser (incl. sendFeedback) 30.32 kB +0.07% +20 B 🔺
@sentry/browser (incl. FeedbackAsync) 35.37 kB +0.06% +18 B 🔺
@sentry/browser (incl. Metrics) 26.83 kB +0.15% +39 B 🔺
@sentry/browser (incl. Logs) 26.98 kB +0.17% +44 B 🔺
@sentry/browser (incl. Metrics & Logs) 27.64 kB +0.1% +25 B 🔺
@sentry/react 27.4 kB +0.08% +20 B 🔺
@sentry/react (incl. Tracing) 44.96 kB +0.44% +194 B 🔺
@sentry/vue 30.09 kB +0.05% +14 B 🔺
@sentry/vue (incl. Tracing) 44.49 kB +0.45% +195 B 🔺
@sentry/svelte 25.67 kB +0.06% +13 B 🔺
CDN Bundle 28.18 kB +0.04% +9 B 🔺
CDN Bundle (incl. Tracing) 43.41 kB +0.36% +152 B 🔺
CDN Bundle (incl. Logs, Metrics) 29.02 kB +0.04% +9 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) 44.25 kB +0.33% +144 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) 68.1 kB +0.02% +8 B 🔺
CDN Bundle (incl. Tracing, Replay) 80.27 kB +0.17% +133 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) 81.13 kB +0.16% +126 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) 85.78 kB +0.16% +131 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) 86.67 kB +0.16% +134 B 🔺
CDN Bundle - uncompressed 82.38 kB +0.04% +26 B 🔺
CDN Bundle (incl. Tracing) - uncompressed 128.36 kB +0.23% +288 B 🔺
CDN Bundle (incl. Logs, Metrics) - uncompressed 85.21 kB +0.04% +26 B 🔺
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed 131.19 kB +0.23% +288 B 🔺
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed 208.88 kB +0.02% +26 B 🔺
CDN Bundle (incl. Tracing, Replay) - uncompressed 245.24 kB +0.12% +288 B 🔺
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed 248.06 kB +0.12% +288 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 258.15 kB +0.12% +288 B 🔺
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed 260.96 kB +0.12% +288 B 🔺
@sentry/nextjs (client) 47.38 kB +0.42% +196 B 🔺
@sentry/sveltekit (client) 43.08 kB +0.44% +186 B 🔺
@sentry/node-core 52.28 kB +0.09% +43 B 🔺
@sentry/node 174.9 kB +0.11% +189 B 🔺
@sentry/node - without tracing 97.59 kB +0.22% +210 B 🔺
@sentry/aws-serverless 113.42 kB +0.21% +230 B 🔺

View base workflow run

Comment on lines +52 to +53
if (!span && hasExternalPropagationContext()) {
return {};
Copy link
Member

Choose a reason for hiding this comment

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

q: Could this be silently breaking for some users with a custom setup?

Copy link
Member Author

Choose a reason for hiding this comment

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

I can't really think of a use-case where it might. Typically if hasExternalPropagationContext evaluates true, the user has set up tracing via OTel, so there should be a spann

@github-actions
Copy link
Contributor

github-actions bot commented Mar 10, 2026

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 9,187 - 9,183 +0%
GET With Sentry 1,723 19% 1,740 -1%
GET With Sentry (error only) 6,217 68% 6,191 +0%
POST Baseline 1,209 - 1,180 +2%
POST With Sentry 597 49% 594 +1%
POST With Sentry (error only) 1,060 88% 1,050 +1%
MYSQL Baseline 3,239 - 3,267 -1%
MYSQL With Sentry 469 14% 478 -2%
MYSQL With Sentry (error only) 2,641 82% 2,687 -2%

View base workflow run

@andreiborza andreiborza force-pushed the ab/otlp-integration branch from 304c86a to 8192218 Compare March 10, 2026 10:35
client.on('close', () => {
void _spanProcessor?.shutdown();
void _tracerProvider?.shutdown();
});
Copy link

Choose a reason for hiding this comment

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

Span flush not awaited on client flush/close

Medium Severity

The flush and close event handlers use void to discard the promises from _spanProcessor?.forceFlush() and _spanProcessor?.shutdown(). Since client.emit('flush') is synchronous and doesn't await handler return values, Sentry.flush() and Sentry.close() resolve before the OTel span processor finishes exporting spans. This can cause data loss in serverless or CLI-exit scenarios where the process ends right after flushing.

Fix in Cursor Fix in Web

@andreiborza andreiborza force-pushed the ab/otlp-integration branch from 8192218 to 6c76bcd Compare March 10, 2026 11:01
@andreiborza andreiborza force-pushed the ab/otlp-integration branch from 6c76bcd to 9f09a31 Compare March 10, 2026 13:15
Copy link

@cursor cursor bot left a comment

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.

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

andreiborza and others added 3 commits March 10, 2026 15:30
Added `otlpIntegration` at `@sentry/node-core/light/otlp` for users who manage their own OpenTelemetry setup
and want to send trace data to Sentry without adopting the full `@sentry/node` SDK.

```js
import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node';
import * as Sentry from '@sentry/node-core/light';
import { otlpIntegration } from '@sentry/node-core/light/otlp';

const provider = new NodeTracerProvider();
provider.register();

Sentry.init({
  dsn: '__DSN__',
  integrations: [
    otlpIntegration({
      setupOtlpTracesExporter: true, // Export OTel spans to Sentry via OTLP (default: true)
      setupPropagator: true, // Propagate sentry-trace/baggage headers (default: true)
      captureExceptions: false, // Capture span.recordException() as Sentry errors (default: false)
    }),
  ],
});
```

The integration links Sentry errors to OTel traces, exports spans to Sentry via OTLP, and propagates
`sentry-trace`/`baggage` headers for distributed tracing.

Co-Authored-By: Claude claude-opus-4-6 <noreply@anthropic.com>
Co-Authored-By: Claude claude-opus-4-6 <noreply@anthropic.com>

Agent transcript: https://claudescope.sentry.dev/share/e2REiiIp0G0cM0nRx0mrVwfUpEASPpwgY10OqDoN7vI
Co-Authored-By: Claude claude-opus-4-6 <noreply@anthropic.com>

Agent transcript: https://claudescope.sentry.dev/share/n3qohm5u6PIFY0ntMpDnPeO5FV_zjLEP72s_oS7b-N4
@andreiborza andreiborza force-pushed the ab/otlp-integration branch from 9f09a31 to c2dc1b5 Compare March 10, 2026 14:49
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.

2 participants