diff --git a/metapackages/auto-instrumentations-node/package.json b/metapackages/auto-instrumentations-node/package.json index 53028866b8..e1f6b379f9 100644 --- a/metapackages/auto-instrumentations-node/package.json +++ b/metapackages/auto-instrumentations-node/package.json @@ -94,7 +94,12 @@ "@opentelemetry/resource-detector-container": "^0.3.11", "@opentelemetry/resource-detector-gcp": "^0.29.10", "@opentelemetry/resources": "^1.24.0", - "@opentelemetry/sdk-node": "^0.52.0" + "@opentelemetry/sdk-node": "^0.52.0", + "@opentelemetry/core": "^1.25.0", + "@opentelemetry/propagator-b3": "^1.25.0", + "@opentelemetry/propagator-jaeger": "^1.25.0", + "@opentelemetry/propagator-aws-xray": "^1.25.0", + "@opentelemetry/propagator-ot-trace": "^0.27.2" }, "files": [ "build/src/**/*.js", diff --git a/metapackages/auto-instrumentations-node/src/index.ts b/metapackages/auto-instrumentations-node/src/index.ts index 669066d0a9..5daf061b84 100644 --- a/metapackages/auto-instrumentations-node/src/index.ts +++ b/metapackages/auto-instrumentations-node/src/index.ts @@ -17,5 +17,6 @@ export { getNodeAutoInstrumentations, getResourceDetectorsFromEnv as getResourceDetectors, + getPropagator, InstrumentationConfigMap, } from './utils'; diff --git a/metapackages/auto-instrumentations-node/src/register.ts b/metapackages/auto-instrumentations-node/src/register.ts index a14538da66..f32d769382 100644 --- a/metapackages/auto-instrumentations-node/src/register.ts +++ b/metapackages/auto-instrumentations-node/src/register.ts @@ -17,6 +17,7 @@ import * as opentelemetry from '@opentelemetry/sdk-node'; import { diag, DiagConsoleLogger } from '@opentelemetry/api'; import { getNodeAutoInstrumentations, + getPropagator, getResourceDetectorsFromEnv, } from './utils'; @@ -28,6 +29,7 @@ diag.setLogger( const sdk = new opentelemetry.NodeSDK({ instrumentations: getNodeAutoInstrumentations(), resourceDetectors: getResourceDetectorsFromEnv(), + textMapPropagator: getPropagator(), }); try { diff --git a/metapackages/auto-instrumentations-node/src/utils.ts b/metapackages/auto-instrumentations-node/src/utils.ts index 04f4c1ed50..0766972170 100644 --- a/metapackages/auto-instrumentations-node/src/utils.ts +++ b/metapackages/auto-instrumentations-node/src/utils.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { diag } from '@opentelemetry/api'; +import { diag, TextMapPropagator } from '@opentelemetry/api'; import { Instrumentation } from '@opentelemetry/instrumentation'; import { AmqplibInstrumentation } from '@opentelemetry/instrumentation-amqplib'; @@ -80,6 +80,15 @@ import { azureFunctionsDetector, azureVmDetector, } from '@opentelemetry/resource-detector-azure'; +import { + CompositePropagator, + W3CBaggagePropagator, + W3CTraceContextPropagator, +} from '@opentelemetry/core'; +import { B3InjectEncoding, B3Propagator } from '@opentelemetry/propagator-b3'; +import { JaegerPropagator } from '@opentelemetry/propagator-jaeger'; +import { OTTracePropagator } from '@opentelemetry/propagator-ot-trace'; +import { AWSXRayPropagator } from '@opentelemetry/propagator-aws-xray'; const RESOURCE_DETECTOR_CONTAINER = 'container'; const RESOURCE_DETECTOR_ENVIRONMENT = 'env'; @@ -253,3 +262,63 @@ export function getResourceDetectorsFromEnv(): Array { return resourceDetector || []; }); } + +type PropagatorFactoryFunction = () => TextMapPropagator; + +const propagatorMap = new Map([ + ['tracecontext', () => new W3CTraceContextPropagator()], + ['baggage', () => new W3CTraceContextPropagator()], + [ + 'b3', + () => new B3Propagator({ injectEncoding: B3InjectEncoding.SINGLE_HEADER }), + ], + [ + 'b3multi', + () => new B3Propagator({ injectEncoding: B3InjectEncoding.MULTI_HEADER }), + ], + ['jaeger', () => new JaegerPropagator()], + ['xray', () => new AWSXRayPropagator()], + ['ottrace', () => new OTTracePropagator()], +]); + +/** + * Get a propagator based on the OTEL_PROPAGATORS env var. + */ +export function getPropagator(): TextMapPropagator { + if (process.env.OTEL_PROPAGATORS == null || process.env.OTEL_PROPAGATORS.trim() === '') { + return new CompositePropagator({ + propagators: [ + new W3CTraceContextPropagator(), + new W3CBaggagePropagator(), + ], + }); + } + + const propagatorsFromEnv = Array.from( + new Set( + process.env.OTEL_PROPAGATORS?.split(',').map(value => + value.toLowerCase().trim() + ) + ) + ); + + const propagators = propagatorsFromEnv.flatMap(propagatorName => { + if (propagatorName === 'none'){ + diag.info( + `Not selecting any propagator for value "none" specified in the environment variable OTEL_PROPAGATORS` + ); + return []; + } + + const propagatorFactoryFunction = propagatorMap.get(propagatorName); + if (propagatorFactoryFunction == null) { + diag.error( + `Invalid propagator "${propagatorName}" specified in the environment variable OTEL_PROPAGATORS` + ); + return []; + } + return propagatorFactoryFunction(); + }); + + return new CompositePropagator({ propagators }); +} diff --git a/metapackages/auto-instrumentations-node/test/utils.test.ts b/metapackages/auto-instrumentations-node/test/utils.test.ts index 0622022f36..82b67017c8 100644 --- a/metapackages/auto-instrumentations-node/test/utils.test.ts +++ b/metapackages/auto-instrumentations-node/test/utils.test.ts @@ -19,7 +19,7 @@ import { HttpInstrumentationConfig } from '@opentelemetry/instrumentation-http'; import * as assert from 'assert'; import * as sinon from 'sinon'; import { getNodeAutoInstrumentations } from '../src'; -import { getResourceDetectorsFromEnv } from '../src/utils'; +import { getPropagator, getResourceDetectorsFromEnv } from '../src/utils'; describe('utils', () => { describe('getNodeAutoInstrumentations', () => { @@ -161,4 +161,59 @@ describe('utils', () => { delete process.env.OTEL_NODE_RESOURCE_DETECTORS; }); }); + + describe('getPropagator', () => { + afterEach(() => { + delete process.env.OTEL_PROPAGATORS; + }); + + it('should return default when env var is unset', () => { + assert.deepStrictEqual(getPropagator().fields(), [ + 'traceparent', + 'tracestate', + 'baggage', + ]); + }); + + it('should return default when env var is empty', () => { + process.env.OTEL_PROPAGATORS = ''; + assert.deepStrictEqual(getPropagator().fields(), [ + 'traceparent', + 'tracestate', + 'baggage', + ]); + }); + + it('should return default when env var is all spaces', () => { + process.env.OTEL_PROPAGATORS = ' '; + assert.deepStrictEqual(getPropagator().fields(), [ + 'traceparent', + 'tracestate', + 'baggage', + ]); + }); + + it('should return the selected propagator when one is in the list', () => { + process.env.OTEL_PROPAGATORS = 'tracecontext'; + assert.deepStrictEqual(getPropagator().fields(), [ + 'traceparent', + 'tracestate', + ]); + }); + + it('should return the selected propagators when multiple are in the list', () => { + process.env.OTEL_PROPAGATORS = 'b3,jaeger'; + assert.deepStrictEqual(getPropagator().fields(), ['b3', 'uber-trace-id']); + }); + + it('should return no-op propagator if all propagators are unknown', () => { + process.env.OTEL_PROPAGATORS = 'my, unknown, propagators'; + assert.deepStrictEqual(getPropagator().fields(), []); + }); + + it('should return no-op propagator if "none" is selected', () => { + process.env.OTEL_PROPAGATORS = 'none'; + assert.deepStrictEqual(getPropagator().fields(), []); + }); + }); }); diff --git a/package-lock.json b/package-lock.json index bc853e7751..dc539e0ea1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -286,6 +286,7 @@ "version": "0.47.1", "license": "Apache-2.0", "dependencies": { + "@opentelemetry/core": "^1.25.0", "@opentelemetry/instrumentation": "^0.52.0", "@opentelemetry/instrumentation-amqplib": "^0.38.0", "@opentelemetry/instrumentation-aws-lambda": "^0.42.0", @@ -325,6 +326,10 @@ "@opentelemetry/instrumentation-tedious": "^0.11.0", "@opentelemetry/instrumentation-undici": "^0.3.0", "@opentelemetry/instrumentation-winston": "^0.38.0", + "@opentelemetry/propagator-aws-xray": "^1.25.0", + "@opentelemetry/propagator-b3": "^1.25.0", + "@opentelemetry/propagator-jaeger": "^1.25.0", + "@opentelemetry/propagator-ot-trace": "^0.27.2", "@opentelemetry/resource-detector-alibaba-cloud": "^0.28.10", "@opentelemetry/resource-detector-aws": "^1.5.1", "@opentelemetry/resource-detector-azure": "^0.2.9", @@ -50359,6 +50364,7 @@ "version": "file:metapackages/auto-instrumentations-node", "requires": { "@opentelemetry/api": "^1.4.1", + "@opentelemetry/core": "^1.25.0", "@opentelemetry/instrumentation": "^0.52.0", "@opentelemetry/instrumentation-amqplib": "^0.38.0", "@opentelemetry/instrumentation-aws-lambda": "^0.42.0", @@ -50398,6 +50404,10 @@ "@opentelemetry/instrumentation-tedious": "^0.11.0", "@opentelemetry/instrumentation-undici": "^0.3.0", "@opentelemetry/instrumentation-winston": "^0.38.0", + "@opentelemetry/propagator-aws-xray": "^1.25.0", + "@opentelemetry/propagator-b3": "^1.25.0", + "@opentelemetry/propagator-jaeger": "^1.25.0", + "@opentelemetry/propagator-ot-trace": "^0.27.2", "@opentelemetry/resource-detector-alibaba-cloud": "^0.28.10", "@opentelemetry/resource-detector-aws": "^1.5.1", "@opentelemetry/resource-detector-azure": "^0.2.9",