Skip to content

Commit

Permalink
feat(sdk-trace-base)!: remove BasicTracerProvider#register() to impro…
Browse files Browse the repository at this point in the history
…ve tree-shaking (#5503)
  • Loading branch information
pichlermarc authored Feb 24, 2025
1 parent 537eaf9 commit 544c409
Show file tree
Hide file tree
Showing 12 changed files with 175 additions and 177 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ For semantic convention package changes, see the [semconv CHANGELOG](packages/se
* (user-facing): `ENVIRONMENT` has been removed without replacement
* (user-facing): `RAW_ENVIRONMENT` has been removed without replacement
* (user-facing): `parseEnvironment` has been removed without replacement
* feat(sdk-trace-base): remove `BasicTracerProvider#register()` to improve tree-shaking [#5503](/~https://github.com/open-telemetry/opentelemetry-js/pull/5503) @pichlermarc
* (user-facing): `BasicTracerProvider#register()` has been removed
* to register a global propagator, please use `propagation.setGlobalPropagator()` from `@opentelemetry/api`
* to register a global context manager, please use `context.setGlobalContextManager()` from `@opentelemetry/api`
* feat!: set compilation target to ES2022 for all packages except `@opentelemetry/api`, `@opentelemetry/api-logs`, `@opentelemetry/api-events`, and `@opentelemetry/semantic-conventions` [#5456](/~https://github.com/open-telemetry/opentelemetry-js/pull/5456) @david-luna
* (user-facing): drops browser runtimes which do not support ES2022 features

Expand Down
27 changes: 17 additions & 10 deletions examples/basic-tracer-node/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,13 @@ const { resourceFromAttributes } = require('@opentelemetry/resources');
const { SEMRESATTRS_SERVICE_NAME } = require('@opentelemetry/semantic-conventions');
const { BasicTracerProvider, ConsoleSpanExporter, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
const { AsyncLocalStorageContextManager } = require("@opentelemetry/context-async-hooks");
const {CompositePropagator, W3CTraceContextPropagator, W3CBaggagePropagator} = require("@opentelemetry/core");

// Configure span processor to send spans to the exporter
const exporter = new JaegerExporter({
endpoint: 'http://localhost:14268/api/traces',
});
const provider = new BasicTracerProvider({
resource: resourceFromAttributes({
[SEMRESATTRS_SERVICE_NAME]: 'basic-service',
}),
spanProcessors: [
new SimpleSpanProcessor(exporter),
new SimpleSpanProcessor(new ConsoleSpanExporter()),
]
});

/**
* Initialize the OpenTelemetry APIs to use the BasicTracerProvider bindings.
Expand All @@ -29,7 +22,21 @@ const provider = new BasicTracerProvider({
* do not register a global tracer provider, instrumentation which calls these
* methods will receive no-op implementations.
*/
provider.register();
opentelemetry.trace.setGlobalTracerProvider(new BasicTracerProvider({
resource: resourceFromAttributes({
[SEMRESATTRS_SERVICE_NAME]: 'basic-service',
}),
spanProcessors: [
new SimpleSpanProcessor(exporter),
new SimpleSpanProcessor(new ConsoleSpanExporter()),
]
}));
opentelemetry.context.setGlobalContextManager(new AsyncLocalStorageContextManager());
opentelemetry.propagation.setGlobalPropagator(new CompositePropagator({ propagators: [
new W3CTraceContextPropagator(),
new W3CBaggagePropagator()]
}));

const tracer = opentelemetry.trace.getTracer('example-basic-tracer-node');

// Create a span. A span must be closed.
Expand Down
12 changes: 6 additions & 6 deletions experimental/packages/exporter-trace-otlp-grpc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ 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 { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc');

const collectorOptions = {
Expand All @@ -34,7 +34,7 @@ const collectorOptions = {
};

const exporter = new OTLPTraceExporter(collectorOptions);
const provider = new BasicTracerProvider({
const provider = new NodeTracerProvider({
spanProcessors: [new SimpleSpanProcessor(exporter)]
});

Expand All @@ -50,7 +50,7 @@ By default, plaintext connection is used. In order to use TLS in Node.js, provid
const fs = require('fs');
const grpc = require('@grpc/grpc-js');

const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc');

const collectorOptions = {
Expand All @@ -61,7 +61,7 @@ const collectorOptions = {
};

const exporter = new OTLPTraceExporter(collectorOptions);
const provider = new BasicTracerProvider({
const provider = new NodeTracerProvider({
spanProcessors: [new SimpleSpanProcessor(exporter)]
});

Expand All @@ -88,7 +88,7 @@ The exporter can be configured to send custom metadata with each request as in t
```js
const grpc = require('@grpc/grpc-js');

const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc');

const metadata = new grpc.Metadata();
Expand All @@ -103,7 +103,7 @@ const collectorOptions = {
};

const exporter = new OTLPTraceExporter(collectorOptions);
const provider = new BasicTracerProvider({
const provider = new NodeTracerProvider({
spanProcessors: [new SimpleSpanProcessor(exporter)]
});

Expand Down
4 changes: 2 additions & 2 deletions experimental/packages/exporter-trace-otlp-http/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ provider.register();
## Traces in Node - JSON over http

```js
const { BasicTracerProvider, BatchSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { NodeTracerProvider, BatchSpanProcessor } = require('@opentelemetry/sdk-trace-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');

const collectorOptions = {
Expand All @@ -71,7 +71,7 @@ const collectorOptions = {
};

const exporter = new OTLPTraceExporter(collectorOptions);
const provider = new BasicTracerProvider({
const provider = new NodeTracerProvider({
spanProcessors: [
new BatchSpanProcessor(exporter, {
// The maximum queue size. After the size is reached spans are dropped.
Expand Down
4 changes: 2 additions & 2 deletions experimental/packages/exporter-trace-otlp-proto/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ To see documentation and sample code for the metric exporter, see the [exporter-
## Traces in Node - PROTO over http

```js
const { BasicTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
const { NodeTracerProvider, SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-proto');

const collectorOptions = {
Expand All @@ -33,7 +33,7 @@ const collectorOptions = {
};

const exporter = new OTLPTraceExporter(collectorOptions);
const provider = new BasicTracerProvider({
const provider = new NodeTracerProvider({
spanProcessors: [new SimpleSpanProcessor(exporter)]
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@ propagation.setGlobalPropagator(new W3CTraceContextPropagator());
// set global context manager
context.setGlobalContextManager(new AsyncHooksContextManager());

// Create a provider for activating and tracking spans
const tracerProvider = new BasicTracerProvider();

// Register the tracer
tracerProvider.register();
// set global tracer provider
trace.setGlobalTracerProvider(new BasicTracerProvider());

// Get a tracer
const tracer = trace.getTracer("w3c-tests");
Expand Down
17 changes: 12 additions & 5 deletions packages/opentelemetry-sdk-trace-base/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ The `tracing` module contains the foundation for all tracing SDKs of [openteleme

Used standalone, this module provides methods for manual instrumentation of code, offering full control over span creation for client-side JavaScript (browser) and Node.js.

It does **not** provide automated instrumentation of known libraries, context propagation for asynchronous invocations or distributed-context out-of-the-box.
It does **not** provide automated instrumentation of known libraries, context propagation or distributed-context out-of-the-box.

For automated instrumentation for Node.js, please see
For a `TracerProvider` that includes default context management and propagation for Node.js, please see
[@opentelemetry/sdk-trace-node](/~https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node).

For a `TracerProvider` that includes default context management and propagation for Browser, please see
[@opentelemetry/sdk-trace-web](/~https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-web).

## Installation

```bash
Expand All @@ -22,16 +25,20 @@ npm install --save @opentelemetry/sdk-trace-base
## Usage

```js
const opentelemetry = require('@opentelemetry/api');
const { trace } = require('@opentelemetry/api');
const { BasicTracerProvider } = require('@opentelemetry/sdk-trace-base');

// To start a trace, you first need to initialize the Tracer provider.
// NOTE: The default OpenTelemetry tracer provider does not record any tracing information.
// Registering a working tracer provider allows the API methods to record traces.
new BasicTracerProvider().register();
trace.setGlobalTracerProvider(new BasicTracerProvider());

// Important: requires a context manager and propagator to be registered manually.
// propagation.setGlobalPropagator(propagator); // replace `propagator` with your `TextMapPropagator`, for example: `W3CTraceContextPropagator` from `@openetelemetry/core`
// context.setGlobalContextManager(contextManager); // replace `contextManager` with your `ContextManager`: `AsyncLocalStorageContextManager` from `@openetelemetry/async-hooks`

// To create a span in a trace, we used the global singleton tracer to start a new span.
const span = opentelemetry.trace.getTracer('default').startSpan('foo');
const span = trace.getTracer('default').startSpan('foo');

// Set a span attribute
span.setAttribute('key', 'value');
Expand Down
47 changes: 3 additions & 44 deletions packages/opentelemetry-sdk-trace-base/src/BasicTracerProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,14 @@
* limitations under the License.
*/

import {
context,
propagation,
TextMapPropagator,
trace,
TracerProvider,
Tracer as ApiTracer,
} from '@opentelemetry/api';
import {
CompositePropagator,
W3CBaggagePropagator,
W3CTraceContextPropagator,
merge,
} from '@opentelemetry/core';
import { TracerProvider, Tracer as ApiTracer } from '@opentelemetry/api';
import { merge } from '@opentelemetry/core';
import { defaultResource, Resource } from '@opentelemetry/resources';
import { SpanProcessor } from './SpanProcessor';
import { Tracer } from './Tracer';
import { loadDefaultConfig } from './config';
import { MultiSpanProcessor } from './MultiSpanProcessor';
import { SDKRegistrationConfig, TracerConfig } from './types';
import { TracerConfig } from './types';
import { reconfigureLimits } from './utility';

export enum ForceFlushState {
Expand All @@ -43,10 +31,6 @@ export enum ForceFlushState {
'unresolved',
}

function getDefaultPropagators(): TextMapPropagator[] {
return [new W3CTraceContextPropagator(), new W3CBaggagePropagator()];
}

/**
* This class represents a basic tracer provider which platform libraries can extend
*/
Expand Down Expand Up @@ -99,31 +83,6 @@ export class BasicTracerProvider implements TracerProvider {
return this._tracers.get(key)!;
}

/**
* Register this TracerProvider for use with the OpenTelemetry API.
* Undefined values may be replaced with defaults, and
* null values will be skipped.
*
* @param config Configuration object for SDK registration
*/
register(config: SDKRegistrationConfig = {}): void {
trace.setGlobalTracerProvider(this);

if (config.contextManager) {
context.setGlobalContextManager(config.contextManager);
}

// undefined means "unset", null means don't register propagator
if (config.propagator !== null) {
propagation.setGlobalPropagator(
config.propagator ??
new CompositePropagator({
propagators: getDefaultPropagators(),
})
);
}
}

forceFlush(): Promise<void> {
const timeout = this._config.forceFlushTimeoutMillis;
const promises = this._activeSpanProcessor['_spanProcessors'].map(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,8 @@ import {
SpanContext,
TraceFlags,
ROOT_CONTEXT,
TextMapPropagator,
TextMapSetter,
Context,
TextMapGetter,
propagation,
diag,
ContextManager,
} from '@opentelemetry/api';
import { CompositePropagator } from '@opentelemetry/core';
import { TraceState } from '@opentelemetry/core';
import {
defaultResource,
Expand All @@ -49,28 +42,8 @@ import { SpanImpl } from '../../src/Span';
import { MultiSpanProcessor } from '../../src/MultiSpanProcessor';
import { Tracer } from '../../src/Tracer';

class DummyPropagator implements TextMapPropagator {
inject(context: Context, carrier: any, setter: TextMapSetter<any>): void {
throw new Error('Method not implemented.');
}
extract(context: Context, carrier: any, getter: TextMapGetter<any>): Context {
throw new Error('Method not implemented.');
}
fields(): string[] {
throw new Error('Method not implemented.');
}
}

describe('BasicTracerProvider', () => {
let setGlobalPropagatorStub: sinon.SinonSpy<[TextMapPropagator], boolean>;
let setGlobalContextManagerStub: sinon.SinonSpy<[ContextManager], boolean>;

beforeEach(() => {
// to avoid actually registering the TraceProvider and leaking env to other tests
sinon.stub(trace, 'setGlobalTracerProvider');
setGlobalPropagatorStub = sinon.spy(propagation, 'setGlobalPropagator');
setGlobalContextManagerStub = sinon.spy(context, 'setGlobalContextManager');

context.disable();
});

Expand Down Expand Up @@ -312,65 +285,6 @@ describe('BasicTracerProvider', () => {
});
});

describe('.register()', () => {
describe('propagator', () => {
it('should be set to a given value if it it provided', () => {
const provider = new BasicTracerProvider();
provider.register({
propagator: new DummyPropagator(),
});

sinon.assert.calledOnceWithExactly(
setGlobalPropagatorStub,
sinon.match.instanceOf(DummyPropagator)
);
});

it('should use w3c trace context and baggage propagators by default', () => {
const provider = new BasicTracerProvider();
provider.register();

sinon.assert.calledOnceWithExactly(
setGlobalPropagatorStub,
sinon.match.instanceOf(CompositePropagator)
);
assert.deepStrictEqual(setGlobalPropagatorStub.args[0][0].fields(), [
'traceparent',
'tracestate',
'baggage',
]);
});
});
describe('contextManager', () => {
it('should not be set if not provided', () => {
const provider = new BasicTracerProvider();
provider.register();

sinon.assert.notCalled(setGlobalContextManagerStub);
});

it('should be set if provided', () => {
const provider = new BasicTracerProvider();
const mockContextManager: ContextManager = {
active: sinon.stub(),
bind: sinon.stub(),
disable: sinon.stub(),
enable: sinon.stub(),
with: sinon.stub(),
};

provider.register({
contextManager: mockContextManager,
});

sinon.assert.calledOnceWithExactly(
setGlobalContextManagerStub,
mockContextManager
);
});
});
});

describe('.startSpan()', () => {
it('should start a span with name only', () => {
const tracer = new BasicTracerProvider().getTracer('default');
Expand Down
Loading

0 comments on commit 544c409

Please sign in to comment.