Simplify SDK registration (#837)

This commit is contained in:
Daniel Dyla 2020-03-10 08:39:05 -04:00 committed by GitHub
parent cd59fcc2a4
commit 5883e4e178
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 261 additions and 9 deletions

View File

@ -18,6 +18,7 @@ export * from './common/Logger';
export * from './common/Time'; export * from './common/Time';
export * from './context/propagation/getter'; export * from './context/propagation/getter';
export * from './context/propagation/HttpTextFormat'; export * from './context/propagation/HttpTextFormat';
export * from './context/propagation/NoopHttpTextFormat';
export * from './context/propagation/setter'; export * from './context/propagation/setter';
export * from './correlation_context/CorrelationContext'; export * from './correlation_context/CorrelationContext';
export * from './correlation_context/EntryValue'; export * from './correlation_context/EntryValue';

View File

@ -43,6 +43,7 @@
"devDependencies": { "devDependencies": {
"@types/mocha": "^5.2.5", "@types/mocha": "^5.2.5",
"@types/node": "^12.6.8", "@types/node": "^12.6.8",
"@opentelemetry/scope-base": "^0.4.0",
"@types/semver": "^6.0.1", "@types/semver": "^6.0.1",
"@types/shimmer": "^1.0.1", "@types/shimmer": "^1.0.1",
"codecov": "^3.6.1", "codecov": "^3.6.1",

View File

@ -14,12 +14,20 @@
* limitations under the License. * limitations under the License.
*/ */
import { BasicTracerProvider } from '@opentelemetry/tracing'; import { AsyncHooksScopeManager } from '@opentelemetry/scope-async-hooks';
import {
BasicTracerProvider,
SDKRegistrationConfig,
} from '@opentelemetry/tracing';
import { DEFAULT_INSTRUMENTATION_PLUGINS, NodeTracerConfig } from './config'; import { DEFAULT_INSTRUMENTATION_PLUGINS, NodeTracerConfig } from './config';
import { PluginLoader } from './instrumentation/PluginLoader'; import { PluginLoader } from './instrumentation/PluginLoader';
/** /**
* This class represents a node tracer with `async_hooks` module. * 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
*/ */
export class NodeTracerProvider extends BasicTracerProvider { export class NodeTracerProvider extends BasicTracerProvider {
private readonly _pluginLoader: PluginLoader; private readonly _pluginLoader: PluginLoader;
@ -37,4 +45,13 @@ export class NodeTracerProvider extends BasicTracerProvider {
stop() { stop() {
this._pluginLoader.unload(); this._pluginLoader.unload();
} }
register(config: SDKRegistrationConfig = {}) {
if (config.contextManager === undefined) {
config.contextManager = new AsyncHooksScopeManager();
config.contextManager.enable();
}
super.register(config);
}
} }

View File

@ -0,0 +1,86 @@
/*!
* Copyright 2020, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
context,
NoopHttpTextFormat,
NoopTracerProvider,
propagation,
trace,
} from '@opentelemetry/api';
import { HttpTraceContext } from '@opentelemetry/core';
import { AsyncHooksScopeManager } from '@opentelemetry/scope-async-hooks';
import { NoopScopeManager } from '@opentelemetry/scope-base';
import * as assert from 'assert';
import { NodeTracerProvider } from '../src';
describe('API registration', () => {
beforeEach(() => {
context.initGlobalContextManager(new NoopScopeManager());
propagation.initGlobalPropagator(new NoopHttpTextFormat());
trace.initGlobalTracerProvider(new NoopTracerProvider());
});
it('should register default implementations', () => {
const tracerProvider = new NodeTracerProvider();
tracerProvider.register();
assert.ok(context['_scopeManager'] instanceof AsyncHooksScopeManager);
assert.ok(propagation['_propagator'] instanceof HttpTraceContext);
assert.ok(trace['_tracerProvider'] === tracerProvider);
});
it('should register configured implementations', () => {
const tracerProvider = new NodeTracerProvider();
const contextManager = new NoopScopeManager();
const propagator = new NoopHttpTextFormat();
tracerProvider.register({
contextManager,
propagator,
});
assert.ok(context['_scopeManager'] === contextManager);
assert.ok(propagation['_propagator'] === propagator);
assert.ok(trace['_tracerProvider'] === tracerProvider);
});
it('should skip null context manager', () => {
const tracerProvider = new NodeTracerProvider();
tracerProvider.register({
contextManager: null,
});
assert.ok(context['_scopeManager'] instanceof NoopScopeManager);
assert.ok(propagation['_propagator'] instanceof HttpTraceContext);
assert.ok(trace['_tracerProvider'] === tracerProvider);
});
it('should skip null propagator', () => {
const tracerProvider = new NodeTracerProvider();
tracerProvider.register({
propagator: null,
});
assert.ok(propagation['_propagator'] instanceof NoopHttpTextFormat);
assert.ok(context['_scopeManager'] instanceof AsyncHooksScopeManager);
assert.ok(trace['_tracerProvider'] === tracerProvider);
});
});

View File

@ -14,23 +14,23 @@
* limitations under the License. * limitations under the License.
*/ */
import { ConsoleLogger } from '@opentelemetry/core'; import * as api from '@opentelemetry/api';
import * as types from '@opentelemetry/api'; import { ConsoleLogger, HttpTraceContext } from '@opentelemetry/core';
import { SpanProcessor, Tracer } from '.'; import { SpanProcessor, Tracer } from '.';
import { DEFAULT_CONFIG } from './config'; import { DEFAULT_CONFIG } from './config';
import { MultiSpanProcessor } from './MultiSpanProcessor'; import { MultiSpanProcessor } from './MultiSpanProcessor';
import { NoopSpanProcessor } from './NoopSpanProcessor'; import { NoopSpanProcessor } from './NoopSpanProcessor';
import { TracerConfig } from './types'; import { SDKRegistrationConfig, TracerConfig } from './types';
/** /**
* This class represents a basic tracer provider which platform libraries can extend * This class represents a basic tracer provider which platform libraries can extend
*/ */
export class BasicTracerProvider implements types.TracerProvider { export class BasicTracerProvider implements api.TracerProvider {
private readonly _registeredSpanProcessors: SpanProcessor[] = []; private readonly _registeredSpanProcessors: SpanProcessor[] = [];
private readonly _tracers: Map<string, Tracer> = new Map(); private readonly _tracers: Map<string, Tracer> = new Map();
activeSpanProcessor = new NoopSpanProcessor(); activeSpanProcessor = new NoopSpanProcessor();
readonly logger: types.Logger; readonly logger: api.Logger;
constructor(private _config: TracerConfig = DEFAULT_CONFIG) { constructor(private _config: TracerConfig = DEFAULT_CONFIG) {
this.logger = _config.logger || new ConsoleLogger(_config.logLevel); this.logger = _config.logger || new ConsoleLogger(_config.logLevel);
@ -59,4 +59,26 @@ export class BasicTracerProvider implements types.TracerProvider {
getActiveSpanProcessor(): SpanProcessor { getActiveSpanProcessor(): SpanProcessor {
return this.activeSpanProcessor; return this.activeSpanProcessor;
} }
/**
* 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 = {}) {
api.trace.initGlobalTracerProvider(this);
if (config.propagator === undefined) {
config.propagator = new HttpTraceContext();
}
if (config.contextManager) {
api.context.initGlobalContextManager(config.contextManager);
}
if (config.propagator) {
api.propagation.initGlobalPropagator(config.propagator);
}
}
} }

View File

@ -14,8 +14,14 @@
* limitations under the License. * limitations under the License.
*/ */
import { Attributes, Logger, Sampler } from '@opentelemetry/api'; import {
Attributes,
HttpTextFormat,
Logger,
Sampler,
} from '@opentelemetry/api';
import { LogLevel } from '@opentelemetry/core'; import { LogLevel } from '@opentelemetry/core';
import { ScopeManager } from '@opentelemetry/scope-base';
/** /**
* TracerConfig provides an interface for configuring a Basic Tracer. * TracerConfig provides an interface for configuring a Basic Tracer.
@ -44,6 +50,19 @@ export interface TracerConfig {
traceParams?: TraceParams; traceParams?: TraceParams;
} }
/**
* Configuration options for registering the API with the SDK.
* Undefined values may be substituted for defaults, and null
* values will not be registered.
*/
export interface SDKRegistrationConfig {
/** Propagator to register as the global propagator */
propagator?: HttpTextFormat | null;
/** Context manager to register as the global context manager */
contextManager?: ScopeManager | null;
}
/** Global configuration of trace service */ /** Global configuration of trace service */
export interface TraceParams { export interface TraceParams {
/** numberOfAttributesPerSpan is number of attributes per span */ /** numberOfAttributesPerSpan is number of attributes per span */

View File

@ -15,7 +15,12 @@
*/ */
import { BasePlugin } from '@opentelemetry/core'; import { BasePlugin } from '@opentelemetry/core';
import { BasicTracerProvider, TracerConfig } from '@opentelemetry/tracing'; import {
BasicTracerProvider,
SDKRegistrationConfig,
TracerConfig,
} from '@opentelemetry/tracing';
import { StackScopeManager } from './StackScopeManager';
/** /**
* WebTracerConfig provides an interface for configuring a Web Tracer. * WebTracerConfig provides an interface for configuring a Web Tracer.
@ -45,4 +50,20 @@ export class WebTracerProvider extends BasicTracerProvider {
plugin.enable([], this, this.logger); plugin.enable([], this, this.logger);
} }
} }
/**
* 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 = {}) {
if (config.contextManager === undefined) {
config.contextManager = new StackScopeManager();
config.contextManager.enable();
}
super.register(config);
}
} }

View File

@ -0,0 +1,85 @@
/*!
* Copyright 2020, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
context,
NoopHttpTextFormat,
NoopTracerProvider,
propagation,
trace,
} from '@opentelemetry/api';
import { HttpTraceContext } from '@opentelemetry/core';
import { NoopScopeManager } from '@opentelemetry/scope-base';
import * as assert from 'assert';
import { WebTracerProvider, StackScopeManager } from '../src';
describe('API registration', () => {
beforeEach(() => {
context.initGlobalContextManager(new NoopScopeManager());
propagation.initGlobalPropagator(new NoopHttpTextFormat());
trace.initGlobalTracerProvider(new NoopTracerProvider());
});
it('should register default implementations', () => {
const tracerProvider = new WebTracerProvider();
tracerProvider.register();
assert.ok(context['_scopeManager'] instanceof StackScopeManager);
assert.ok(propagation['_propagator'] instanceof HttpTraceContext);
assert.ok(trace['_tracerProvider'] === tracerProvider);
});
it('should register configured implementations', () => {
const tracerProvider = new WebTracerProvider();
const contextManager = new NoopScopeManager();
const propagator = new NoopHttpTextFormat();
tracerProvider.register({
contextManager,
propagator,
});
assert.ok(context['_scopeManager'] === contextManager);
assert.ok(propagation['_propagator'] === propagator);
assert.ok(trace['_tracerProvider'] === tracerProvider);
});
it('should skip null context manager', () => {
const tracerProvider = new WebTracerProvider();
tracerProvider.register({
contextManager: null,
});
assert.ok(context['_scopeManager'] instanceof NoopScopeManager);
assert.ok(propagation['_propagator'] instanceof HttpTraceContext);
assert.ok(trace['_tracerProvider'] === tracerProvider);
});
it('should skip null propagator', () => {
const tracerProvider = new WebTracerProvider();
tracerProvider.register({
propagator: null,
});
assert.ok(propagation['_propagator'] instanceof NoopHttpTextFormat);
assert.ok(context['_scopeManager'] instanceof StackScopeManager);
assert.ok(trace['_tracerProvider'] === tracerProvider);
});
});