-
Notifications
You must be signed in to change notification settings - Fork 953
Description
We've been testing using tracing channels for some new instrumentations we are working on at Sentry, at first I thought the context propagation wasn't working and tried some of the stuff discussed in #1263 (comment)
However it does work with bindStore bound to the OTEL local storage and a transform function that returns the OTEL context.
// Get OTel's AsyncLocalStorage for bindStore
const otelStorage = (context as any)._getContextManager()._asyncLocalStorage;
if (otelStorage) {
channel.start.bindStore(otelStorage, (data) => {
const span = Sentry.startSpanManual(
{
// attrs...
},
(span) => span
);
data.span = span;
// Return the context to store in AsyncLocalStorage
return trace.setSpan(context.active(), span);
});
}
channel.subscribe({
// do stuff and handle span end/error
});The problematic part here is using private APIs to grab the AsyncLocalStorage
const otelStorage = (context as any)._getContextManager()._asyncLocalStorage;We think it would be great to offer a public API that let's us grab it for use-cases like that, I'm proposing either a:
- A getter
import { context, trace } from '@opentelemetry/api';
// or `__dangerouslyXXX` if we are worried about abuse
const otelStorage = context.getAsyncLocalStorage();- Or a function that preps a tracing channel for context propagation:
function tracingChannelWithOtelContext(
channel: TracingChannel,
transform: (data: any) => Span
) {
// Get OTel's AsyncLocalStorage for bindStore
const otelStorage = 'Get the storage internally somehow...';
channel.start.bindStore(otelStorage, (data) => {
const span = transform(data);
return trace.setSpan(context.active(), span);
});
return channel;
}
const channel = tracingChannelWithOtelContext(
tracingChannel('unjs.unstorage'),
(data) => {
const span = Sentry.startSpanManual(
{
// attrs...
},
(span) => span
);
return span;
}
);I'm not aware of the implications of exposing this, so I think the public function approach is a little better since it keeps the private internals private, and allows SDKs to use tracing channels. At the same time I think exposing it is helpful for other usecases around AsyncLocalStorage.