Enabling OpenTelemetry vs. Sentry instrumentation #720
Description
In order for the SDKs to support OpenTelemetry, we need to disable Sentry instrumentation and enable OpenTelemetry instrumentation. To enable otel, we introduce a new top-level option, instrumenter
, which decides what instrumentation to enable. Currently there are two options, otel
and sentry
.
Sentry.init({
instrumenter: 'otel',
});
Today we can generate performance data in two ways with a Sentry SDK.
Sentry.startTransaction()
transaction.startChild()
orspan.startChild()
The easiest solution to gate Sentry instrumentation is to go through all the call sites of Sentry.startTransaction()
and span.startChild()
done by SDK auto-instrumentation and gate them behind flags. Essentially, if the current instrumenter is Sentry, then call Sentry.startTransaction()
or span.startChild()
. This can get pretty messy though, since we have to cover each callsite with an if statement, and handle cases where spans/transactions are not defined.
let transaction;
if (instrumenter === 'sentry') {
transaction = Sentry.startTransaction();
}
The better option is probably to hide this logic inside Sentry.startTransaction()
(hub.startTransaction()
). The problem here is that this doesn't address transaction.startChild()
/span.startChild()
, since they aren't top level methods, they are instead methods on the class. We can solve this by introducing a new top level method that creates spans on the active transaction (this is being investigated here: getsentry/rfcs#28).
// starts transaction
Sentry.startTransaction(transactionContext);
// starts span around callback
// name tbd (hardest problem in CS 😢)
Sentry.trace(spanContext, callback);
Sentry.trace
will need to always put the span on the scope. If this doesn't happen we'll have to update a lot of logic to conditionally call scope.setSpan
based on if Sentry.trace
returned an undefined span.