From 72c60f17ef5307a4b495cc5ad814ab549eba14f0 Mon Sep 17 00:00:00 2001 From: Naseem <24660299+naseemkullah@users.noreply.github.com> Date: Mon, 5 Feb 2024 07:05:31 -0500 Subject: [PATCH] feat(node-sdk): add spanProcessors option (#4454) --- experimental/CHANGELOG.md | 1 + .../packages/opentelemetry-sdk-node/README.md | 6 +++++ .../opentelemetry-sdk-node/src/sdk.ts | 26 ++++++++++++++----- .../opentelemetry-sdk-node/src/types.ts | 4 ++- .../opentelemetry-sdk-node/test/sdk.test.ts | 18 ++++++++++--- 5 files changed, 45 insertions(+), 10 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 7b677d8fa9..6e3d38a000 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to experimental packages in this project will be documented ### :rocket: (Enhancement) * feat(exporter-metrics-otlp-http): add option to set the exporter aggregation preference [#4409](https://github.com/open-telemetry/opentelemetry-js/pull/4409) @AkselAllas +* feat(node-sdk): add spanProcessors option [#4454](https://github.com/open-telemetry/opentelemetry-js/pull/4454) @naseemkullah ### :bug: (Bug Fix) diff --git a/experimental/packages/opentelemetry-sdk-node/README.md b/experimental/packages/opentelemetry-sdk-node/README.md index ac828b371c..0afe166c71 100644 --- a/experimental/packages/opentelemetry-sdk-node/README.md +++ b/experimental/packages/opentelemetry-sdk-node/README.md @@ -124,6 +124,12 @@ Configure a custom sampler. By default, all traces will be sampled. ### spanProcessor +Deprecated, please use [spanProcessors](#spanprocessors) instead. + +### spanProcessors + +An array of span processors to register to the tracer provider. + ### traceExporter Configure a trace exporter. If an exporter is configured, it will be used with a [BatchSpanProcessor](../../../packages/opentelemetry-sdk-trace-base/src/platform/node/export/BatchSpanProcessor.ts). If an exporter OR span processor is not configured programatically, this package will auto setup the default `otlp` exporter with `http/protobuf` protocol with a `BatchSpanProcessor`. diff --git a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts index 39aca6f58a..c8ebfb48a7 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts @@ -75,7 +75,7 @@ export type LoggerProviderConfig = { export class NodeSDK { private _tracerProviderConfig?: { tracerConfig: NodeTracerConfig; - spanProcessor: SpanProcessor; + spanProcessors: SpanProcessor[]; contextManager?: ContextManager; textMapPropagator?: TextMapPropagator; }; @@ -130,7 +130,11 @@ export class NodeSDK { this._autoDetectResources = configuration.autoDetectResources ?? true; // If a tracer provider can be created from manual configuration, create it - if (configuration.traceExporter || configuration.spanProcessor) { + if ( + configuration.traceExporter || + configuration.spanProcessor || + configuration.spanProcessors + ) { const tracerProviderConfig: NodeTracerConfig = {}; if (configuration.sampler) { @@ -143,13 +147,21 @@ export class NodeSDK { tracerProviderConfig.idGenerator = configuration.idGenerator; } + if (configuration.spanProcessor) { + diag.warn( + "The 'spanProcessor' option is deprecated. Please use 'spanProcessors' instead." + ); + } + const spanProcessor = configuration.spanProcessor ?? new BatchSpanProcessor(configuration.traceExporter!); + const spanProcessors = configuration.spanProcessors ?? [spanProcessor]; + this.configureTracerProvider( tracerProviderConfig, - spanProcessor, + spanProcessors, configuration.contextManager, configuration.textMapPropagator ); @@ -192,13 +204,13 @@ export class NodeSDK { */ public configureTracerProvider( tracerConfig: NodeTracerConfig, - spanProcessor: SpanProcessor, + spanProcessors: SpanProcessor[], contextManager?: ContextManager, textMapPropagator?: TextMapPropagator ): void { this._tracerProviderConfig = { tracerConfig, - spanProcessor, + spanProcessors, contextManager, textMapPropagator, }; @@ -334,7 +346,9 @@ export class NodeSDK { this._tracerProvider = tracerProvider; if (this._tracerProviderConfig) { - tracerProvider.addSpanProcessor(this._tracerProviderConfig.spanProcessor); + for (const spanProcessor of this._tracerProviderConfig.spanProcessors) { + tracerProvider.addSpanProcessor(spanProcessor); + } } tracerProvider.register({ diff --git a/experimental/packages/opentelemetry-sdk-node/src/types.ts b/experimental/packages/opentelemetry-sdk-node/src/types.ts index 9292e0ae70..2ed7cae48d 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/types.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/types.ts @@ -40,7 +40,9 @@ export interface NodeSDKConfiguration { resourceDetectors: Array; sampler: Sampler; serviceName?: string; - spanProcessor: SpanProcessor; + /** @deprecated use spanProcessors instead*/ + spanProcessor?: SpanProcessor; + spanProcessors?: SpanProcessor[]; traceExporter: SpanExporter; spanLimits: SpanLimits; idGenerator: IdGenerator; diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index d6a93c8a60..8251a99984 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -200,12 +200,15 @@ describe('Node SDK', () => { delete env.OTEL_TRACES_EXPORTER; }); - it('should register a tracer provider if a span processor is provided', async () => { + it('should register a tracer provider if span processors are provided', async () => { const exporter = new ConsoleSpanExporter(); - const spanProcessor = new SimpleSpanProcessor(exporter); const sdk = new NodeSDK({ - spanProcessor, + spanProcessors: [ + new NoopSpanProcessor(), + new SimpleSpanProcessor(exporter), + new BatchSpanProcessor(exporter), + ], autoDetectResources: false, }); @@ -223,6 +226,15 @@ describe('Node SDK', () => { const apiTracerProvider = trace.getTracerProvider() as ProxyTracerProvider; assert.ok(apiTracerProvider.getDelegate() instanceof NodeTracerProvider); + + const listOfProcessors = + sdk['_tracerProvider']!['_registeredSpanProcessors']!; + + assert(sdk['_tracerProvider'] instanceof NodeTracerProvider); + assert(listOfProcessors.length === 3); + assert(listOfProcessors[0] instanceof NoopSpanProcessor); + assert(listOfProcessors[1] instanceof SimpleSpanProcessor); + assert(listOfProcessors[2] instanceof BatchSpanProcessor); }); it('should register a meter provider if a reader is provided', async () => {