Skip to content

Commit

Permalink
improv(tracing): allow to load exporter from environment #1676
Browse files Browse the repository at this point in the history
  • Loading branch information
vmarchaud committed May 2, 2021
1 parent e1e79ef commit 75e963b
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 11 deletions.
2 changes: 2 additions & 0 deletions packages/opentelemetry-core/src/utils/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export type ENVIRONMENT = {
OTEL_EXPORTER_ZIPKIN_ENDPOINT?: string;
OTEL_LOG_LEVEL?: DiagLogLevel;
OTEL_RESOURCE_ATTRIBUTES?: string;
OTEL_TRACES_EXPORTER?: string;
OTEL_TRACES_SAMPLER_ARG?: string;
OTEL_TRACES_SAMPLER?: string;
} & ENVIRONMENT_NUMBERS &
Expand Down Expand Up @@ -105,6 +106,7 @@ export const DEFAULT_ENVIRONMENT: Required<ENVIRONMENT> = {
OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT: 128,
OTEL_SPAN_EVENT_COUNT_LIMIT: 128,
OTEL_SPAN_LINK_COUNT_LIMIT: 128,
OTEL_TRACES_EXPORTER: 'none',
OTEL_TRACES_SAMPLER: TracesSamplerValues.ParentBasedAlwaysOn,
OTEL_TRACES_SAMPLER_ARG: '',
};
Expand Down
50 changes: 47 additions & 3 deletions packages/opentelemetry-tracing/src/BasicTracerProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@ import { Resource } from '@opentelemetry/resources';
import { SpanProcessor, Tracer } from '.';
import { DEFAULT_CONFIG } from './config';
import { MultiSpanProcessor } from './MultiSpanProcessor';
import { NoopSpanProcessor } from './NoopSpanProcessor';
import { NoopSpanProcessor } from './export/NoopSpanProcessor';
import { SDKRegistrationConfig, TracerConfig } from './types';
const merge = require('lodash.merge');
import merge = require('lodash.merge');
import { SpanExporter } from './export/SpanExporter';
import { BatchSpanProcessor } from './export/BatchSpanProcessor';

export type PROPAGATOR_FACTORY = () => TextMapPropagator;
export type EXPORTER_FACTORY = () => SpanExporter;

/**
* This class represents a basic tracer provider which platform libraries can extend
Expand All @@ -50,11 +53,16 @@ export class BasicTracerProvider implements TracerProvider {
['baggage', () => new HttpBaggagePropagator()],
]);

protected static readonly _registeredExporters = new Map<
string,
EXPORTER_FACTORY
>();

private readonly _config: TracerConfig;
private readonly _registeredSpanProcessors: SpanProcessor[] = [];
private readonly _tracers: Map<string, Tracer> = new Map();

activeSpanProcessor: SpanProcessor = new NoopSpanProcessor();
activeSpanProcessor: SpanProcessor;
readonly resource: Resource;

constructor(config: TracerConfig = {}) {
Expand All @@ -64,6 +72,14 @@ export class BasicTracerProvider implements TracerProvider {
this._config = Object.assign({}, mergedConfig, {
resource: this.resource,
});

const defaultExporter = this._buildExporterFromEnv();
if (defaultExporter !== undefined) {
const batchProcessor = new BatchSpanProcessor(defaultExporter);
this.activeSpanProcessor = batchProcessor;
} else {
this.activeSpanProcessor = new NoopSpanProcessor();
}
}

getTracer(name: string, version?: string): Tracer {
Expand All @@ -80,6 +96,18 @@ export class BasicTracerProvider implements TracerProvider {
* @param spanProcessor the new SpanProcessor to be added.
*/
addSpanProcessor(spanProcessor: SpanProcessor): void {
if (this._registeredSpanProcessors.length === 0) {
// since we might have enabled by default a batchProcessor, we disable it
// before adding the new one
this.activeSpanProcessor
.shutdown()
.catch(err =>
diag.error(
'Error while trying to shutdown current span processor',
err
)
);
}
this._registeredSpanProcessors.push(spanProcessor);
this.activeSpanProcessor = new MultiSpanProcessor(
this._registeredSpanProcessors
Expand Down Expand Up @@ -120,6 +148,10 @@ export class BasicTracerProvider implements TracerProvider {
return BasicTracerProvider._registeredPropagators.get(name)?.();
}

protected _getSpanExporter(name: string): SpanExporter | undefined {
return BasicTracerProvider._registeredExporters.get(name)?.();
}

protected _buildPropagatorFromEnv(): TextMapPropagator | undefined {
// per spec, propagators from env must be deduplicated
const uniquePropagatorNames = Array.from(
Expand Down Expand Up @@ -156,4 +188,16 @@ export class BasicTracerProvider implements TracerProvider {
});
}
}

protected _buildExporterFromEnv(): SpanExporter | undefined {
const exporterName = getEnv().OTEL_TRACES_EXPORTER;
if (exporterName === 'none') return;
const exporter = this._getSpanExporter(exporterName);
if (!exporter) {
diag.warn(
`Exporter "${exporterName}" requested through environment variable is unavailable.`
);
}
return exporter;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
*/

import { Context } from '@opentelemetry/api';
import { ReadableSpan } from './export/ReadableSpan';
import { Span } from './Span';
import { SpanProcessor } from './SpanProcessor';
import { ReadableSpan } from './ReadableSpan';
import { Span } from '../Span';
import { SpanProcessor } from '../SpanProcessor';

/** No-op implementation of SpanProcessor */
export class NoopSpanProcessor implements SpanProcessor {
Expand Down
1 change: 1 addition & 0 deletions packages/opentelemetry-tracing/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ export * from './export/InMemorySpanExporter';
export * from './export/ReadableSpan';
export * from './export/SimpleSpanProcessor';
export * from './export/SpanExporter';
export * from './export/NoopSpanProcessor';
export * from './Span';
export * from './SpanProcessor';
export * from './types';
30 changes: 25 additions & 5 deletions packages/opentelemetry-tracing/test/BasicTracerProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ import {
import { Resource } from '@opentelemetry/resources';
import * as assert from 'assert';
import * as sinon from 'sinon';
import { BasicTracerProvider, Span } from '../src';
import { BasicTracerProvider, NoopSpanProcessor, Span } from '../src';

describe('BasicTracerProvider', () => {
let removeEvent: Function | undefined;
const envSource = (typeof window !== 'undefined'
? window
: process.env) as any;

beforeEach(() => {
context.disable();
Expand Down Expand Up @@ -120,13 +123,30 @@ describe('BasicTracerProvider', () => {
const tracer = new BasicTracerProvider();
assert.ok(tracer instanceof BasicTracerProvider);
});

it('should use noop span processor by default', () => {
const tracer = new BasicTracerProvider();
assert.ok(tracer.activeSpanProcessor instanceof NoopSpanProcessor);
});

it('warns if there is no exporter registered with a given name', () => {
const warnStub = sinon.spy(diag, 'warn');

envSource.OTEL_TRACES_EXPORTER = 'missing-exporter';
const provider = new BasicTracerProvider({});
provider.register();

assert.ok(
warnStub.calledOnceWithExactly(
'Exporter "missing-exporter" requested through environment variable is unavailable.'
)
);
warnStub.restore();
envSource.OTEL_TRACES_EXPORTER = 'none';
});
});

describe('.register()', () => {
const envSource = (typeof window !== 'undefined'
? window
: process.env) as any;

describe('propagator', () => {
class DummyPropagator implements TextMapPropagator {
inject(
Expand Down

0 comments on commit 75e963b

Please sign in to comment.