feat(node-core): Add OTLP integration for node-core/light#19729
feat(node-core): Add OTLP integration for node-core/light#19729andreiborza wants to merge 5 commits intodevelopfrom
Conversation
There was a problem hiding this comment.
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:
getTraceDatachecks 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.
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>
5f20150 to
e1f9019
Compare
e1f9019 to
9e9c617
Compare
size-limit report 📦
|
| if (!span && hasExternalPropagationContext()) { | ||
| return {}; |
There was a problem hiding this comment.
q: Could this be silently breaking for some users with a custom setup?
There was a problem hiding this comment.
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
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.
|
9e9c617 to
304c86a
Compare
304c86a to
8192218
Compare
| client.on('close', () => { | ||
| void _spanProcessor?.shutdown(); | ||
| void _tracerProvider?.shutdown(); | ||
| }); |
There was a problem hiding this comment.
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.
8192218 to
6c76bcd
Compare
6c76bcd to
9f09a31
Compare
9f09a31 to
c2dc1b5
Compare
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/8DFqqLeunVtEbRWN6SnCfcJ8kjt__yomPfY01iQxSMU
Co-Authored-By: Claude claude-opus-4-6 <noreply@anthropic.com> Agent transcript: https://claudescope.sentry.dev/share/hfhxEBlY6K2-8KKuZFKgEQ9b1NahysDmjm3gxHBEbl4
Co-Authored-By: Claude claude-opus-4-6 <noreply@anthropic.com> Agent transcript: https://claudescope.sentry.dev/share/e2REiiIp0G0cM0nRx0mrVwfUpEASPpwgY10OqDoN7vI
c2dc1b5 to
52436f7
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| describe('External Propagation Context', () => { | ||
| afterEach(() => { | ||
| // Reset by registering a provider that returns undefined | ||
| registerExternalPropagationContext(() => undefined); |
There was a problem hiding this comment.
Test cleanup leaves external propagation context registered
Medium Severity
The test cleanup uses registerExternalPropagationContext(() => undefined) which keeps hasExternalPropagationContext() returning true (the function reference is not undefined). This means getTraceData() in any subsequent test without an active span will return {} instead of normal trace data, since the guard !span && hasExternalPropagationContext() evaluates to true. There's no way to truly unregister — a dedicated clear/unregister function is missing from the production API, causing this persistent leak across test suites that share a process.
Additional Locations (1)
52436f7 to
2b22df3
Compare



Added
otlpIntegrationat@sentry/node-core/light/otlpfor users who manage their own OpenTelemetry setup and want to send trace data to Sentry without adopting the full@sentry/nodeSDK.Split up for easier reviewing: