Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(node-tracer): use AsyncLocalStorageContextManager by default starting Node 14.8 #1511 #1525

Merged
merged 4 commits into from Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 9 additions & 2 deletions packages/opentelemetry-node/src/NodeTracerProvider.ts
Expand Up @@ -14,13 +14,17 @@
* limitations under the License.
*/

import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks';
import {
AsyncHooksContextManager,
AsyncLocalStorageContextManager,
} from '@opentelemetry/context-async-hooks';
import {
BasicTracerProvider,
SDKRegistrationConfig,
} from '@opentelemetry/tracing';
import { DEFAULT_INSTRUMENTATION_PLUGINS, NodeTracerConfig } from './config';
import { PluginLoader, Plugins } from './instrumentation/PluginLoader';
import * as semver from 'semver';

/**
* Register this TracerProvider for use with the OpenTelemetry API.
Expand Down Expand Up @@ -53,7 +57,10 @@ export class NodeTracerProvider extends BasicTracerProvider {

register(config: SDKRegistrationConfig = {}) {
if (config.contextManager === undefined) {
config.contextManager = new AsyncHooksContextManager();
const ContextManager = semver.gte(process.version, '14.8.0')
? AsyncLocalStorageContextManager
: AsyncHooksContextManager;
config.contextManager = new ContextManager();
config.contextManager.enable();
}

Expand Down
18 changes: 11 additions & 7 deletions packages/opentelemetry-node/test/registration.test.ts
Expand Up @@ -21,11 +21,19 @@ import {
trace,
ProxyTracerProvider,
} from '@opentelemetry/api';
import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks';
import {
AsyncHooksContextManager,
AsyncLocalStorageContextManager,
} from '@opentelemetry/context-async-hooks';
import { NoopContextManager } from '@opentelemetry/context-base';
import { CompositePropagator } from '@opentelemetry/core';
import * as assert from 'assert';
import { NodeTracerProvider } from '../src';
import * as semver from 'semver';

const DefaultContextManager = semver.gte(process.version, '14.8.0')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we rather check if AsyncLocalStorageContextManager is available (feature detection) instead of checking the version using semver. If you already require that it means it will be undefined for lower versions

const DefaultContextManager = AsyncLocalStorageContextManager || AsyncHooksContextManager

should be enough ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the description he mentioned that there is a bug in versions before 14.8. Feature detection would still detect that local storage is available, but he suggests we would want to use the async hooks version anyways.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sry haven't spotted that

? AsyncLocalStorageContextManager
: AsyncHooksContextManager;

describe('API registration', () => {
beforeEach(() => {
Expand All @@ -38,9 +46,7 @@ describe('API registration', () => {
const tracerProvider = new NodeTracerProvider();
tracerProvider.register();

assert.ok(
context['_getContextManager']() instanceof AsyncHooksContextManager
);
assert.ok(context['_getContextManager']() instanceof DefaultContextManager);
assert.ok(
propagation['_getGlobalPropagator']() instanceof CompositePropagator
);
Expand Down Expand Up @@ -96,9 +102,7 @@ describe('API registration', () => {
propagation['_getGlobalPropagator']() instanceof NoopTextMapPropagator
);

assert.ok(
context['_getContextManager']() instanceof AsyncHooksContextManager
);
assert.ok(context['_getContextManager']() instanceof DefaultContextManager);

const apiTracerProvider = trace.getTracerProvider();
assert.ok(apiTracerProvider instanceof ProxyTracerProvider);
Expand Down
13 changes: 10 additions & 3 deletions packages/opentelemetry-sdk-node/test/sdk.test.ts
Expand Up @@ -26,7 +26,10 @@ import {
trace,
ProxyTracerProvider,
} from '@opentelemetry/api';
import { AsyncHooksContextManager } from '@opentelemetry/context-async-hooks';
import {
AsyncHooksContextManager,
AsyncLocalStorageContextManager,
} from '@opentelemetry/context-async-hooks';
import { NoopContextManager } from '@opentelemetry/context-base';
import { CompositePropagator } from '@opentelemetry/core';
import { ConsoleMetricExporter, MeterProvider } from '@opentelemetry/metrics';
Expand Down Expand Up @@ -81,6 +84,10 @@ const mockedIdentityResponse = {
};
const mockedHostResponse = 'my-hostname';

const DefaultContextManager = semver.gte(process.version, '14.8.0')
? AsyncLocalStorageContextManager
: AsyncHooksContextManager;

describe('Node SDK', () => {
before(() => {
// Disable attempted load of default plugins
Expand Down Expand Up @@ -127,7 +134,7 @@ describe('Node SDK', () => {
assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider);

assert.ok(
context['_getContextManager']() instanceof AsyncHooksContextManager
context['_getContextManager']() instanceof DefaultContextManager
);
assert.ok(
propagation['_getGlobalPropagator']() instanceof CompositePropagator
Expand All @@ -151,7 +158,7 @@ describe('Node SDK', () => {
assert.ok(metrics.getMeterProvider() instanceof NoopMeterProvider);

assert.ok(
context['_getContextManager']() instanceof AsyncHooksContextManager
context['_getContextManager']() instanceof DefaultContextManager
);
assert.ok(
propagation['_getGlobalPropagator']() instanceof CompositePropagator
Expand Down