-
Notifications
You must be signed in to change notification settings - Fork 946
Description
Context
Context Propagation/Continues Local Storage (CLS) is not part of the language, JavaScript or the runtime Node's offering. Although there is some work in Node Core to support distributed tracing use-cases, the solutions today like node-continuation-local-storage come with significant performance overhead and issues, especially with using third-party libraries and a larger amount of async operations like Promises in user-land.
The current practice among APM providers is to hook the Node's module system, monkey patch core modules and bind async primitives via CLS in Node to achieve one line automatic tracing for their customers. This solution is acceptable for most of the Node users, but not for everyone, it's also not compatible with browser environments.
I believe the new OpenTelemetry initiative would give us the opportunity to create a simple synchronous tracer API like OpenTracing and the ability to handle CLS as a separate extension of this API.
Example API
(based on current OpenCensus APIs)
Synchronous Tracer APIs:
/**
* Start a new RootSpan to currentRootSpan
* @param options Options for tracer instance
* @returns {Span} A root span
*/
startRootSpan(options: TraceOptions): Span;
/**
* Start a new Span instance to the currentRootSpan
* @param childOf Span
* @param [options] A TraceOptions object to start a root span.
* @returns The new Span instance started
*/
startChildSpan(options?: SpanOptions): Span;
CLS interface to set the context (must be async):
/**
* Sets span to current context
* @param span Span to setup in context.
* @param fn A callback function that runs after context setup.
*/
withSpan<T>(span: Span, fn: () => T): T;
Tracer API combined with CLS:
/**
* Starts a root span and sets it to context.
* @param options Options for tracer instance
* @param fn A callback function to run after starting a root span.
*/
startWithRootSpan<T>(options: TraceOptions, fn: (root: Span) => T): T;
/**
* Start a new Span instance to the currentRootSpan
* @param childOf Span
* @param [options] A TraceOptions object to start a root span.
* @param fn A callback function to run after starting a root span.
*/
startWithChildSpan<T>(options: TraceOptions, fn: (root: Span) => T): T;
An additional benefit of this API is that using withSpan developer could chain spans in CLS and client RPCs like gRPC would start from the correct contextual child span. OpenCensus today doesn't support context propagation for child spans.