From 51bcdd92d36e18128291bb1357d62e7eca55a32d Mon Sep 17 00:00:00 2001 From: David Luna Date: Tue, 28 Apr 2026 17:32:44 +0200 Subject: [PATCH 01/11] chore(sdk-node): move away from sdk-trace-node --- .../test/grpc-protobuf-ts.test.ts | 6 ++--- .../test/helper.ts | 22 +++++++++---------- .../test/functionals/http-enable.test.ts | 4 ++-- .../test/functionals/http-metrics.test.ts | 4 ++-- .../test/functionals/http-package.test.ts | 4 ++-- .../test/functionals/http-sampler.test.ts | 4 ++-- .../test/functionals/https-package.test.ts | 4 ++-- .../test/integrations/http-enable.test.ts | 4 ++-- .../test/integrations/https-enable.test.ts | 4 ++-- .../opentelemetry-sdk-node/src/index.ts | 1 - .../opentelemetry-sdk-node/src/sdk.ts | 20 ++++++++++------- .../opentelemetry-sdk-node/test/sdk.test.ts | 14 ++++++------ .../opentelemetry-sdk-node/test/start.test.ts | 11 ++++------ .../opentelemetry-sdk-node/test/utils.test.ts | 2 +- package-lock.json | 1 + .../src/NodeTracerProvider.ts | 3 +++ .../src/config.ts | 3 +++ 17 files changed, 59 insertions(+), 52 deletions(-) diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/test/grpc-protobuf-ts.test.ts b/experimental/packages/opentelemetry-instrumentation-grpc/test/grpc-protobuf-ts.test.ts index 51779f04f46..100956a6fb9 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/test/grpc-protobuf-ts.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-grpc/test/grpc-protobuf-ts.test.ts @@ -13,9 +13,9 @@ import * as grpc from '@grpc/grpc-js'; import { GrpcTesterClient } from './proto/ts/fixtures/grpc-test.client'; import { InMemorySpanExporter, - NodeTracerProvider, + BasicTracerProvider, SimpleSpanProcessor, -} from '@opentelemetry/sdk-trace-node'; +} from '@opentelemetry/sdk-trace-base'; import * as protoLoader from '@grpc/proto-loader'; import * as path from 'path'; import * as assert from 'assert'; @@ -138,7 +138,7 @@ describe('#grpc-protobuf', () => { let client: GrpcTesterClient; let server: grpc.Server; let contextManager: ContextManager; - const provider = new NodeTracerProvider({ + const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/test/helper.ts b/experimental/packages/opentelemetry-instrumentation-grpc/test/helper.ts index 70200ba2395..819fc63f1e1 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/test/helper.ts +++ b/experimental/packages/opentelemetry-instrumentation-grpc/test/helper.ts @@ -6,11 +6,11 @@ import type { Attributes } from '@opentelemetry/api'; import { context, propagation, SpanKind, trace } from '@opentelemetry/api'; import { W3CTraceContextPropagator } from '@opentelemetry/core'; -import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; import type { ContextManager } from '@opentelemetry/api'; import type { ReadableSpan } from '@opentelemetry/sdk-trace-base'; import { + BasicTracerProvider, InMemorySpanExporter, SimpleSpanProcessor, } from '@opentelemetry/sdk-trace-base'; @@ -574,7 +574,7 @@ export const runTests = ( const ClientServerValidationTest = ( method: (typeof methodList)[0], - provider: NodeTracerProvider, + provider: BasicTracerProvider, checkSpans = true, attributesValidation?: { serverAttributes?: Attributes; @@ -618,7 +618,7 @@ export const runTests = ( const ErrorValidationTest = ( method: (typeof methodList)[0], - provider: NodeTracerProvider, + provider: BasicTracerProvider, checkSpans = true, attributesValidation?: { serverAttributes?: Attributes; @@ -674,7 +674,7 @@ export const runTests = ( const runTestWithAttributeValidation = ( method: (typeof methodList)[0], - provider: NodeTracerProvider, + provider: BasicTracerProvider, checkSpans = true, attributesValidation: { serverAttributes?: Attributes; @@ -692,7 +692,7 @@ export const runTests = ( const runTest = ( method: (typeof methodList)[0], - provider: NodeTracerProvider, + provider: BasicTracerProvider, checkSpans = true ) => { ClientServerValidationTest(method, provider, checkSpans); @@ -708,7 +708,7 @@ export const runTests = ( method: (typeof methodList)[0], key: string, errorCode: number, - provider: NodeTracerProvider + provider: BasicTracerProvider ) => { it(`should raise an error for client/server rootSpans: method=${method.methodName}, status=${key}`, async () => { const expectEmpty = memoryExporter.getFinishedSpans(); @@ -819,7 +819,7 @@ export const runTests = ( }; describe('enable()', () => { - const provider = new NodeTracerProvider({ + const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); beforeEach(() => { @@ -864,7 +864,7 @@ export const runTests = ( }); describe('disable()', () => { - const provider = new NodeTracerProvider({ + const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); beforeEach(() => { @@ -896,7 +896,7 @@ export const runTests = ( }); describe('Test filtering requests using metadata', () => { - const provider = new NodeTracerProvider({ + const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); beforeEach(() => { @@ -926,7 +926,7 @@ export const runTests = ( }); describe('Test filtering requests using options', () => { - const provider = new NodeTracerProvider({ + const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); const checkSpans: { [key: string]: boolean } = { @@ -1004,7 +1004,7 @@ export const runTests = ( }); describe('Test capturing metadata', () => { - const provider = new NodeTracerProvider({ + const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-enable.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-enable.test.ts index 75fe29c275c..06a773b771e 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-enable.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-enable.test.ts @@ -13,8 +13,8 @@ import { DiagConsoleLogger, INVALID_SPAN_CONTEXT, } from '@opentelemetry/api'; -import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; import { + BasicTracerProvider, InMemorySpanExporter, SimpleSpanProcessor, } from '@opentelemetry/sdk-trace-base'; @@ -90,7 +90,7 @@ const hostname = 'localhost'; const pathname = '/test'; const serverName = 'my.server.name'; const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider({ +const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); instrumentation.setTracerProvider(provider); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-metrics.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-metrics.test.ts index fc32d814a0b..91a6f5e86ea 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-metrics.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-metrics.test.ts @@ -8,7 +8,7 @@ import { InMemoryMetricExporter, MeterProvider, } from '@opentelemetry/sdk-metrics'; -import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; +import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; import { ATTR_ERROR_TYPE, ATTR_HTTP_REQUEST_METHOD, @@ -50,7 +50,7 @@ const serverPort = 22346; const protocol = 'http'; const hostname = 'localhost'; const pathname = '/test'; -const tracerProvider = new NodeTracerProvider(); +const tracerProvider = new BasicTracerProvider(); const metricsMemoryExporter = new InMemoryMetricExporter( AggregationTemporality.DELTA ); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-package.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-package.test.ts index dd0dc23b338..7b0f5c66dc0 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-package.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-package.test.ts @@ -6,8 +6,8 @@ import type { Span } from '@opentelemetry/api'; import { context, SpanKind, propagation } from '@opentelemetry/api'; import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; -import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; import { + BasicTracerProvider, InMemorySpanExporter, SimpleSpanProcessor, } from '@opentelemetry/sdk-trace-base'; @@ -41,7 +41,7 @@ describe('Packages', () => { context.disable(); }); describe('get', () => { - const provider = new NodeTracerProvider({ + const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); instrumentation.setTracerProvider(provider); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-sampler.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-sampler.test.ts index b5e861817eb..cccca1b9f89 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-sampler.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/http-sampler.test.ts @@ -11,9 +11,9 @@ import type { SpanKind, } from '@opentelemetry/api'; import { context } from '@opentelemetry/api'; -import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; import type { Sampler, SamplingResult } from '@opentelemetry/sdk-trace-base'; import { + BasicTracerProvider, InMemorySpanExporter, SamplingDecision, SimpleSpanProcessor, @@ -56,7 +56,7 @@ import * as http from 'http'; import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider({ +const provider = new BasicTracerProvider({ sampler, spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/https-package.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/https-package.test.ts index 7df39965a39..340038fb4c5 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/functionals/https-package.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/functionals/https-package.test.ts @@ -6,8 +6,8 @@ import type { Span } from '@opentelemetry/api'; import { context, SpanKind, propagation } from '@opentelemetry/api'; import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks'; -import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; import { + BasicTracerProvider, InMemorySpanExporter, SimpleSpanProcessor, } from '@opentelemetry/sdk-trace-base'; @@ -41,7 +41,7 @@ describe('Packages', () => { context.disable(); }); describe('get', () => { - const provider = new NodeTracerProvider({ + const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); instrumentation.setTracerProvider(provider); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/integrations/http-enable.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/integrations/http-enable.test.ts index 565c5a215b1..7fb7d41dc98 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/integrations/http-enable.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/integrations/http-enable.test.ts @@ -17,8 +17,8 @@ import { urlToHttpOptions } from 'url'; import { HttpInstrumentation } from '../../src/http'; import { assertSpan } from '../utils/assertSpan'; import * as utils from '../utils/utils'; -import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; import { + BasicTracerProvider, InMemorySpanExporter, SimpleSpanProcessor, } from '@opentelemetry/sdk-trace-base'; @@ -119,7 +119,7 @@ describe('HttpInstrumentation Integration tests', () => { }); }); - const provider = new NodeTracerProvider({ + const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); instrumentation.setTracerProvider(provider); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/integrations/https-enable.test.ts b/experimental/packages/opentelemetry-instrumentation-http/test/integrations/https-enable.test.ts index 9067f3da2a2..6320caa82ba 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/integrations/https-enable.test.ts +++ b/experimental/packages/opentelemetry-instrumentation-http/test/integrations/https-enable.test.ts @@ -19,8 +19,8 @@ import type { Socket } from 'net'; import { assertSpan } from '../utils/assertSpan'; import { urlToHttpOptions } from 'url'; import * as utils from '../utils/utils'; -import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; import { + BasicTracerProvider, InMemorySpanExporter, SimpleSpanProcessor, } from '@opentelemetry/sdk-trace-base'; @@ -119,7 +119,7 @@ describe('HttpsInstrumentation Integration tests', () => { done(); }); }); - const provider = new NodeTracerProvider({ + const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); instrumentation.setTracerProvider(provider); diff --git a/experimental/packages/opentelemetry-sdk-node/src/index.ts b/experimental/packages/opentelemetry-sdk-node/src/index.ts index 32dfe2432d5..dce863ecfe3 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/index.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/index.ts @@ -14,7 +14,6 @@ export * as contextBase from '@opentelemetry/api'; export * as core from '@opentelemetry/core'; export * as logs from '@opentelemetry/sdk-logs'; export * as metrics from '@opentelemetry/sdk-metrics'; -export * as node from '@opentelemetry/sdk-trace-node'; export * as resources from '@opentelemetry/resources'; export * as tracing from '@opentelemetry/sdk-trace-base'; /* eslint-enable no-restricted-syntax */ diff --git a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts index d9e865515ed..250690fe029 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/sdk.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/sdk.ts @@ -39,10 +39,14 @@ import { ConsoleMetricExporter, PeriodicExportingMetricReader, } from '@opentelemetry/sdk-metrics'; -import type { SpanProcessor } from '@opentelemetry/sdk-trace-base'; -import { BatchSpanProcessor } from '@opentelemetry/sdk-trace-base'; -import type { NodeTracerConfig } from '@opentelemetry/sdk-trace-node'; -import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; +import type { + SpanProcessor, + TracerConfig, +} from '@opentelemetry/sdk-trace-base'; +import { + BasicTracerProvider, + BatchSpanProcessor, +} from '@opentelemetry/sdk-trace-base'; import { ATTR_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; import type { NodeSDKConfiguration } from './types'; import { @@ -64,7 +68,7 @@ import { } from './utils'; type TracerProviderConfig = { - tracerConfig: NodeTracerConfig; + tracerConfig: TracerConfig; spanProcessors: SpanProcessor[]; }; @@ -160,7 +164,7 @@ export class NodeSDK { private _autoDetectResources: boolean; - private _tracerProvider?: NodeTracerProvider; + private _tracerProvider?: BasicTracerProvider; private _loggerProvider?: LoggerProvider; private _meterProvider?: MeterProvider; private _serviceName?: string; @@ -207,7 +211,7 @@ export class NodeSDK { configuration.spanProcessor || configuration.spanProcessors ) { - const tracerProviderConfig: NodeTracerConfig = {}; + const tracerProviderConfig: TracerConfig = {}; if (configuration.sampler) { tracerProviderConfig.sampler = configuration.sampler; @@ -346,7 +350,7 @@ export class NodeSDK { // Only register if there is a span processor if (spanProcessors.length > 0) { - this._tracerProvider = new NodeTracerProvider({ + this._tracerProvider = new BasicTracerProvider({ ...this._configuration, resource: this._resource, meterProvider: sdkMetricsEnabled ? this._meterProvider : undefined, diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index 1a50361d1ef..c960d133484 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -29,13 +29,13 @@ import { OTLPMetricExporter as OTLPGrpcMetricExporter } from '@opentelemetry/exp import { OTLPMetricExporter as OTLPProtoMetricExporter } from '@opentelemetry/exporter-metrics-otlp-proto'; import { OTLPMetricExporter as OTLPHttpMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'; import { PrometheusExporter as PrometheusMetricExporter } from '@opentelemetry/exporter-prometheus'; -import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; import { assertServiceInstanceIdIsUUID, assertServiceResource, } from './util/resource-assertions'; import type { IdGenerator, SpanProcessor } from '@opentelemetry/sdk-trace-base'; import { + BasicTracerProvider, ConsoleSpanExporter, SimpleSpanProcessor, BatchSpanProcessor, @@ -193,7 +193,7 @@ describe('Node SDK', () => { assert.strictEqual(setGlobalTracerProviderSpy.callCount, 1); assert.ok( setGlobalTracerProviderSpy.lastCall.args[0] instanceof - NodeTracerProvider + BasicTracerProvider ); await sdk.shutdown(); }); @@ -216,7 +216,7 @@ describe('Node SDK', () => { ); assert.ok( setGlobalTracerProviderSpy.lastCall.args[0] instanceof - NodeTracerProvider + BasicTracerProvider ); await sdk.shutdown(); }); @@ -240,7 +240,7 @@ describe('Node SDK', () => { const nodeTracerProvider = setGlobalTracerProviderSpy.lastCall.args[0]; assert.strictEqual(setGlobalTracerProviderSpy.callCount, 1); - assert.ok(nodeTracerProvider instanceof NodeTracerProvider); + assert.ok(nodeTracerProvider instanceof BasicTracerProvider); const spanProcessor = nodeTracerProvider['_activeSpanProcessor'] as any; @@ -434,7 +434,7 @@ describe('Node SDK', () => { assert.strictEqual(setGlobalTracerProviderSpy.callCount, 1); const tracerProvider = setGlobalTracerProviderSpy.lastCall.args[0]; - assert.ok(tracerProvider instanceof NodeTracerProvider); + assert.ok(tracerProvider instanceof BasicTracerProvider); assert.ok( (tracerProvider as any)._config.meterProvider instanceof MeterProvider ); @@ -474,7 +474,7 @@ describe('Node SDK', () => { assert.strictEqual(setGlobalTracerProviderSpy.callCount, 1); const tracerProvider = setGlobalTracerProviderSpy.lastCall.args[0]; - assert.ok(tracerProvider instanceof NodeTracerProvider); + assert.ok(tracerProvider instanceof BasicTracerProvider); assert.equal((tracerProvider as any)._config.meterProvider, undefined); const loggerProvider = setGlobalLoggerProviderSpy.lastCall.args[0]; @@ -1722,7 +1722,7 @@ describe('Node SDK', () => { const getSdkSpanProcessors = (sdk: NodeSDK) => { const tracerProvider = sdk['_tracerProvider']; - assert.ok(tracerProvider instanceof NodeTracerProvider); + assert.ok(tracerProvider instanceof BasicTracerProvider); const activeSpanProcessor = tracerProvider['_activeSpanProcessor']; diff --git a/experimental/packages/opentelemetry-sdk-node/test/start.test.ts b/experimental/packages/opentelemetry-sdk-node/test/start.test.ts index 2c7547709dd..e878b91041d 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/start.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/start.test.ts @@ -61,16 +61,13 @@ import { MeterProvider, PeriodicExportingMetricReader, } from '@opentelemetry/sdk-metrics'; -import type { - SpanProcessor, - NodeTracerProvider, -} from '@opentelemetry/sdk-trace-node'; -import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; +import type { SpanProcessor } from '@opentelemetry/sdk-trace-base'; import { + BasicTracerProvider, BatchSpanProcessor, ConsoleSpanExporter, SimpleSpanProcessor, -} from '@opentelemetry/sdk-trace-node'; +} from '@opentelemetry/sdk-trace-base'; describe('startNodeSDK', function () { let setGlobalLoggerProviderSpy: Sinon.SinonSpy; @@ -806,7 +803,7 @@ describe('startNodeSDK', function () { let stubLoggerInfo: Sinon.SinonStub; const getSdkSpanProcessors = () => { - const tracerProvider = trace.getTracerProvider() as NodeTracerProvider; + const tracerProvider = trace.getTracerProvider() as BasicTracerProvider; const delegateInfo = (tracerProvider as any)['_delegate']; return delegateInfo?._config?.spanProcessors as SpanProcessor[]; }; diff --git a/experimental/packages/opentelemetry-sdk-node/test/utils.test.ts b/experimental/packages/opentelemetry-sdk-node/test/utils.test.ts index decf876a94c..b80111b29da 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/utils.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/utils.test.ts @@ -35,7 +35,7 @@ import { } from '@opentelemetry/resources'; import type { LoggerProviderConfig } from '@opentelemetry/sdk-logs'; import { AggregationType, InstrumentType } from '@opentelemetry/sdk-metrics'; -import type { SpanLimits } from '@opentelemetry/sdk-trace-node'; +import type { SpanLimits } from '@opentelemetry/sdk-trace-base'; describe('getPropagatorFromEnv', function () { afterEach(() => { diff --git a/package-lock.json b/package-lock.json index 6c4e2730ba1..2fc3fa3f6e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6424,6 +6424,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "engines": { "node": ">=14" } diff --git a/packages/opentelemetry-sdk-trace-node/src/NodeTracerProvider.ts b/packages/opentelemetry-sdk-trace-node/src/NodeTracerProvider.ts index 5d7c9d893c5..e3b915d16a3 100644 --- a/packages/opentelemetry-sdk-trace-node/src/NodeTracerProvider.ts +++ b/packages/opentelemetry-sdk-trace-node/src/NodeTracerProvider.ts @@ -61,6 +61,9 @@ function setupPropagator(propagator: TextMapPropagator | null | undefined) { * Undefined values may be replaced with defaults, and * null values will be skipped. * + * @deprecated this class and package will be removed in next major (3.0) and replaced by + * the `TracerProvider` class of the future `@opentelemetry/sdk-trace` package. + * * @param config Configuration object for SDK registration */ export class NodeTracerProvider extends BasicTracerProvider { diff --git a/packages/opentelemetry-sdk-trace-node/src/config.ts b/packages/opentelemetry-sdk-trace-node/src/config.ts index 61d0ce7b316..1f5edb5ff03 100644 --- a/packages/opentelemetry-sdk-trace-node/src/config.ts +++ b/packages/opentelemetry-sdk-trace-node/src/config.ts @@ -7,5 +7,8 @@ import type { TracerConfig } from '@opentelemetry/sdk-trace-base'; /** * NodeTracerConfig provides an interface for configuring a Node Tracer. + * + * @deprecated this interface and package will be removed in next major (3.0) and replaced by + * the `TracerProviderConfig` interface of the future `@opentelemetry/sdk-trace` package. */ export type NodeTracerConfig = TracerConfig; From 866ef94352586a4ba1f1c2fd922ffde62c292d57 Mon Sep 17 00:00:00 2001 From: David Luna Date: Tue, 28 Apr 2026 19:29:09 +0200 Subject: [PATCH 02/11] chore: update changelog --- experimental/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index d6f2ec294ff..c53fd2f002e 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -26,6 +26,7 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2 ### :house: Internal * refactor(opentelemetry-exporter-prometheus): do not call enforcePrometheusNamingConvention() multiple times per metric [#6636](https://github.com/open-telemetry/opentelemetry-js/pull/6636) @cjihrig +* refactor(sdk-node): replace usage of `NodeTracerProvider` for `BasicTracerProvider` in SDK start [#6640](https://github.com/open-telemetry/opentelemetry-js/pull/6640) @david-luna ## 0.215.0 From 4f0099e3c51bb85a613c7e79e1a233af54f06928 Mon Sep 17 00:00:00 2001 From: David Luna Date: Mon, 4 May 2026 16:02:27 +0200 Subject: [PATCH 03/11] chore(sdk-trace-base): add TracerProvider class --- .../opentelemetry-sdk-node/test/sdk.test.ts | 27 +- .../opentelemetry-sdk-node/test/start.test.ts | 4 +- .../src/BasicTracerProvider.ts | 98 +-- .../src/TracerProvider.ts | 161 ++++ .../opentelemetry-sdk-trace-base/src/types.ts | 5 + .../test/common/BasicTracerProvider.test.ts | 57 +- .../test/common/MultiSpanProcessor.test.ts | 15 +- .../test/common/Tracer.test.ts | 14 +- .../test/common/TracerProvider.test.ts | 801 ++++++++++++++++++ .../common/export/TestTracingSpanExporter.ts | 9 +- .../test/node/Tracer.test.ts | 4 +- 11 files changed, 1054 insertions(+), 141 deletions(-) create mode 100644 packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts create mode 100644 packages/opentelemetry-sdk-trace-base/test/common/TracerProvider.test.ts diff --git a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts index c960d133484..2448a6b7289 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/sdk.test.ts @@ -68,7 +68,10 @@ import { OTLPTraceExporter as OTLPProtoTraceExporter } from '@opentelemetry/expo import { OTLPTraceExporter as OTLPGrpcTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc'; import { ZipkinExporter } from '@opentelemetry/exporter-zipkin'; -import { NOOP_COUNTER_METRIC } from '../../../../api/src/metrics/NoopMeter'; +import { + NOOP_COUNTER_METRIC, + NOOP_METER, +} from '../../../../api/src/metrics/NoopMeter'; import { ATTR_HOST_NAME, ATTR_PROCESS_PID } from '../src/semconv'; function assertDefaultContextManagerRegistered() { @@ -238,11 +241,13 @@ describe('Node SDK', () => { assertDefaultContextManagerRegistered(); assertDefaultPropagatorRegistered(); - const nodeTracerProvider = setGlobalTracerProviderSpy.lastCall.args[0]; + const tracerProvider = setGlobalTracerProviderSpy.lastCall.args[0]; assert.strictEqual(setGlobalTracerProviderSpy.callCount, 1); - assert.ok(nodeTracerProvider instanceof BasicTracerProvider); + assert.ok(tracerProvider instanceof BasicTracerProvider); - const spanProcessor = nodeTracerProvider['_activeSpanProcessor'] as any; + const spanProcessor = tracerProvider['_delegate'][ + '_activeSpanProcessor' + ] as any; assert.ok( spanProcessor.constructor.name === 'MultiSpanProcessor', @@ -436,7 +441,8 @@ describe('Node SDK', () => { const tracerProvider = setGlobalTracerProviderSpy.lastCall.args[0]; assert.ok(tracerProvider instanceof BasicTracerProvider); assert.ok( - (tracerProvider as any)._config.meterProvider instanceof MeterProvider + (tracerProvider as any)._delegate._config.meterProvider instanceof + MeterProvider ); const loggerProvider = setGlobalLoggerProviderSpy.lastCall.args[0]; @@ -475,7 +481,10 @@ describe('Node SDK', () => { assert.strictEqual(setGlobalTracerProviderSpy.callCount, 1); const tracerProvider = setGlobalTracerProviderSpy.lastCall.args[0]; assert.ok(tracerProvider instanceof BasicTracerProvider); - assert.equal((tracerProvider as any)._config.meterProvider, undefined); + assert.deepEqual( + (tracerProvider as any)._delegate._config.meterProvider.getMeter(), + NOOP_METER + ); const loggerProvider = setGlobalLoggerProviderSpy.lastCall.args[0]; assert.deepEqual( @@ -1724,7 +1733,8 @@ describe('Node SDK', () => { assert.ok(tracerProvider instanceof BasicTracerProvider); - const activeSpanProcessor = tracerProvider['_activeSpanProcessor']; + const activeSpanProcessor = + tracerProvider['_delegate']['_activeSpanProcessor']; assert.ok(activeSpanProcessor.constructor.name === 'MultiSpanProcessor'); @@ -1815,7 +1825,8 @@ describe('Node SDK', () => { const listOfProcessors = getSdkSpanProcessors(sdk); assert.ok( - sdk['_tracerProvider']!['_config']?.sampler instanceof AlwaysOffSampler + sdk['_tracerProvider']!['_delegate']['_config']?.sampler instanceof + AlwaysOffSampler ); assert.strictEqual(listOfProcessors.length, 1); assert.ok(listOfProcessors[0] instanceof SimpleSpanProcessor); diff --git a/experimental/packages/opentelemetry-sdk-node/test/start.test.ts b/experimental/packages/opentelemetry-sdk-node/test/start.test.ts index e878b91041d..c5939f5fa4f 100644 --- a/experimental/packages/opentelemetry-sdk-node/test/start.test.ts +++ b/experimental/packages/opentelemetry-sdk-node/test/start.test.ts @@ -351,7 +351,7 @@ describe('startNodeSDK', function () { ); const tracerProvider = trace.getTracerProvider() as BasicTracerProvider; - const delegateInfo = (tracerProvider as any)['_delegate']; + const delegateInfo = (tracerProvider as any)['_delegate']['_delegate']; assert.strictEqual(delegateInfo._config.spanProcessors.length, 5); assert.ok( @@ -804,7 +804,7 @@ describe('startNodeSDK', function () { const getSdkSpanProcessors = () => { const tracerProvider = trace.getTracerProvider() as BasicTracerProvider; - const delegateInfo = (tracerProvider as any)['_delegate']; + const delegateInfo = (tracerProvider as any)['_delegate']['_delegate']; return delegateInfo?._config?.spanProcessors as SpanProcessor[]; }; diff --git a/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts b/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts index d8a8ac22e62..8515c700dbd 100644 --- a/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts +++ b/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts @@ -3,16 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type { TracerProvider, Tracer as ApiTracer } from '@opentelemetry/api'; +import type { + TracerProvider as ApiTracerProvider, + Tracer as ApiTracer, +} from '@opentelemetry/api'; import { merge } from '@opentelemetry/core'; -import type { Resource } from '@opentelemetry/resources'; -import { defaultResource } from '@opentelemetry/resources'; -import type { SpanProcessor } from './SpanProcessor'; -import { Tracer } from './Tracer'; import { loadDefaultConfig } from './config'; -import { MultiSpanProcessor } from './MultiSpanProcessor'; import type { TracerConfig } from './types'; import { reconfigureLimits } from './utility'; +import { TracerProvider } from './TracerProvider'; export enum ForceFlushState { 'resolved', @@ -24,31 +23,15 @@ export enum ForceFlushState { /** * This class represents a basic tracer provider which platform libraries can extend */ -export class BasicTracerProvider implements TracerProvider { - private readonly _config: TracerConfig; - private readonly _tracers: Map = new Map(); - private readonly _resource: Resource; - private readonly _activeSpanProcessor: MultiSpanProcessor; - +export class BasicTracerProvider implements ApiTracerProvider { + private _delegate: TracerProvider; constructor(config: TracerConfig = {}) { const mergedConfig = merge( {}, loadDefaultConfig(), reconfigureLimits(config) ); - this._resource = mergedConfig.resource ?? defaultResource(); - - this._config = Object.assign({}, mergedConfig, { - resource: this._resource, - }); - - const spanProcessors: SpanProcessor[] = []; - - if (config.spanProcessors?.length) { - spanProcessors.push(...config.spanProcessors); - } - - this._activeSpanProcessor = new MultiSpanProcessor(spanProcessors); + this._delegate = new TracerProvider(mergedConfig); } getTracer( @@ -56,73 +39,14 @@ export class BasicTracerProvider implements TracerProvider { version?: string, options?: { schemaUrl?: string } ): ApiTracer { - const key = `${name}@${version || ''}:${options?.schemaUrl || ''}`; - if (!this._tracers.has(key)) { - this._tracers.set( - key, - new Tracer( - { name, version, schemaUrl: options?.schemaUrl }, - this._config, - this._resource, - this._activeSpanProcessor - ) - ); - } - - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return this._tracers.get(key)!; + return this._delegate.getTracer(name, version, options); } forceFlush(): Promise { - const timeout = this._config.forceFlushTimeoutMillis; - const promises = this._activeSpanProcessor['_spanProcessors'].map( - (spanProcessor: SpanProcessor) => { - return new Promise(resolve => { - let state: ForceFlushState; - const timeoutInterval = setTimeout(() => { - resolve( - new Error( - `Span processor did not completed within timeout period of ${timeout} ms` - ) - ); - state = ForceFlushState.timeout; - }, timeout); - - spanProcessor - .forceFlush() - .then(() => { - clearTimeout(timeoutInterval); - if (state !== ForceFlushState.timeout) { - state = ForceFlushState.resolved; - resolve(state); - } - }) - .catch(error => { - clearTimeout(timeoutInterval); - state = ForceFlushState.error; - resolve(error); - }); - }); - } - ); - - return new Promise((resolve, reject) => { - Promise.all(promises) - .then(results => { - const errors = results.filter( - result => result !== ForceFlushState.resolved - ); - if (errors.length > 0) { - reject(errors); - } else { - resolve(); - } - }) - .catch(error => reject([error])); - }); + return this._delegate.forceFlush(); } shutdown(): Promise { - return this._activeSpanProcessor.shutdown(); + return this._delegate.shutdown(); } } diff --git a/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts b/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts new file mode 100644 index 00000000000..84f68ca5367 --- /dev/null +++ b/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts @@ -0,0 +1,161 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import type { + TracerProvider as ApiTracerProvider, + Tracer as ApiTracer, +} from '@opentelemetry/api'; +import { createNoopMeter } from '@opentelemetry/api'; +import type { Resource } from '@opentelemetry/resources'; +import { defaultResource } from '@opentelemetry/resources'; +import type { SpanProcessor } from './SpanProcessor'; +import { Tracer } from './Tracer'; +import { MultiSpanProcessor } from './MultiSpanProcessor'; +import type { TracerProviderConfig } from './types'; +import { ParentBasedSampler } from './sampler/ParentBasedSampler'; +import { AlwaysOnSampler } from './sampler/AlwaysOnSampler'; +import { RandomIdGenerator } from './platform'; + +export enum ForceFlushState { + 'resolved', + 'timeout', + 'error', + 'unresolved', +} + +/** + * This class represents a basic tracer provider which platform libraries can extend + */ +export class TracerProvider implements ApiTracerProvider { + private readonly _config: Required; + private readonly _tracers: Map = new Map(); + private readonly _resource: Resource; + private readonly _activeSpanProcessor: MultiSpanProcessor; + + constructor(config: TracerProviderConfig = {}) { + this._config = { + resource: config.resource ?? defaultResource(), + sampler: + config.sampler ?? + new ParentBasedSampler({ + root: new AlwaysOnSampler(), + }), + forceFlushTimeoutMillis: 3000, + generalLimits: { + attributeCountLimit: config.generalLimits?.attributeCountLimit ?? 128, + attributeValueLengthLimit: + config.generalLimits?.attributeValueLengthLimit ?? Infinity, + }, + spanLimits: { + // We will check and set default value later + attributeCountLimit: config.spanLimits?.attributeCountLimit, + attributeValueLengthLimit: config.spanLimits?.attributeValueLengthLimit, + eventCountLimit: config.spanLimits?.eventCountLimit ?? 128, + linkCountLimit: config.spanLimits?.linkCountLimit ?? 128, + attributePerEventCountLimit: + config.spanLimits?.attributePerEventCountLimit ?? 128, + attributePerLinkCountLimit: + config.spanLimits?.attributePerLinkCountLimit ?? 128, + }, + idGenerator: config.idGenerator || new RandomIdGenerator(), + spanProcessors: config.spanProcessors ?? [], + meterProvider: config.meterProvider ?? { + getMeter() { + return createNoopMeter(); + }, + }, + }; + + // Ensure Span limits + if (!this._config.spanLimits.attributeValueLengthLimit) { + this._config.spanLimits.attributeValueLengthLimit = + config.generalLimits?.attributeValueLengthLimit ?? Infinity; + } + if (!this._config.spanLimits.attributeCountLimit) { + this._config.spanLimits.attributeCountLimit = + config.generalLimits?.attributeCountLimit ?? 128; + } + + this._resource = this._config.resource; + this._activeSpanProcessor = new MultiSpanProcessor( + this._config.spanProcessors + ); + } + + getTracer( + name: string, + version?: string, + options?: { schemaUrl?: string } + ): ApiTracer { + const key = `${name}@${version || ''}:${options?.schemaUrl || ''}`; + if (!this._tracers.has(key)) { + this._tracers.set( + key, + new Tracer( + { name, version, schemaUrl: options?.schemaUrl }, + this._config, + this._resource, + this._activeSpanProcessor + ) + ); + } + + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return this._tracers.get(key)!; + } + + forceFlush(): Promise { + const timeout = this._config.forceFlushTimeoutMillis; + const promises = this._activeSpanProcessor['_spanProcessors'].map( + (spanProcessor: SpanProcessor) => { + return new Promise(resolve => { + let state: ForceFlushState; + const timeoutInterval = setTimeout(() => { + resolve( + new Error( + `Span processor did not completed within timeout period of ${timeout} ms` + ) + ); + state = ForceFlushState.timeout; + }, timeout); + + spanProcessor + .forceFlush() + .then(() => { + clearTimeout(timeoutInterval); + if (state !== ForceFlushState.timeout) { + state = ForceFlushState.resolved; + resolve(state); + } + }) + .catch(error => { + clearTimeout(timeoutInterval); + state = ForceFlushState.error; + resolve(error); + }); + }); + } + ); + + return new Promise((resolve, reject) => { + Promise.all(promises) + .then(results => { + const errors = results.filter( + result => result !== ForceFlushState.resolved + ); + if (errors.length > 0) { + reject(errors); + } else { + resolve(); + } + }) + .catch(error => reject([error])); + }); + } + + shutdown(): Promise { + return this._activeSpanProcessor.shutdown(); + } +} diff --git a/packages/opentelemetry-sdk-trace-base/src/types.ts b/packages/opentelemetry-sdk-trace-base/src/types.ts index 49abc9c98b6..1d8b2272389 100644 --- a/packages/opentelemetry-sdk-trace-base/src/types.ts +++ b/packages/opentelemetry-sdk-trace-base/src/types.ts @@ -55,6 +55,11 @@ export interface TracerConfig { meterProvider?: MeterProvider; } +/** + * TracerProviderConfig provides an interface for configuring a Tracer Provider. + */ +export type TracerProviderConfig = TracerConfig; + /** * Configuration options for registering the API with the SDK. * Undefined values may be substituted for defaults, and null diff --git a/packages/opentelemetry-sdk-trace-base/test/common/BasicTracerProvider.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/BasicTracerProvider.test.ts index 64939a054de..034a1287e91 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/BasicTracerProvider.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/BasicTracerProvider.test.ts @@ -46,17 +46,21 @@ describe('BasicTracerProvider', () => { describe('constructor', () => { describe('when options not defined', () => { it('should construct an instance', () => { - const tracer = new BasicTracerProvider(); - assert.ok(tracer instanceof BasicTracerProvider); + const tracerProvider = new BasicTracerProvider(); + assert.ok(tracerProvider instanceof BasicTracerProvider); }); it('should use empty span processor by default', () => { const errorStub = sinon.spy(diag, 'error'); - const tracer = new BasicTracerProvider(); + const tracerProvider = new BasicTracerProvider(); - assert.ok(tracer['_activeSpanProcessor'] instanceof MultiSpanProcessor); + assert.ok( + tracerProvider['_delegate']['_activeSpanProcessor'] instanceof + MultiSpanProcessor + ); assert.strictEqual( - tracer['_activeSpanProcessor']['_spanProcessors'].length, + tracerProvider['_delegate']['_activeSpanProcessor']['_spanProcessors'] + .length, 0 ); sinon.assert.notCalled(errorStub); @@ -67,22 +71,27 @@ describe('BasicTracerProvider', () => { it('should use the span processors defined in the config', () => { const traceExporter = new ConsoleSpanExporter(); const spanProcessor = new SimpleSpanProcessor(traceExporter); - const tracer = new BasicTracerProvider({ + const tracerProvider = new BasicTracerProvider({ spanProcessors: [spanProcessor], }); - assert.ok(tracer['_activeSpanProcessor'] instanceof MultiSpanProcessor); assert.ok( - tracer['_activeSpanProcessor']['_spanProcessors'].length === 1 + tracerProvider['_delegate']['_activeSpanProcessor'] instanceof + MultiSpanProcessor + ); + assert.ok( + tracerProvider['_delegate']['_activeSpanProcessor']['_spanProcessors'] + .length === 1 ); assert.ok( - tracer['_activeSpanProcessor']['_spanProcessors'][0] instanceof - SimpleSpanProcessor + tracerProvider['_delegate']['_activeSpanProcessor'][ + '_spanProcessors' + ][0] instanceof SimpleSpanProcessor ); assert.ok( - tracer['_activeSpanProcessor']['_spanProcessors'][0][ - '_exporter' - ] instanceof ConsoleSpanExporter + tracerProvider['_delegate']['_activeSpanProcessor'][ + '_spanProcessors' + ][0]['_exporter'] instanceof ConsoleSpanExporter ); }); }); @@ -289,8 +298,14 @@ describe('BasicTracerProvider', () => { const tracerProvider = new BasicTracerProvider(); const tracer = tracerProvider.getTracer('default') as Tracer; const span = tracer.startSpan('my-span') as Span; - assert.strictEqual(tracer['_resource'], tracerProvider['_resource']); - assert.strictEqual(span.resource, tracerProvider['_resource']); + assert.strictEqual( + tracer['_resource'], + tracerProvider['_delegate']['_resource'] + ); + assert.strictEqual( + span.resource, + tracerProvider['_delegate']['_resource'] + ); }); it('should start a span with name and options', () => { @@ -533,7 +548,10 @@ describe('BasicTracerProvider', () => { describe('.resource', () => { it('should use the default resource when no resource is provided', function () { const tracerProvider = new BasicTracerProvider(); - assert.deepStrictEqual(tracerProvider['_resource'], defaultResource()); + assert.deepStrictEqual( + tracerProvider['_delegate']['_resource'], + defaultResource() + ); }); it('should use not use the default if resource passed', function () { @@ -541,7 +559,10 @@ describe('BasicTracerProvider', () => { const tracerProvider = new BasicTracerProvider({ resource: providedResource, }); - assert.deepStrictEqual(tracerProvider['_resource'], providedResource); + assert.deepStrictEqual( + tracerProvider['_delegate']['_resource'], + providedResource + ); }); }); @@ -549,7 +570,7 @@ describe('BasicTracerProvider', () => { it('should trigger shutdown when manually invoked', () => { const tracerProvider = new BasicTracerProvider(); const shutdownStub = sinon.stub( - tracerProvider['_activeSpanProcessor'], + tracerProvider['_delegate']['_activeSpanProcessor'], 'shutdown' ); tracerProvider.shutdown(); diff --git a/packages/opentelemetry-sdk-trace-base/test/common/MultiSpanProcessor.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/MultiSpanProcessor.test.ts index d898544d2fb..7d960b244bf 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/MultiSpanProcessor.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/MultiSpanProcessor.test.ts @@ -6,11 +6,8 @@ import * as assert from 'assert'; import * as Sinon from 'sinon'; import type { Span, SpanProcessor } from '../../src'; -import { - BasicTracerProvider, - InMemorySpanExporter, - SimpleSpanProcessor, -} from '../../src'; +import { InMemorySpanExporter, SimpleSpanProcessor } from '../../src'; +import { TracerProvider } from '../../src/TracerProvider'; import { setGlobalErrorHandler, loggingErrorHandler, @@ -62,7 +59,7 @@ describe('MultiSpanProcessor', () => { it('should handle one span processor', () => { const processor1 = new TestProcessor('sp1'); - const tracerProvider = new BasicTracerProvider({ + const tracerProvider = new TracerProvider({ spanProcessors: [processor1], }); const tracer = tracerProvider.getTracer('default'); @@ -76,7 +73,7 @@ describe('MultiSpanProcessor', () => { it('should handle one span processor with on ending', () => { TestProcessor.events = []; const processor1 = new ExtendedTestProcessor('sp1'); - const tracerProvider = new BasicTracerProvider({ + const tracerProvider = new TracerProvider({ spanProcessors: [processor1], }); const tracer = tracerProvider.getTracer('default'); @@ -95,7 +92,7 @@ describe('MultiSpanProcessor', () => { TestProcessor.events = []; const processor1 = new TestProcessor('p1'); const processor2 = new ExtendedTestProcessor('p2'); - const tracerProvider = new BasicTracerProvider({ + const tracerProvider = new TracerProvider({ spanProcessors: [processor1, processor2], }); const tracer = tracerProvider.getTracer('default'); @@ -126,7 +123,7 @@ describe('MultiSpanProcessor', () => { TestProcessor.events = []; const processor1 = new TestProcessor('p1'); const processor2 = new ExtendedTestProcessor('p2'); - const tracerProvider = new BasicTracerProvider({ + const tracerProvider = new TracerProvider({ spanProcessors: [processor1, processor2], }); const tracer = tracerProvider.getTracer('default'); diff --git a/packages/opentelemetry-sdk-trace-base/test/common/Tracer.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/Tracer.test.ts index 4ac52106e66..41629ac3ebf 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/Tracer.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/Tracer.test.ts @@ -23,19 +23,15 @@ import type { InstrumentationScope } from '@opentelemetry/core'; import { sanitizeAttributes, suppressTracing } from '@opentelemetry/core'; import * as assert from 'assert'; import type { Sampler, Span, SpanProcessor } from '../../src'; -import { - AlwaysOffSampler, - AlwaysOnSampler, - BasicTracerProvider, - SamplingDecision, -} from '../../src'; +import { AlwaysOffSampler, AlwaysOnSampler, SamplingDecision } from '../../src'; +import { TracerProvider } from '../../src/TracerProvider'; import { TestStackContextManager } from './export/TestStackContextManager'; import * as sinon from 'sinon'; import { invalidAttributes, validAttributes } from './util'; import { Tracer } from '../../src/Tracer'; describe('Tracer', () => { - const tracerProvider = new BasicTracerProvider(); + const tracerProvider = new TracerProvider(); class TestSampler implements Sampler { private readonly traceState?: TraceState; @@ -251,7 +247,7 @@ describe('Tracer', () => { const sp: SpanProcessor = new DummySpanProcessor(); const onStartSpy = sinon.spy(sp, 'onStart'); - const tp = new BasicTracerProvider({ + const tp = new TracerProvider({ spanProcessors: [sp], }); @@ -287,7 +283,7 @@ describe('Tracer', () => { const sp: SpanProcessor = new DummySpanProcessor(); const onStartSpy = sinon.spy(sp, 'onStart'); - const tp = new BasicTracerProvider({ + const tp = new TracerProvider({ spanProcessors: [sp], }); diff --git a/packages/opentelemetry-sdk-trace-base/test/common/TracerProvider.test.ts b/packages/opentelemetry-sdk-trace-base/test/common/TracerProvider.test.ts new file mode 100644 index 00000000000..303b182e6b3 --- /dev/null +++ b/packages/opentelemetry-sdk-trace-base/test/common/TracerProvider.test.ts @@ -0,0 +1,801 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import type { SpanContext } from '@opentelemetry/api'; +import { + context, + trace, + TraceFlags, + ROOT_CONTEXT, + diag, +} from '@opentelemetry/api'; +import { TraceState } from '@opentelemetry/core'; +import { + defaultResource, + resourceFromAttributes, +} from '@opentelemetry/resources'; +import { MeterProvider } from '@opentelemetry/sdk-metrics'; +import * as assert from 'assert'; +import * as sinon from 'sinon'; +import type { Span } from '../../src'; +import { + NoopSpanProcessor, + AlwaysOnSampler, + AlwaysOffSampler, + ConsoleSpanExporter, + SimpleSpanProcessor, +} from '../../src'; +import { TracerProvider } from '../../src/TracerProvider'; +import { SpanImpl } from '../../src/Span'; +import { MultiSpanProcessor } from '../../src/MultiSpanProcessor'; +import type { Tracer } from '../../src/Tracer'; +import { TestRecordOnlySampler } from './export/TestRecordOnlySampler'; +import { TestMetricReader } from './util'; + +describe('TracerProvider', () => { + beforeEach(() => { + context.disable(); + }); + + afterEach(() => { + sinon.restore(); + }); + + describe('constructor', () => { + describe('when options not defined', () => { + it('should construct an instance', () => { + const tracer = new TracerProvider(); + assert.ok(tracer instanceof TracerProvider); + }); + + it('should use empty span processor by default', () => { + const errorStub = sinon.spy(diag, 'error'); + const tracer = new TracerProvider(); + + assert.ok(tracer['_activeSpanProcessor'] instanceof MultiSpanProcessor); + assert.strictEqual( + tracer['_activeSpanProcessor']['_spanProcessors'].length, + 0 + ); + sinon.assert.notCalled(errorStub); + }); + }); + + describe('when user sets span processors', () => { + it('should use the span processors defined in the config', () => { + const traceExporter = new ConsoleSpanExporter(); + const spanProcessor = new SimpleSpanProcessor(traceExporter); + const tracer = new TracerProvider({ + spanProcessors: [spanProcessor], + }); + + assert.ok(tracer['_activeSpanProcessor'] instanceof MultiSpanProcessor); + assert.ok( + tracer['_activeSpanProcessor']['_spanProcessors'].length === 1 + ); + assert.ok( + tracer['_activeSpanProcessor']['_spanProcessors'][0] instanceof + SimpleSpanProcessor + ); + assert.ok( + tracer['_activeSpanProcessor']['_spanProcessors'][0][ + '_exporter' + ] instanceof ConsoleSpanExporter + ); + }); + }); + + describe('when "sampler" option defined', () => { + it('should have an instance with sampler', () => { + const tracer = new TracerProvider({ + sampler: new AlwaysOnSampler(), + }); + assert.ok(tracer instanceof TracerProvider); + }); + }); + + describe('generalLimits', () => { + describe('when not defined default values', () => { + it('should have tracer with default values', () => { + const tracer = new TracerProvider({}).getTracer('default') as Tracer; + assert.deepStrictEqual(tracer.getGeneralLimits(), { + attributeValueLengthLimit: Infinity, + attributeCountLimit: 128, + }); + }); + }); + + describe('when "attributeCountLimit" is defined', () => { + it('should have tracer with defined value', () => { + const tracer = new TracerProvider({ + generalLimits: { + attributeCountLimit: 100, + }, + }).getTracer('default') as Tracer; + const generalLimits = tracer.getGeneralLimits(); + assert.strictEqual(generalLimits.attributeCountLimit, 100); + }); + }); + + describe('when "attributeValueLengthLimit" is defined', () => { + it('should have tracer with defined value', () => { + const tracer = new TracerProvider({ + generalLimits: { + attributeValueLengthLimit: 10, + }, + }).getTracer('default') as Tracer; + const generalLimits = tracer.getGeneralLimits(); + assert.strictEqual(generalLimits.attributeValueLengthLimit, 10); + }); + + it('should have tracer with negative "attributeValueLengthLimit" value', () => { + const tracer = new TracerProvider({ + generalLimits: { + attributeValueLengthLimit: -10, + }, + }).getTracer('default') as Tracer; + const generalLimits = tracer.getGeneralLimits(); + assert.strictEqual(generalLimits.attributeValueLengthLimit, -10); + }); + }); + }); + + describe('spanLimits', () => { + describe('when not defined default values', () => { + it('should have tracer with default values', () => { + const tracer = new TracerProvider({}).getTracer('default') as Tracer; + assert.deepStrictEqual(tracer.getSpanLimits(), { + attributeValueLengthLimit: Infinity, + attributeCountLimit: 128, + eventCountLimit: 128, + linkCountLimit: 128, + attributePerEventCountLimit: 128, + attributePerLinkCountLimit: 128, + }); + }); + }); + + describe('when "attributeCountLimit" is defined', () => { + it('should have tracer with defined value', () => { + const tracer = new TracerProvider({ + spanLimits: { + attributeCountLimit: 100, + }, + }).getTracer('default') as Tracer; + const spanLimits = tracer.getSpanLimits(); + assert.strictEqual(spanLimits.attributeCountLimit, 100); + }); + }); + + describe('when "attributeValueLengthLimit" is defined', () => { + it('should have tracer with defined value', () => { + const tracer = new TracerProvider({ + spanLimits: { + attributeValueLengthLimit: 10, + }, + }).getTracer('default') as Tracer; + const spanLimits = tracer.getSpanLimits(); + assert.strictEqual(spanLimits.attributeValueLengthLimit, 10); + }); + + it('should have tracer with negative "attributeValueLengthLimit" value', () => { + const tracer = new TracerProvider({ + spanLimits: { + attributeValueLengthLimit: -10, + }, + }).getTracer('default') as Tracer; + const spanLimits = tracer.getSpanLimits(); + assert.strictEqual(spanLimits.attributeValueLengthLimit, -10); + }); + }); + + describe('when attribute value length limit is not defined', () => { + it('should use default value of Infinity', () => { + const tracer = new TracerProvider().getTracer('default') as Tracer; + const spanLimits = tracer.getSpanLimits(); + const generalLimits = tracer.getGeneralLimits(); + assert.strictEqual(generalLimits.attributeValueLengthLimit, Infinity); + assert.strictEqual(spanLimits.attributeValueLengthLimit, Infinity); + }); + }); + + describe('when attribute count limit is not defined', () => { + it('should use default value of 128', () => { + const tracer = new TracerProvider().getTracer('default') as Tracer; + const spanLimits = tracer.getSpanLimits(); + const generalLimits = tracer.getGeneralLimits(); + assert.strictEqual(generalLimits.attributeCountLimit, 128); + assert.strictEqual(spanLimits.attributeCountLimit, 128); + }); + }); + + describe('when "eventCountLimit" is defined', () => { + it('should have tracer with defined value', () => { + const tracer = new TracerProvider({ + spanLimits: { + eventCountLimit: 300, + }, + }).getTracer('default') as Tracer; + const spanLimits = tracer.getSpanLimits(); + assert.strictEqual(spanLimits.eventCountLimit, 300); + }); + }); + + describe('when "linkCountLimit" is defined', () => { + it('should have tracer with defined value', () => { + const tracer = new TracerProvider({ + spanLimits: { + linkCountLimit: 10, + }, + }).getTracer('default') as Tracer; + const spanLimits = tracer.getSpanLimits(); + assert.strictEqual(spanLimits.linkCountLimit, 10); + }); + }); + + describe('when only generalLimits are defined', () => { + it('should have span limits as general limits', () => { + const tracer = new TracerProvider({ + generalLimits: { + attributeValueLengthLimit: 100, + attributeCountLimit: 200, + }, + }).getTracer('default') as Tracer; + const spanLimits = tracer.getSpanLimits(); + assert.strictEqual(spanLimits.attributeValueLengthLimit, 100); + assert.strictEqual(spanLimits.attributeCountLimit, 200); + }); + }); + + describe('when both generalLimits and spanLimits defined', () => { + it('should have span limits as priority than general limits', () => { + const tracer = new TracerProvider({ + generalLimits: { + attributeValueLengthLimit: 100, + attributeCountLimit: 200, + }, + spanLimits: { + attributeValueLengthLimit: 10, + attributeCountLimit: 20, + }, + }).getTracer('default') as Tracer; + const spanLimits = tracer.getSpanLimits(); + assert.strictEqual(spanLimits.attributeValueLengthLimit, 10); + assert.strictEqual(spanLimits.attributeCountLimit, 20); + }); + }); + }); + }); + + describe('.startSpan()', () => { + it('should start a span with name only', () => { + const tracer = new TracerProvider().getTracer('default'); + const span = tracer.startSpan('my-span'); + assert.ok(span); + assert.ok(span instanceof SpanImpl); + }); + + it('should propagate resources', () => { + const tracerProvider = new TracerProvider(); + const tracer = tracerProvider.getTracer('default') as Tracer; + const span = tracer.startSpan('my-span') as Span; + assert.strictEqual(tracer['_resource'], tracerProvider['_resource']); + assert.strictEqual(span.resource, tracerProvider['_resource']); + }); + + it('should start a span with name and options', () => { + const tracer = new TracerProvider().getTracer('default'); + const span = tracer.startSpan('my-span', {}); + assert.ok(span); + assert.ok(span instanceof SpanImpl); + const context = span.spanContext(); + assert.ok(context.traceId.match(/[a-f0-9]{32}/)); + assert.ok(context.spanId.match(/[a-f0-9]{16}/)); + assert.strictEqual(context.traceFlags, TraceFlags.SAMPLED); + assert.deepStrictEqual(context.traceState, undefined); + span.end(); + }); + + it('should start a span with given attributes', () => { + const tracer = new TracerProvider().getTracer('default'); + const span = tracer.startSpan('my-span', { + attributes: { foo: 'foo', bar: 'bar' }, + }) as Span; + assert.deepStrictEqual(span.attributes, { bar: 'bar', foo: 'foo' }); + span.end(); + }); + + it('should start a span with spanoptions->attributes', () => { + const tracer = new TracerProvider().getTracer('default'); + const span = tracer.startSpan('my-span', { + attributes: { foo: 'foo', bar: 'bar' }, + }) as Span; + assert.deepStrictEqual(span.attributes, { foo: 'foo', bar: 'bar' }); + span.end(); + }); + + it('should start a span with name and parent spancontext', () => { + const tracer = new TracerProvider().getTracer('default'); + const state = new TraceState('a=1,b=2'); + + const span = tracer.startSpan( + 'my-span', + {}, + trace.setSpanContext(ROOT_CONTEXT, { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.SAMPLED, + traceState: state, + }) + ); + assert.ok(span instanceof SpanImpl); + const context = span.spanContext(); + assert.strictEqual(context.traceId, 'd4cda95b652f4a1592b449d5929fda1b'); + assert.strictEqual(context.traceFlags, TraceFlags.SAMPLED); + assert.deepStrictEqual(context.traceState, state); + span.end(); + }); + + it('should start a span with name and parent span', () => { + const tracer = new TracerProvider().getTracer('default'); + const span = tracer.startSpan('my-span'); + const childSpan = tracer.startSpan( + 'child-span', + {}, + trace.setSpan(ROOT_CONTEXT, span) + ); + const context = childSpan.spanContext(); + assert.strictEqual(context.traceId, span.spanContext().traceId); + assert.strictEqual(context.traceFlags, TraceFlags.SAMPLED); + span.end(); + childSpan.end(); + }); + + it('should create a root span when root is true', () => { + const tracer = new TracerProvider().getTracer('default'); + const span = tracer.startSpan('my-span'); + const overrideParent = tracer.startSpan('my-parent-override-span'); + const rootSpan = tracer.startSpan( + 'root-span', + { root: true }, + trace.setSpan(ROOT_CONTEXT, span) + ); + const context = rootSpan.spanContext(); + assert.notStrictEqual( + context.traceId, + overrideParent.spanContext().traceId + ); + span.end(); + rootSpan.end(); + }); + + it('should start a span with name and with invalid parent span', () => { + const tracer = new TracerProvider({ + sampler: new AlwaysOnSampler(), + }).getTracer('default'); + const span = tracer.startSpan( + 'my-span', + {}, + trace.setSpanContext( + ROOT_CONTEXT, + 'invalid-parent' as unknown as SpanContext + ) + ); + assert.ok(span instanceof SpanImpl); + assert.deepStrictEqual( + (span as Span).parentSpanContext?.spanId, + undefined + ); + }); + + it('should start a span with name and with invalid spancontext', () => { + const tracer = new TracerProvider().getTracer('default'); + const span = tracer.startSpan( + 'my-span', + {}, + trace.setSpanContext(ROOT_CONTEXT, { + traceId: '0', + spanId: '0', + traceFlags: TraceFlags.SAMPLED, + }) + ); + assert.ok(span instanceof SpanImpl); + const context = span.spanContext(); + assert.ok(context.traceId.match(/[a-f0-9]{32}/)); + assert.ok(context.spanId.match(/[a-f0-9]{16}/)); + assert.strictEqual(context.traceFlags, TraceFlags.SAMPLED); + assert.deepStrictEqual(context.traceState, undefined); + }); + + it('should return a non recording span when never sampling', () => { + const tracer = new TracerProvider({ + sampler: new AlwaysOffSampler(), + }).getTracer('default'); + const span = tracer.startSpan('my-span'); + assert.ok(!span.isRecording()); + const context = span.spanContext(); + assert.ok(context.traceId.match(/[a-f0-9]{32}/)); + assert.ok(context.spanId.match(/[a-f0-9]{16}/)); + assert.strictEqual(context.traceFlags, TraceFlags.NONE); + assert.deepStrictEqual(context.traceState, undefined); + span.end(); + }); + + it('should create real span when sampled', () => { + const tracer = new TracerProvider({ + sampler: new AlwaysOnSampler(), + }).getTracer('default'); + const span = tracer.startSpan('my-span'); + assert.ok(span instanceof SpanImpl); + assert.strictEqual(span.spanContext().traceFlags, TraceFlags.SAMPLED); + assert.strictEqual(span.isRecording(), true); + }); + + it('should assign a resource', () => { + const tracer = new TracerProvider().getTracer('default'); + const span = tracer.startSpan('my-span') as Span; + assert.ok(span); + assert.ok(span.resource); + }); + }); + + describe('.withSpan()', () => { + it('should run context with NoopContextManager context manager', done => { + const tracer = new TracerProvider().getTracer('default'); + const span = tracer.startSpan('my-span'); + context.with(trace.setSpan(context.active(), span), () => { + assert.deepStrictEqual(trace.getSpan(context.active()), undefined); + return done(); + }); + }); + }); + + describe('.forceFlush()', () => { + it('should call forceFlush on all registered span processors', done => { + sinon.restore(); + const forceFlushStub = sinon.stub( + NoopSpanProcessor.prototype, + 'forceFlush' + ); + forceFlushStub.resolves(); + + const spanProcessorOne = new NoopSpanProcessor(); + const spanProcessorTwo = new NoopSpanProcessor(); + const tracerProvider = new TracerProvider({ + spanProcessors: [spanProcessorOne, spanProcessorTwo], + }); + + tracerProvider + .forceFlush() + .then(() => { + sinon.restore(); + assert.ok(forceFlushStub.calledTwice); + done(); + }) + .catch(error => { + sinon.restore(); + done(error); + }); + }); + + it('should throw error when calling forceFlush on all registered span processors fails', done => { + sinon.restore(); + + const forceFlushStub = sinon.stub( + NoopSpanProcessor.prototype, + 'forceFlush' + ); + forceFlushStub.returns(Promise.reject('Error')); + + const spanProcessorOne = new NoopSpanProcessor(); + const spanProcessorTwo = new NoopSpanProcessor(); + const tracerProvider = new TracerProvider({ + spanProcessors: [spanProcessorOne, spanProcessorTwo], + }); + + tracerProvider + .forceFlush() + .then(() => { + sinon.restore(); + done(new Error('Successful forceFlush not expected')); + }) + .catch(_error => { + sinon.restore(); + sinon.assert.calledTwice(forceFlushStub); + done(); + }); + }); + }); + + describe('.bind()', () => { + it('should bind context with NoopContextManager context manager', done => { + const tracer = new TracerProvider().getTracer('default'); + const span = tracer.startSpan('my-span'); + const fn = () => { + assert.deepStrictEqual(trace.getSpan(context.active()), undefined); + return done(); + }; + const patchedFn = context.bind(trace.setSpan(context.active(), span), fn); + return patchedFn(); + }); + }); + + describe('.resource', () => { + it('should use the default resource when no resource is provided', function () { + const tracerProvider = new TracerProvider(); + assert.deepStrictEqual(tracerProvider['_resource'], defaultResource()); + }); + + it('should use not use the default if resource passed', function () { + const providedResource = resourceFromAttributes({ foo: 'bar' }); + const tracerProvider = new TracerProvider({ + resource: providedResource, + }); + assert.deepStrictEqual(tracerProvider['_resource'], providedResource); + }); + }); + + describe('.shutdown()', () => { + it('should trigger shutdown when manually invoked', () => { + const tracerProvider = new TracerProvider(); + const shutdownStub = sinon.stub( + tracerProvider['_activeSpanProcessor'], + 'shutdown' + ); + tracerProvider.shutdown(); + sinon.assert.calledOnce(shutdownStub); + }); + }); + + describe('TracerMetrics', () => { + it('should record metrics for sampled spans', async () => { + const metricReader = new TestMetricReader(); + const meterProvider = new MeterProvider({ + readers: [metricReader], + }); + const tracerProvider = new TracerProvider({ + meterProvider, + sampler: new AlwaysOnSampler(), + }); + const tracer = tracerProvider.getTracer('test'); + const span = tracer.startSpan('span'); + let { resourceMetrics } = await metricReader.collect(); + let metrics = resourceMetrics.scopeMetrics[0].metrics; + let spansStartedMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.started' + ); + let spansLiveMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.live' + ); + assert.ok(spansStartedMetric); + assert.strictEqual(spansStartedMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(spansStartedMetric.dataPoints[0].attributes, { + 'otel.span.parent.origin': 'none', + 'otel.span.sampling_result': 'RECORD_AND_SAMPLE', + }); + assert.ok(spansLiveMetric); + assert.strictEqual(spansLiveMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(spansLiveMetric.dataPoints[0].attributes, { + 'otel.span.sampling_result': 'RECORD_AND_SAMPLE', + }); + span.end(); + ({ resourceMetrics } = await metricReader.collect()); + metrics = resourceMetrics.scopeMetrics[0].metrics; + spansStartedMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.started' + ); + spansLiveMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.live' + ); + assert.ok(spansStartedMetric); + assert.strictEqual(spansStartedMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(spansStartedMetric.dataPoints[0].attributes, { + 'otel.span.parent.origin': 'none', + 'otel.span.sampling_result': 'RECORD_AND_SAMPLE', + }); + assert.ok(spansLiveMetric); + assert.strictEqual(spansLiveMetric.dataPoints[0].value, 0); + assert.deepStrictEqual(spansLiveMetric.dataPoints[0].attributes, { + 'otel.span.sampling_result': 'RECORD_AND_SAMPLE', + }); + }); + + it('should record metrics for record-only spans', async () => { + const metricReader = new TestMetricReader(); + const meterProvider = new MeterProvider({ + readers: [metricReader], + }); + const tracerProvider = new TracerProvider({ + meterProvider, + sampler: new TestRecordOnlySampler(), + }); + const tracer = tracerProvider.getTracer('test'); + const span = tracer.startSpan('span'); + let { resourceMetrics } = await metricReader.collect(); + let metrics = resourceMetrics.scopeMetrics[0].metrics; + let spansStartedMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.started' + ); + let spansLiveMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.live' + ); + assert.ok(spansStartedMetric); + assert.strictEqual(spansStartedMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(spansStartedMetric.dataPoints[0].attributes, { + 'otel.span.parent.origin': 'none', + 'otel.span.sampling_result': 'RECORD_ONLY', + }); + assert.ok(spansLiveMetric); + assert.strictEqual(spansLiveMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(spansLiveMetric.dataPoints[0].attributes, { + 'otel.span.sampling_result': 'RECORD_ONLY', + }); + span.end(); + ({ resourceMetrics } = await metricReader.collect()); + metrics = resourceMetrics.scopeMetrics[0].metrics; + spansStartedMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.started' + ); + spansLiveMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.live' + ); + assert.ok(spansStartedMetric); + assert.strictEqual(spansStartedMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(spansStartedMetric.dataPoints[0].attributes, { + 'otel.span.parent.origin': 'none', + 'otel.span.sampling_result': 'RECORD_ONLY', + }); + assert.ok(spansLiveMetric); + assert.strictEqual(spansLiveMetric.dataPoints[0].value, 0); + assert.deepStrictEqual(spansLiveMetric.dataPoints[0].attributes, { + 'otel.span.sampling_result': 'RECORD_ONLY', + }); + }); + + it('should record metrics for dropped spans', async () => { + const metricReader = new TestMetricReader(); + const meterProvider = new MeterProvider({ + readers: [metricReader], + }); + const tracerProvider = new TracerProvider({ + meterProvider, + sampler: new AlwaysOffSampler(), + }); + const tracer = tracerProvider.getTracer('test'); + const span = tracer.startSpan('span'); + let { resourceMetrics } = await metricReader.collect(); + let metrics = resourceMetrics.scopeMetrics[0].metrics; + let spansStartedMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.started' + ); + let spansLiveMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.live' + ); + assert.ok(spansStartedMetric); + assert.strictEqual(spansStartedMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(spansStartedMetric.dataPoints[0].attributes, { + 'otel.span.parent.origin': 'none', + 'otel.span.sampling_result': 'DROP', + }); + assert.strictEqual(spansLiveMetric, undefined); + span.end(); + ({ resourceMetrics } = await metricReader.collect()); + metrics = resourceMetrics.scopeMetrics[0].metrics; + spansStartedMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.started' + ); + spansLiveMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.live' + ); + assert.ok(spansStartedMetric); + assert.strictEqual(spansStartedMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(spansStartedMetric.dataPoints[0].attributes, { + 'otel.span.parent.origin': 'none', + 'otel.span.sampling_result': 'DROP', + }); + assert.strictEqual(spansLiveMetric, undefined); + }); + + it('should record metrics for dropped spans with remote parent', async () => { + const metricReader = new TestMetricReader(); + const meterProvider = new MeterProvider({ + readers: [metricReader], + }); + const tracerProvider = new TracerProvider({ + meterProvider, + sampler: new AlwaysOffSampler(), + }); + const tracer = tracerProvider.getTracer('test'); + const parentContext = trace.setSpanContext(context.active(), { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.SAMPLED, + isRemote: true, + }); + const span = tracer.startSpan('span', undefined, parentContext); + let { resourceMetrics } = await metricReader.collect(); + let metrics = resourceMetrics.scopeMetrics[0].metrics; + let spansStartedMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.started' + ); + let spansLiveMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.live' + ); + assert.ok(spansStartedMetric); + assert.strictEqual(spansStartedMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(spansStartedMetric.dataPoints[0].attributes, { + 'otel.span.parent.origin': 'remote', + 'otel.span.sampling_result': 'DROP', + }); + assert.strictEqual(spansLiveMetric, undefined); + span.end(); + ({ resourceMetrics } = await metricReader.collect()); + metrics = resourceMetrics.scopeMetrics[0].metrics; + spansStartedMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.started' + ); + spansLiveMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.live' + ); + assert.ok(spansStartedMetric); + assert.strictEqual(spansStartedMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(spansStartedMetric.dataPoints[0].attributes, { + 'otel.span.parent.origin': 'remote', + 'otel.span.sampling_result': 'DROP', + }); + assert.strictEqual(spansLiveMetric, undefined); + }); + + it('should record metrics for dropped spans with local parent', async () => { + const metricReader = new TestMetricReader(); + const meterProvider = new MeterProvider({ + readers: [metricReader], + }); + const tracerProvider = new TracerProvider({ + meterProvider, + sampler: new AlwaysOffSampler(), + }); + const tracer = tracerProvider.getTracer('test'); + const parentContext = trace.setSpanContext(context.active(), { + traceId: 'd4cda95b652f4a1592b449d5929fda1b', + spanId: '6e0c63257de34c92', + traceFlags: TraceFlags.SAMPLED, + isRemote: false, + }); + const span = tracer.startSpan('span', undefined, parentContext); + let { resourceMetrics } = await metricReader.collect(); + let metrics = resourceMetrics.scopeMetrics[0].metrics; + let spansStartedMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.started' + ); + let spansLiveMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.live' + ); + assert.ok(spansStartedMetric); + assert.strictEqual(spansStartedMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(spansStartedMetric.dataPoints[0].attributes, { + 'otel.span.parent.origin': 'local', + 'otel.span.sampling_result': 'DROP', + }); + assert.strictEqual(spansLiveMetric, undefined); + span.end(); + ({ resourceMetrics } = await metricReader.collect()); + metrics = resourceMetrics.scopeMetrics[0].metrics; + spansStartedMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.started' + ); + spansLiveMetric = metrics.find( + metric => metric.descriptor.name === 'otel.sdk.span.live' + ); + assert.ok(spansStartedMetric); + assert.strictEqual(spansStartedMetric.dataPoints[0].value, 1); + assert.deepStrictEqual(spansStartedMetric.dataPoints[0].attributes, { + 'otel.span.parent.origin': 'local', + 'otel.span.sampling_result': 'DROP', + }); + assert.strictEqual(spansLiveMetric, undefined); + }); + }); +}); diff --git a/packages/opentelemetry-sdk-trace-base/test/common/export/TestTracingSpanExporter.ts b/packages/opentelemetry-sdk-trace-base/test/common/export/TestTracingSpanExporter.ts index 31f5fd29682..a3a0ae044ab 100644 --- a/packages/opentelemetry-sdk-trace-base/test/common/export/TestTracingSpanExporter.ts +++ b/packages/opentelemetry-sdk-trace-base/test/common/export/TestTracingSpanExporter.ts @@ -5,11 +5,8 @@ import type { ExportResult } from '@opentelemetry/core'; import type { ReadableSpan, SpanProcessor } from '../../../src'; -import { - BasicTracerProvider, - InMemorySpanExporter, - AlwaysOnSampler, -} from '../../../src'; +import { InMemorySpanExporter, AlwaysOnSampler } from '../../../src'; +import { TracerProvider } from '../../../src/TracerProvider'; import { Tracer } from '../../../src/Tracer'; /** @@ -36,7 +33,7 @@ export class TestTracingSpanExporter extends InMemorySpanExporter { }, }; - const tracerProvider = new BasicTracerProvider({ + const tracerProvider = new TracerProvider({ spanProcessors: [spanProcessor], }); diff --git a/packages/opentelemetry-sdk-trace-base/test/node/Tracer.test.ts b/packages/opentelemetry-sdk-trace-base/test/node/Tracer.test.ts index 10c75ea478e..17718f59d06 100644 --- a/packages/opentelemetry-sdk-trace-base/test/node/Tracer.test.ts +++ b/packages/opentelemetry-sdk-trace-base/test/node/Tracer.test.ts @@ -4,12 +4,12 @@ */ import { context, TraceFlags } from '@opentelemetry/api'; import * as assert from 'assert'; -import { BasicTracerProvider } from '../../src'; +import { TracerProvider } from '../../src/TracerProvider'; import { TestStackContextManager } from '../common/export/TestStackContextManager'; import { Tracer } from '../../src/Tracer'; describe('Tracer', () => { - const tracerProvider = new BasicTracerProvider(); + const tracerProvider = new TracerProvider(); beforeEach(() => { const contextManager = new TestStackContextManager().enable(); From 49b3cfc5f26923f076d5ac46c4c2a7e59d7e9a86 Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 6 May 2026 09:41:41 +0200 Subject: [PATCH 04/11] chore: restore exports --- experimental/packages/opentelemetry-sdk-node/src/index.ts | 1 + .../opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts | 3 +++ packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts | 6 +++--- packages/opentelemetry-sdk-trace-base/src/types.ts | 4 ++-- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/experimental/packages/opentelemetry-sdk-node/src/index.ts b/experimental/packages/opentelemetry-sdk-node/src/index.ts index dce863ecfe3..32dfe2432d5 100644 --- a/experimental/packages/opentelemetry-sdk-node/src/index.ts +++ b/experimental/packages/opentelemetry-sdk-node/src/index.ts @@ -14,6 +14,7 @@ export * as contextBase from '@opentelemetry/api'; export * as core from '@opentelemetry/core'; export * as logs from '@opentelemetry/sdk-logs'; export * as metrics from '@opentelemetry/sdk-metrics'; +export * as node from '@opentelemetry/sdk-trace-node'; export * as resources from '@opentelemetry/resources'; export * as tracing from '@opentelemetry/sdk-trace-base'; /* eslint-enable no-restricted-syntax */ diff --git a/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts b/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts index 8515c700dbd..aa9aa48a4a6 100644 --- a/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts +++ b/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts @@ -22,6 +22,9 @@ export enum ForceFlushState { /** * This class represents a basic tracer provider which platform libraries can extend + * + * @deprecated this class and package will be removed in next major (3.0) and replaced by + * the `TracerProvider` class of the future `@opentelemetry/sdk-trace` package. */ export class BasicTracerProvider implements ApiTracerProvider { private _delegate: TracerProvider; diff --git a/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts b/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts index 84f68ca5367..6435bc415ce 100644 --- a/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts +++ b/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts @@ -13,7 +13,7 @@ import { defaultResource } from '@opentelemetry/resources'; import type { SpanProcessor } from './SpanProcessor'; import { Tracer } from './Tracer'; import { MultiSpanProcessor } from './MultiSpanProcessor'; -import type { TracerProviderConfig } from './types'; +import type { TracerProviderOptions } from './types'; import { ParentBasedSampler } from './sampler/ParentBasedSampler'; import { AlwaysOnSampler } from './sampler/AlwaysOnSampler'; import { RandomIdGenerator } from './platform'; @@ -29,12 +29,12 @@ export enum ForceFlushState { * This class represents a basic tracer provider which platform libraries can extend */ export class TracerProvider implements ApiTracerProvider { - private readonly _config: Required; + private readonly _config: Required; private readonly _tracers: Map = new Map(); private readonly _resource: Resource; private readonly _activeSpanProcessor: MultiSpanProcessor; - constructor(config: TracerProviderConfig = {}) { + constructor(config: TracerProviderOptions = {}) { this._config = { resource: config.resource ?? defaultResource(), sampler: diff --git a/packages/opentelemetry-sdk-trace-base/src/types.ts b/packages/opentelemetry-sdk-trace-base/src/types.ts index 1d8b2272389..a61cd16a9d8 100644 --- a/packages/opentelemetry-sdk-trace-base/src/types.ts +++ b/packages/opentelemetry-sdk-trace-base/src/types.ts @@ -56,9 +56,9 @@ export interface TracerConfig { } /** - * TracerProviderConfig provides an interface for configuring a Tracer Provider. + * TracerProviderOptions provides an interface for configuring a Tracer Provider. */ -export type TracerProviderConfig = TracerConfig; +export type TracerProviderOptions = TracerConfig; /** * Configuration options for registering the API with the SDK. From 1e7860e7c69dedaa39484ed2521058cd2d75d623 Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 6 May 2026 09:44:04 +0200 Subject: [PATCH 05/11] chore: add exports --- packages/opentelemetry-sdk-trace-base/src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/opentelemetry-sdk-trace-base/src/index.ts b/packages/opentelemetry-sdk-trace-base/src/index.ts index 453aed27bce..256fca8282f 100644 --- a/packages/opentelemetry-sdk-trace-base/src/index.ts +++ b/packages/opentelemetry-sdk-trace-base/src/index.ts @@ -4,6 +4,7 @@ */ export { BasicTracerProvider } from './BasicTracerProvider'; +export { TracerProvider } from './TracerProvider'; export { BatchSpanProcessor, RandomIdGenerator } from './platform'; export { ConsoleSpanExporter } from './export/ConsoleSpanExporter'; export { InMemorySpanExporter } from './export/InMemorySpanExporter'; @@ -27,5 +28,6 @@ export type { SDKRegistrationConfig, SpanLimits, TracerConfig, + TracerProviderOptions, } from './types'; export type { IdGenerator } from './IdGenerator'; From 78aeba6dbf8f8d846e2d86da3508d507e02276bc Mon Sep 17 00:00:00 2001 From: David Luna Date: Mon, 18 May 2026 16:48:13 +0200 Subject: [PATCH 06/11] chore: remove remainig references to sdk-trace-node --- doc/esm-support.md | 4 +-- .../README.md | 29 ++++++++++++++--- .../package.json | 1 - .../tsconfig.json | 3 -- .../package.json | 1 - .../test/integrations/double-instr.test.cjs | 4 +-- .../test/integrations/esm.test.mjs | 4 +-- .../tsconfig.json | 3 -- .../opentelemetry-sdk-node/package.json | 1 - package-lock.json | 3 -- .../opentelemetry-propagator-jaeger/README.md | 10 +++--- .../src/BasicTracerProvider.ts | 24 ++------------ .../src/TracerProvider.ts | 31 +++++++++++++++++++ 13 files changed, 68 insertions(+), 50 deletions(-) diff --git a/doc/esm-support.md b/doc/esm-support.md index e9abc70aa29..81a62f941a0 100644 --- a/doc/esm-support.md +++ b/doc/esm-support.md @@ -71,7 +71,7 @@ node --experimental-loader=@opentelemetry/instrumentation/hook.mjs --import @ope ```javascript /*telemetry.cjs*/ const { NodeSDK } = require('@opentelemetry/sdk-node'); -const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-node'); +const { ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-base'); const { getNodeAutoInstrumentations, } = require('@opentelemetry/auto-instrumentations-node'); @@ -95,7 +95,7 @@ node --require ./telemetry.cjs app.js ```typescript /*telemetry.ts | telemetry.mjs*/ import { NodeSDK } from '@opentelemetry/sdk-node'; -import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-node'; +import { ConsoleSpanExporter } from '@opentelemetry/sdk-trace-base'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; const sdk = new NodeSDK({ diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/README.md b/experimental/packages/opentelemetry-instrumentation-grpc/README.md index 5a403fae70a..8e6f365c2a5 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/README.md +++ b/experimental/packages/opentelemetry-instrumentation-grpc/README.md @@ -27,16 +27,35 @@ OpenTelemetry gRPC Instrumentation allows the user to automatically collect trac To load a specific instrumentation (**gRPC** in this case), specify it in the Node Tracer's configuration. ```javascript -const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node'); +const { BasicTracerProvider, SimpleSpanProcessor, ConsoleSpanExporter } = require('@opentelemetry/sdk-trace-base'); const { GrpcInstrumentation } = require('@opentelemetry/instrumentation-grpc'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); - -const provider = new NodeTracerProvider({ +const { AsyncLocalStorageContextManager } = require('@opentelemetry/context-async-hooks'); +const { + CompositePropagator, + W3CBaggagePropagator, + W3CTraceContextPropagator, +} = require('@opentelemetry/core'); +const { + trace, propagation, context, +} = require('@opentelemetry/api'); + +const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())] }); -provider.register(); - +// Set context manager and propagation +context.setGlobalContextManager(new AsyncLocalStorageContextManager()); +propagation.setGlobalPropagator( + new CompositePropagator({ + propagators: [ + new W3CTraceContextPropagator(), + new W3CBaggagePropagator(), + ], + }) +); + +trace.setGlobalTracerProvider(provider); registerInstrumentations({ instrumentations: [new GrpcInstrumentation()] }); diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/package.json b/experimental/packages/opentelemetry-instrumentation-grpc/package.json index 59457b1e315..c18afc6b1d4 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/package.json +++ b/experimental/packages/opentelemetry-instrumentation-grpc/package.json @@ -53,7 +53,6 @@ "@opentelemetry/context-async-hooks": "2.7.1", "@opentelemetry/core": "2.7.1", "@opentelemetry/sdk-trace-base": "2.7.1", - "@opentelemetry/sdk-trace-node": "2.7.1", "@protobuf-ts/grpc-transport": "2.11.1", "@protobuf-ts/plugin": "2.11.1", "@protobuf-ts/runtime": "2.11.1", diff --git a/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json b/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json index bca06f77e4a..8d2891d26a4 100644 --- a/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation-grpc/tsconfig.json @@ -21,9 +21,6 @@ { "path": "../../../packages/opentelemetry-sdk-trace-base" }, - { - "path": "../../../packages/opentelemetry-sdk-trace-node" - }, { "path": "../../../semantic-conventions" }, diff --git a/experimental/packages/opentelemetry-instrumentation-http/package.json b/experimental/packages/opentelemetry-instrumentation-http/package.json index 0863448d3b1..db4b28fa867 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/package.json +++ b/experimental/packages/opentelemetry-instrumentation-http/package.json @@ -52,7 +52,6 @@ "@opentelemetry/context-async-hooks": "2.7.1", "@opentelemetry/sdk-metrics": "2.7.1", "@opentelemetry/sdk-trace-base": "2.7.1", - "@opentelemetry/sdk-trace-node": "2.7.1", "@types/mocha": "10.0.10", "@types/node": "18.19.130", "@types/request-promise-native": "1.0.21", diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/integrations/double-instr.test.cjs b/experimental/packages/opentelemetry-instrumentation-http/test/integrations/double-instr.test.cjs index b434aa6528f..532f19ee77a 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/integrations/double-instr.test.cjs +++ b/experimental/packages/opentelemetry-instrumentation-http/test/integrations/double-instr.test.cjs @@ -27,7 +27,7 @@ const path = require('path'); const fs = require('fs'); const { SpanKind } = require('@opentelemetry/api'); -const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node'); +const { BasicTracerProvider } = require('@opentelemetry/sdk-trace-base'); const { InMemorySpanExporter, SimpleSpanProcessor, @@ -36,7 +36,7 @@ const { const { HttpInstrumentation } = require('../../build/src/index.js'); const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider({ +const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); const instrumentation = new HttpInstrumentation(); diff --git a/experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs b/experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs index 597dadfeda3..4c5d6f22436 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs +++ b/experimental/packages/opentelemetry-instrumentation-http/test/integrations/esm.test.mjs @@ -36,7 +36,7 @@ import { } from 'https'; // ESM import style C import { SpanKind } from '@opentelemetry/api'; -import { NodeTracerProvider } from '@opentelemetry/sdk-trace-node'; +import { BasicTracerProvider } from '@opentelemetry/sdk-trace-base'; import { InMemorySpanExporter, SimpleSpanProcessor, @@ -46,7 +46,7 @@ import { assertSpan } from '../../build/test/utils/assertSpan.js'; import { HttpInstrumentation } from '../../build/src/index.js'; const memoryExporter = new InMemorySpanExporter(); -const provider = new NodeTracerProvider({ +const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(memoryExporter)], }); const instrumentation = new HttpInstrumentation(); diff --git a/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json b/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json index a57d906b761..eba652aa39d 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json +++ b/experimental/packages/opentelemetry-instrumentation-http/tsconfig.json @@ -21,9 +21,6 @@ { "path": "../../../packages/opentelemetry-sdk-trace-base" }, - { - "path": "../../../packages/opentelemetry-sdk-trace-node" - }, { "path": "../../../packages/sdk-metrics" }, diff --git a/experimental/packages/opentelemetry-sdk-node/package.json b/experimental/packages/opentelemetry-sdk-node/package.json index f0710f255bd..7593ed51d8a 100644 --- a/experimental/packages/opentelemetry-sdk-node/package.json +++ b/experimental/packages/opentelemetry-sdk-node/package.json @@ -67,7 +67,6 @@ "@opentelemetry/sdk-logs": "0.218.0", "@opentelemetry/sdk-metrics": "2.7.1", "@opentelemetry/sdk-trace-base": "2.7.1", - "@opentelemetry/sdk-trace-node": "2.7.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { diff --git a/package-lock.json b/package-lock.json index 2ce45e0592d..2e142c2255a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -891,7 +891,6 @@ "@opentelemetry/context-async-hooks": "2.7.1", "@opentelemetry/core": "2.7.1", "@opentelemetry/sdk-trace-base": "2.7.1", - "@opentelemetry/sdk-trace-node": "2.7.1", "@protobuf-ts/grpc-transport": "2.11.1", "@protobuf-ts/plugin": "2.11.1", "@protobuf-ts/runtime": "2.11.1", @@ -927,7 +926,6 @@ "@opentelemetry/context-async-hooks": "2.7.1", "@opentelemetry/sdk-metrics": "2.7.1", "@opentelemetry/sdk-trace-base": "2.7.1", - "@opentelemetry/sdk-trace-node": "2.7.1", "@types/mocha": "10.0.10", "@types/node": "18.19.130", "@types/request-promise-native": "1.0.21", @@ -6230,7 +6228,6 @@ "dev": true, "license": "MIT", "optional": true, - "peer": true, "engines": { "node": ">=14" } diff --git a/packages/opentelemetry-propagator-jaeger/README.md b/packages/opentelemetry-propagator-jaeger/README.md index 5f681132a8e..86fc9fc6e69 100644 --- a/packages/opentelemetry-propagator-jaeger/README.md +++ b/packages/opentelemetry-propagator-jaeger/README.md @@ -24,13 +24,13 @@ Format: Example of usage: ```javascript -const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node'); +const { BasicTracerProvider } = require('@opentelemetry/sdk-trace-base'); const { JaegerPropagator } = require('@opentelemetry/propagator-jaeger'); +const { trace, propagation } = require('@opentelemetry/api'); -const provider = new NodeTracerProvider(); -provider.register({ - propagator: new JaegerPropagator() -}); +const provider = new BasicTracerProvider(); +propagation.setGlobalPropagator(new JaegerPropagator()); +trace.setGlobalTracerProvider(provider); ``` ## Baggage Notes diff --git a/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts b/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts index bcc32951829..b851d25f54b 100644 --- a/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts +++ b/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts @@ -13,11 +13,7 @@ import type { TracerConfig } from './types'; import { reconfigureLimits } from './utility'; import { TracerProvider } from './TracerProvider'; import type { InspectFn, InspectStylizeOptions } from './inspect'; -import { - formatInspect, - inspectCustom, - settledResourceAttributes, -} from './inspect'; +import { inspectCustom } from './inspect'; export enum ForceFlushState { 'resolved', @@ -64,22 +60,6 @@ export class BasicTracerProvider implements ApiTracerProvider { options: InspectStylizeOptions | undefined, inspect: InspectFn | undefined ): unknown { - const processors = this._activeSpanProcessor[ - '_spanProcessors' - ] as SpanProcessor[]; - const payload = { - resource: { attributes: settledResourceAttributes(this._resource) }, - tracers: Array.from(this._tracers.keys()), - spanProcessors: processors.map( - p => p.constructor?.name ?? 'SpanProcessor' - ), - }; - return formatInspect( - 'BasicTracerProvider', - payload, - depth, - options, - inspect - ); + return this._delegate[inspectCustom](depth, options, inspect); } } diff --git a/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts b/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts index 6435bc415ce..ab9add86aa9 100644 --- a/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts +++ b/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts @@ -17,6 +17,13 @@ import type { TracerProviderOptions } from './types'; import { ParentBasedSampler } from './sampler/ParentBasedSampler'; import { AlwaysOnSampler } from './sampler/AlwaysOnSampler'; import { RandomIdGenerator } from './platform'; +import type { InspectFn, InspectStylizeOptions } from './inspect'; +import { + formatInspect, + inspectCustom, + settledResourceAttributes, +} from './inspect'; + export enum ForceFlushState { 'resolved', @@ -158,4 +165,28 @@ export class TracerProvider implements ApiTracerProvider { shutdown(): Promise { return this._activeSpanProcessor.shutdown(); } + + [inspectCustom]( + depth: number, + options: InspectStylizeOptions | undefined, + inspect: InspectFn | undefined + ): unknown { + const processors = this._activeSpanProcessor[ + '_spanProcessors' + ] as SpanProcessor[]; + const payload = { + resource: { attributes: settledResourceAttributes(this._resource) }, + tracers: Array.from(this._tracers.keys()), + spanProcessors: processors.map( + p => p.constructor?.name ?? 'SpanProcessor' + ), + }; + return formatInspect( + 'BasicTracerProvider', + payload, + depth, + options, + inspect + ); + } } From 09b5d317c167e655917f08f28dce093eb5613246 Mon Sep 17 00:00:00 2001 From: David Luna Date: Mon, 18 May 2026 16:58:18 +0200 Subject: [PATCH 07/11] chore: put back missing dependency --- experimental/packages/opentelemetry-sdk-node/package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/experimental/packages/opentelemetry-sdk-node/package.json b/experimental/packages/opentelemetry-sdk-node/package.json index 7593ed51d8a..f0710f255bd 100644 --- a/experimental/packages/opentelemetry-sdk-node/package.json +++ b/experimental/packages/opentelemetry-sdk-node/package.json @@ -67,6 +67,7 @@ "@opentelemetry/sdk-logs": "0.218.0", "@opentelemetry/sdk-metrics": "2.7.1", "@opentelemetry/sdk-trace-base": "2.7.1", + "@opentelemetry/sdk-trace-node": "2.7.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { From 48a35b77aa2a777a2b07a68cf31f335bbfa8bda1 Mon Sep 17 00:00:00 2001 From: David Luna Date: Tue, 19 May 2026 12:31:58 +0200 Subject: [PATCH 08/11] chore: update docs --- experimental/CHANGELOG.md | 2 +- .../exporter-trace-otlp-grpc/README.md | 122 ++++++++++++++++-- .../exporter-trace-otlp-http/README.md | 27 +++- .../exporter-trace-otlp-proto/README.md | 25 +++- .../README.md | 29 ++++- .../opentelemetry-instrumentation/README.md | 10 +- .../src/BasicTracerProvider.ts | 3 - 7 files changed, 186 insertions(+), 32 deletions(-) diff --git a/experimental/CHANGELOG.md b/experimental/CHANGELOG.md index 3f1e3cb47a3..e04266475e2 100644 --- a/experimental/CHANGELOG.md +++ b/experimental/CHANGELOG.md @@ -24,6 +24,7 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2 ### :house: Internal * refactor(configuration): remove redundant env var parsing in EnvironmentConfigFactory [#6710](https://github.com/open-telemetry/opentelemetry-js/pull/6710) @MikeGoldsmith +* refactor(sdk-node): replace usage of `NodeTracerProvider` for `BasicTracerProvider` in SDK start [#6640](https://github.com/open-telemetry/opentelemetry-js/pull/6640) @david-luna ## 0.218.0 @@ -80,7 +81,6 @@ For notes on migrating to 2.x / 0.200.x see [the upgrade guide](doc/upgrade-to-2 * test(otlp-transformer): add metrics transform benchmark [#6628](https://github.com/open-telemetry/opentelemetry-js/pull/6628) @pichlermarc * refactor(opentelemetry-exporter-prometheus): do not call enforcePrometheusNamingConvention() multiple times per metric [#6636](https://github.com/open-telemetry/opentelemetry-js/pull/6636) @cjihrig -* refactor(sdk-node): replace usage of `NodeTracerProvider` for `BasicTracerProvider` in SDK start [#6640](https://github.com/open-telemetry/opentelemetry-js/pull/6640) @david-luna ## 0.215.0 diff --git a/experimental/packages/exporter-trace-otlp-grpc/README.md b/experimental/packages/exporter-trace-otlp-grpc/README.md index 617e7a1e68c..2b8a4415377 100644 --- a/experimental/packages/exporter-trace-otlp-grpc/README.md +++ b/experimental/packages/exporter-trace-otlp-grpc/README.md @@ -24,8 +24,17 @@ To see documentation and sample code for the metric exporter, see the [exporter- The OTLPTraceExporter in Node expects the URL to only be the hostname. It will not work with `/v1/traces`. ```js -const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node'); +const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc'); +const { AsyncLocalStorageContextManager } = require('@opentelemetry/context-async-hooks'); +const { + CompositePropagator, + W3CBaggagePropagator, + W3CTraceContextPropagator, +} = require('@opentelemetry/core'); +const { + trace, propagation, context, +} = require('@opentelemetry/api'); const collectorOptions = { // url is optional and can be omitted - default is http://localhost:4317 @@ -34,11 +43,22 @@ const collectorOptions = { }; const exporter = new OTLPTraceExporter(collectorOptions); -const provider = new NodeTracerProvider({ +const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] }); -provider.register(); +// Set context manager and propagation +context.setGlobalContextManager(new AsyncLocalStorageContextManager()); +propagation.setGlobalPropagator( + new CompositePropagator({ + propagators: [ + new W3CTraceContextPropagator(), + new W3CBaggagePropagator(), + ], + }) +); + +trace.setGlobalTracerProvider(provider); ['SIGINT', 'SIGTERM'].forEach(signal => { process.on(signal, () => provider.shutdown().catch(console.error)); }); @@ -47,8 +67,17 @@ provider.register(); By default, the exporter creates a secure (TLS) connection. When connecting to a local development collector without TLS, you can use an insecure connection by specifying the `http://` scheme in the URL: ```js -const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node'); +const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc'); +const { AsyncLocalStorageContextManager } = require('@opentelemetry/context-async-hooks'); +const { + CompositePropagator, + W3CBaggagePropagator, + W3CTraceContextPropagator, +} = require('@opentelemetry/core'); +const { + trace, propagation, context, +} = require('@opentelemetry/api'); const collectorOptions = { url: 'http://localhost:4317', // http:// creates an insecure connection @@ -59,7 +88,18 @@ const provider = new NodeTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] }); -provider.register(); +// Set context manager and propagation +context.setGlobalContextManager(new AsyncLocalStorageContextManager()); +propagation.setGlobalPropagator( + new CompositePropagator({ + propagators: [ + new W3CTraceContextPropagator(), + new W3CBaggagePropagator(), + ], + }) +); + +trace.setGlobalTracerProvider(provider); ``` Alternatively, you can explicitly configure insecure credentials: @@ -67,8 +107,17 @@ Alternatively, you can explicitly configure insecure credentials: ```js const grpc = require('@grpc/grpc-js'); -const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node'); +const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc'); +const { AsyncLocalStorageContextManager } = require('@opentelemetry/context-async-hooks'); +const { + CompositePropagator, + W3CBaggagePropagator, + W3CTraceContextPropagator, +} = require('@opentelemetry/core'); +const { + trace, propagation, context, +} = require('@opentelemetry/api'); const collectorOptions = { url: 'localhost:4317', @@ -80,7 +129,18 @@ const provider = new NodeTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] }); -provider.register(); +// Set context manager and propagation +context.setGlobalContextManager(new AsyncLocalStorageContextManager()); +propagation.setGlobalPropagator( + new CompositePropagator({ + propagators: [ + new W3CTraceContextPropagator(), + new W3CBaggagePropagator(), + ], + }) +); + +trace.setGlobalTracerProvider(provider); ``` To use TLS in Node.js, provide `credentials` option like so: @@ -89,8 +149,17 @@ To use TLS in Node.js, provide `credentials` option like so: const fs = require('fs'); const grpc = require('@grpc/grpc-js'); -const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node'); +const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc'); +const { AsyncLocalStorageContextManager } = require('@opentelemetry/context-async-hooks'); +const { + CompositePropagator, + W3CBaggagePropagator, + W3CTraceContextPropagator, +} = require('@opentelemetry/core'); +const { + trace, propagation, context, +} = require('@opentelemetry/api'); const collectorOptions = { // url is optional and can be omitted - default is http://localhost:4317 @@ -104,7 +173,18 @@ const provider = new NodeTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] }); -provider.register(); +// Set context manager and propagation +context.setGlobalContextManager(new AsyncLocalStorageContextManager()); +propagation.setGlobalPropagator( + new CompositePropagator({ + propagators: [ + new W3CTraceContextPropagator(), + new W3CBaggagePropagator(), + ], + }) +); + +trace.setGlobalTracerProvider(provider); ['SIGINT', 'SIGTERM'].forEach(signal => { process.on(signal, () => provider.shutdown().catch(console.error)); }); @@ -127,8 +207,17 @@ The exporter can be configured to send custom metadata with each request as in t ```js const grpc = require('@grpc/grpc-js'); -const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node'); +const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc'); +const { AsyncLocalStorageContextManager } = require('@opentelemetry/context-async-hooks'); +const { + CompositePropagator, + W3CBaggagePropagator, + W3CTraceContextPropagator, +} = require('@opentelemetry/core'); +const { + trace, propagation, context, +} = require('@opentelemetry/api'); const metadata = new grpc.Metadata(); // For instance, an API key or access token might go here. @@ -146,7 +235,18 @@ const provider = new NodeTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] }); -provider.register(); +// Set context manager and propagation +context.setGlobalContextManager(new AsyncLocalStorageContextManager()); +propagation.setGlobalPropagator( + new CompositePropagator({ + propagators: [ + new W3CTraceContextPropagator(), + new W3CBaggagePropagator(), + ], + }) +); + +trace.setGlobalTracerProvider(provider); ['SIGINT', 'SIGTERM'].forEach(signal => { process.on(signal, () => provider.shutdown().catch(console.error)); }); diff --git a/experimental/packages/exporter-trace-otlp-http/README.md b/experimental/packages/exporter-trace-otlp-http/README.md index 959d5625ee2..773f2447964 100644 --- a/experimental/packages/exporter-trace-otlp-http/README.md +++ b/experimental/packages/exporter-trace-otlp-http/README.md @@ -59,8 +59,17 @@ provider.register(); ## Traces in Node - JSON over http ```js -const { NodeTracerProvider, BatchSpanProcessor } = require('@opentelemetry/sdk-trace-node'); +const { BasicTracerProvider, BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http'); +const { AsyncLocalStorageContextManager } = require('@opentelemetry/context-async-hooks'); +const { + CompositePropagator, + W3CBaggagePropagator, + W3CTraceContextPropagator, +} = require('@opentelemetry/core'); +const { + trace, propagation, context, +} = require('@opentelemetry/api'); const collectorOptions = { url: '', // url is optional and can be omitted - default is http://localhost:4318/v1/traces @@ -71,7 +80,7 @@ const collectorOptions = { }; const exporter = new OTLPTraceExporter(collectorOptions); -const provider = new NodeTracerProvider({ +const provider = new BasicTracerProvider({ spanProcessors: [ new BatchSpanProcessor(exporter, { // The maximum queue size. After the size is reached spans are dropped. @@ -82,8 +91,18 @@ const provider = new NodeTracerProvider({ ] }); -provider.register(); - +// Set context manager and propagation +context.setGlobalContextManager(new AsyncLocalStorageContextManager()); +propagation.setGlobalPropagator( + new CompositePropagator({ + propagators: [ + new W3CTraceContextPropagator(), + new W3CBaggagePropagator(), + ], + }) +); + +trace.setGlobalTracerProvider(provider); ``` ## GRPC diff --git a/experimental/packages/exporter-trace-otlp-proto/README.md b/experimental/packages/exporter-trace-otlp-proto/README.md index 979e149e555..32a051a2b59 100644 --- a/experimental/packages/exporter-trace-otlp-proto/README.md +++ b/experimental/packages/exporter-trace-otlp-proto/README.md @@ -22,8 +22,17 @@ To see documentation and sample code for the metric exporter, see the [exporter- ## Traces in Node - PROTO over http ```js -const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node'); +const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base'); const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-proto'); +const { AsyncLocalStorageContextManager } = require('@opentelemetry/context-async-hooks'); +const { + CompositePropagator, + W3CBaggagePropagator, + W3CTraceContextPropagator, +} = require('@opentelemetry/core'); +const { + trace, propagation, context, +} = require('@opentelemetry/api'); const collectorOptions = { url: '', // url is optional and can be omitted - default is http://localhost:4318/v1/traces @@ -37,8 +46,18 @@ const provider = new NodeTracerProvider({ spanProcessors: [new SimpleSpanProcessor(exporter)] }); -provider.register(); - +// Set context manager and propagation +context.setGlobalContextManager(new AsyncLocalStorageContextManager()); +propagation.setGlobalPropagator( + new CompositePropagator({ + propagators: [ + new W3CTraceContextPropagator(), + new W3CBaggagePropagator(), + ], + }) +); + +trace.setGlobalTracerProvider(provider); ``` ## Exporter Timeout Configuration diff --git a/experimental/packages/opentelemetry-instrumentation-http/README.md b/experimental/packages/opentelemetry-instrumentation-http/README.md index e59bc45068d..1dd00c18c4a 100644 --- a/experimental/packages/opentelemetry-instrumentation-http/README.md +++ b/experimental/packages/opentelemetry-instrumentation-http/README.md @@ -30,17 +30,36 @@ To load a specific instrumentation (HTTP in this case), specify it in the Node T const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http'); const { ConsoleSpanExporter, - NodeTracerProvider, + BasicTracerProvider, SimpleSpanProcessor, -} = require('@opentelemetry/sdk-trace-node'); +} = require('@opentelemetry/sdk-trace-base'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); +const { AsyncLocalStorageContextManager } = require('@opentelemetry/context-async-hooks'); +const { + CompositePropagator, + W3CBaggagePropagator, + W3CTraceContextPropagator, +} = require('@opentelemetry/core'); +const { + trace, propagation, context, +} = require('@opentelemetry/api'); -const provider = new NodeTracerProvider({ +const provider = new BasicTracerProvider({ spanProcessors: [new SimpleSpanProcessor(new ConsoleSpanExporter())] }); -provider.register(); - +// Set context manager and propagation +context.setGlobalContextManager(new AsyncLocalStorageContextManager()); +propagation.setGlobalPropagator( + new CompositePropagator({ + propagators: [ + new W3CTraceContextPropagator(), + new W3CBaggagePropagator(), + ], + }) +); + +trace.setGlobalTracerProvider(provider); registerInstrumentations({ instrumentations: [new HttpInstrumentation()], }); diff --git a/experimental/packages/opentelemetry-instrumentation/README.md b/experimental/packages/opentelemetry-instrumentation/README.md index 92ee119c395..df4f2960e2e 100644 --- a/experimental/packages/opentelemetry-instrumentation/README.md +++ b/experimental/packages/opentelemetry-instrumentation/README.md @@ -165,16 +165,15 @@ myInstrumentation.enable(); ### NODE - Auto Loader ```javascript +const { propagation } = require('@opentelemetry/api'); const { B3Propagator } = require('@opentelemetry/propagator-b3'); const { registerInstrumentations } = require('@opentelemetry/instrumentation'); const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http'); -const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node'); +const { BasicTracerProvider } = require('@opentelemetry/sdk-trace-base'); -const tracerProvider = new NodeTracerProvider(); +const tracerProvider = new BasicTracerProvider(); -tracerProvider.register({ - propagator: new B3Propagator(), -}); +propagation.setGlobalPropagator(new B3Propagator()); registerInstrumentations({ instrumentations: [ @@ -194,6 +193,7 @@ const { registerInstrumentations } = require('@opentelemetry/instrumentation'); const { XMLHttpRequestInstrumentation } = require('@opentelemetry/instrumentation-xml-http-request'); const { WebTracerProvider } = require('@opentelemetry/sdk-trace-web'); +// XXX const tracerProvider = new WebTracerProvider(); tracerProvider.register({ diff --git a/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts b/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts index b851d25f54b..b0dae52ad91 100644 --- a/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts +++ b/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts @@ -24,9 +24,6 @@ export enum ForceFlushState { /** * This class represents a basic tracer provider which platform libraries can extend - * - * @deprecated this class and package will be removed in next major (3.0) and replaced by - * the `TracerProvider` class of the future `@opentelemetry/sdk-trace` package. */ export class BasicTracerProvider implements ApiTracerProvider { private _delegate: TracerProvider; From 86d391e19e93b28cc893867587bfd7f55bf9ddc6 Mon Sep 17 00:00:00 2001 From: David Luna Date: Tue, 19 May 2026 12:47:40 +0200 Subject: [PATCH 09/11] chore: remove internal export --- packages/opentelemetry-sdk-trace-base/src/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/opentelemetry-sdk-trace-base/src/index.ts b/packages/opentelemetry-sdk-trace-base/src/index.ts index 256fca8282f..78a77a48aaa 100644 --- a/packages/opentelemetry-sdk-trace-base/src/index.ts +++ b/packages/opentelemetry-sdk-trace-base/src/index.ts @@ -4,7 +4,6 @@ */ export { BasicTracerProvider } from './BasicTracerProvider'; -export { TracerProvider } from './TracerProvider'; export { BatchSpanProcessor, RandomIdGenerator } from './platform'; export { ConsoleSpanExporter } from './export/ConsoleSpanExporter'; export { InMemorySpanExporter } from './export/InMemorySpanExporter'; From 1b256cab428039f8943d602dac4a678754960e2b Mon Sep 17 00:00:00 2001 From: David Luna Date: Tue, 19 May 2026 21:35:26 +0200 Subject: [PATCH 10/11] chore: fix lint issue --- packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts b/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts index ab9add86aa9..df86a8e3099 100644 --- a/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts +++ b/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts @@ -24,7 +24,6 @@ import { settledResourceAttributes, } from './inspect'; - export enum ForceFlushState { 'resolved', 'timeout', From d32a7be8b52e6b9b1c1abffb0caf2f684fe94ccc Mon Sep 17 00:00:00 2001 From: David Luna Date: Wed, 20 May 2026 15:29:33 +0200 Subject: [PATCH 11/11] chore: remove unused enum --- .../src/BasicTracerProvider.ts | 7 ------- .../opentelemetry-sdk-trace-base/src/TracerProvider.ts | 2 +- packages/opentelemetry-sdk-trace-base/src/index.ts | 1 + 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts b/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts index b0dae52ad91..ffcbfa38ea5 100644 --- a/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts +++ b/packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts @@ -15,13 +15,6 @@ import { TracerProvider } from './TracerProvider'; import type { InspectFn, InspectStylizeOptions } from './inspect'; import { inspectCustom } from './inspect'; -export enum ForceFlushState { - 'resolved', - 'timeout', - 'error', - 'unresolved', -} - /** * This class represents a basic tracer provider which platform libraries can extend */ diff --git a/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts b/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts index df86a8e3099..f417ffb90d6 100644 --- a/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts +++ b/packages/opentelemetry-sdk-trace-base/src/TracerProvider.ts @@ -24,7 +24,7 @@ import { settledResourceAttributes, } from './inspect'; -export enum ForceFlushState { +enum ForceFlushState { 'resolved', 'timeout', 'error', diff --git a/packages/opentelemetry-sdk-trace-base/src/index.ts b/packages/opentelemetry-sdk-trace-base/src/index.ts index 78a77a48aaa..256fca8282f 100644 --- a/packages/opentelemetry-sdk-trace-base/src/index.ts +++ b/packages/opentelemetry-sdk-trace-base/src/index.ts @@ -4,6 +4,7 @@ */ export { BasicTracerProvider } from './BasicTracerProvider'; +export { TracerProvider } from './TracerProvider'; export { BatchSpanProcessor, RandomIdGenerator } from './platform'; export { ConsoleSpanExporter } from './export/ConsoleSpanExporter'; export { InMemorySpanExporter } from './export/InMemorySpanExporter';