Official Sentry SDK for OpenTelemetry

This package allows you to send your OpenTelemetry trace data to Sentry via OpenTelemetry SpanProcessors.
If you are using @sentry/node
, OpenTelemetry support is included out of the box. This package is only necessary if you
are setting up OpenTelemetry support for Sentry yourself.
Installation
npm install @sentry/opentelemetry
yarn add @sentry/opentelemetry
Note that @sentry/opentelemetry
depends on the following peer dependencies:
@opentelemetry/api
version 1.0.0
or greater
@opentelemetry/core
version 1.0.0
or greater
@opentelemetry/semantic-conventions
version 1.0.0
or greater
@opentelemetry/sdk-trace-base
version 1.0.0
or greater, or a package that implements that, like
@opentelemetry/sdk-node
.
Usage
This package exposes a few building blocks you can add to your OpenTelemetry setup in order to capture OpenTelemetry
traces to Sentry.
This is how you can use this in your app:
- Initialize Sentry, e.g.
@sentry/node
!
- Call
setupEventContextTrace(client)
- Add
SentrySampler
as sampler
- Add
SentrySpanProcessor
as span processor
- Add a context manager wrapped via
wrapContextManagerClass
- Add
SentryPropagator
as propagator
- Setup OTEL-powered async context strategy for Sentry via
setOpenTelemetryContextAsyncContextStrategy()
For example, you could set this up as follows:
import * as Sentry from '@sentry/node';
import {
SentryPropagator,
SentrySampler,
SentrySpanProcessor,
setupEventContextTrace,
wrapContextManagerClass,
setOpenTelemetryContextAsyncContextStrategy,
} from '@sentry/opentelemetry';
import { AsyncLocalStorageContextManager } from '@opentelemetry/context-async-hooks';
import { context, propagation, trace } from '@opentelemetry/api';
function setupSentry() {
Sentry.init({
dsn: 'xxx',
});
const client = Sentry.getClient();
setupEventContextTrace(client);
const provider = new BasicTracerProvider({
sampler: new SentrySampler(client),
});
provider.addSpanProcessor(new SentrySpanProcessor());
const SentryContextManager = wrapContextManagerClass(AsyncLocalStorageContextManager);
trace.setGlobalTracerProvider(provider);
propagation.setGlobalPropagator(new SentryPropagator());
context.setGlobalContextManager(new SentryContextManager());
setOpenTelemetryContextAsyncContextStrategy();
}
A full setup example can be found in
node-experimental.
Links
9.16.0
Important changes
- feat: Create a Vite plugin that injects sentryConfig into the global config (#16197)
Add a new plugin makeConfigInjectorPlugin
within our existing vite plugin that updates the global vite config with sentry options
- feat(browser): Add option to sample linked traces consistently (#16037)
This PR implements consistent sampling across traces as outlined in (#15754)
- feat(cloudflare): Add support for durable objects (#16180)
This PR introduces a new instrumentDurableObjectWithSentry
method to the SDK, which instruments durable objects. We capture both traces and errors automatically.
- feat(node): Add Prisma integration by default (#16073)
Prisma integration is enabled by default, it should work for both ESM and CJS.
- feat(react-router): Add client-side router instrumentation (#16185)
Adds client-side instrumentation for react router's HydratedRouter
. To enable it, simply replace browserTracingIntegration()
with reactRouterTracingIntegration()
in your client-side init call.
- fix(node): Avoid double-wrapping http module (#16177)
When running your application in ESM mode, there have been scenarios that resulted in the http
/https
emitting duplicate spans for incoming requests. This was apparently caused by us double-wrapping the modules for incoming request isolation.
In order to solve this problem, the modules are no longer monkey patched by us for request isolation. Instead, we register diagnosticschannel hooks to handle request isolation now.
While this is generally not expected to break anything, there is one tiny change that _may affect you if you have been relying on very specific functionality:
The ignoreOutgoingRequests
option of httpIntegration
receives the RequestOptions
as second argument. This type is not changed, however due to how the wrapping now works, we no longer pass through the full RequestOptions, but re-construct this partially based on the generated request. For the vast majority of cases, this should be fine, but for the sake of completeness, these are the only fields that may be available there going forward - other fields that may have existed before may no longer be set:
ignoreOutgoingRequests(url: string, {
method: string;
protocol: string;
host: string;
hostname: string; // same as host
path: string;
headers: OutgoingHttpHeaders;
})
Other changes
- feat(cloudflare): Add logs exports (#16165)
- feat(vercel-edge): Add logs export (#16166)
- feat(cloudflare): Read
SENTRY_RELEASE
from env
(#16201)
- feat(node): Drop
http.server
spans with 404 status by default (#16205)
- fix(browser): Respect manually set sentry tracing headers in XHR requests (#16184)
- fix(core): Respect manually set sentry tracing headers in fetch calls (#16183)
- fix(feedback): Prevent
removeFromDom()
from throwing (#16030)
- fix(node): Use class constructor in docstring for winston transport (#16167)
- fix(node): Fix vercel flushing logic & add test for it (#16208)
- fix(node): Fix 404 route handling in express 5 (#16211)
- fix(logs): Ensure logs can be flushed correctly (#16216)
- ref(core): Switch to standardized log envelope (#16133)