OpenTelemetry Support
You can configure your OpenTelemetry SDK to send traces and spans to Sentry.
npm install @sentry/node @sentry/opentelemetry
The minimum required version of the @sentry/node
and the @sentry/opentelemetry
package is 7.75.0
and their versions should always be aligned.
Note that @sentry/opentelemetry
depends on the following peer dependencies:
@opentelemetry/api
, version 1.0.0 or greater@opentelemetry/sdk-trace-base
, version 1.0.0 or greater, or a package that implements it, like@opentelemetry/sdk-node
There are a few steps necessary in order to ensure that your OpenTelemetry setup is fully synced with your Sentry SDK. The following code snippet walks through the needed steps.
// Sentry dependencies
const Sentry = require("@sentry/node");
const {
getClient,
setupGlobalHub,
SentryPropagator,
SentrySampler,
SentrySpanProcessor,
setupEventContextTrace,
wrapContextManagerClass,
setOpenTelemetryContextAsyncContextStrategy,
} = require("@sentry/opentelemetry");
// OpenTelemetry dependencies
const opentelemetry = require("@opentelemetry/sdk-node");
const otelApi = require("@opentelemetry/api");
const {
getNodeAutoInstrumentations,
} = require("@opentelemetry/auto-instrumentations-node");
const {
OTLPTraceExporter,
} = require("@opentelemetry/exporter-trace-otlp-grpc");
const {
AsyncLocalStorageContextManager,
} = require("@opentelemetry/context-async-hooks");
function setupSentry() {
setupGlobalHub();
// Make sure to call `Sentry.init` BEFORE initializing the OpenTelemetry SDK
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
tracesSampleRate: 1.0,
// set the instrumenter to use OpenTelemetry instead of Sentry
instrumenter: "otel",
// ...
});
const client = getClient();
setupEventContextTrace(client);
// You can wrap whatever local storage context manager you want to use
const SentryContextManager = wrapContextManagerClass(
AsyncLocalStorageContextManager
);
const sdk = new opentelemetry.NodeSDK({
// Existing config
traceExporter: new OTLPTraceExporter(),
instrumentations: [getNodeAutoInstrumentations()],
// Sentry config
spanProcessor: new SentrySpanProcessor(),
textMapPropagator: new SentryPropagator(),
contextManager: new SentryContextManager(),
sampler: new SentrySampler(client),
});
// Ensure OpenTelemetry Context & Sentry Hub/Scope is synced
setOpenTelemetryContextAsyncContextStrategy();
sdk.start();
}
setupSentry();
Note that with this setup, you can only use OpenTelemetry tracing for performance. Sentry.startTransaction()
will not work. You can either create spans via tracer.startActiveSpan()
, or use the startSpan()
/ startInactiveSpan()
methods exported from @sentry/opentelemetry
, which are just thin wrappers around the OpenTelemetry API:
import { startSpan, startInactiveSpan } from "@sentry/opentelemetry";
startSpan({ name: "my span" }, (span) => {
// span is an OpenTelemetry Span!
span.setAttribute("my_attr", "value");
// span is automatically ended at the end of the callback
});
const span = startInactiveSpan({ name: "my span" });
// do something
span.end();
If you are using the @sentry/opentelemetry-node package, you can continue to do so. Usage instructions are in the package's README. This package has a slightly easier setup process but provides a more limited connection between Sentry and OpenTelemetry than the instructions outlined above.
With Sentry’s OpenTelemetry SDK, an OpenTelemetry Span
becomes a Sentry Transaction
or Span
. The first Span
sent through the Sentry SpanProcessor
is a Transaction
, and any child Span
gets attached to the first Transaction
upon checking the parent Span
context. This is true for the OpenTelemetry root Span
and any top level Span
in the system. For example, a request sent from frontend to backend will create an OpenTelemetry root Span
with a corresponding Sentry Transaction
. The backend request will create a new Sentry Transaction
for the OpenTelemetry Span
. The Sentry Transaction
and Span
are linked as a trace for navigation and error tracking purposes.
If you need more fine grained control over Sentry, take a look at the Configuration page. In case you'd like to filter out transactions before sending them to Sentry (to get rid of health checks, for example), you may find the Filtering page helpful.
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").
- Package:
- npm:@sentry/node
- Version:
- 7.110.0
- Repository:
- https://github.com/getsentry/sentry-javascript