Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export class AwsOpentelemetryConfigurator {
* @constructor
* @param {Instrumentation[]} instrumentations - Auto-Instrumentations to be added to the ADOT Config
*/
public constructor(instrumentations: Instrumentation[]) {
public constructor(instrumentations: Instrumentation[], useXraySampler: boolean = false) {
/*
* Set and Detect Resources via Resource Detectors
*
Expand Down Expand Up @@ -167,7 +167,9 @@ export class AwsOpentelemetryConfigurator {
// https://github.com/aws-observability/aws-otel-java-instrumentation/blob/a011b8cc29ee32b7f668c04ccfdf64cd30de467c/awsagentprovider/src/main/java/software/amazon/opentelemetry/javaagent/providers/AwsTracerCustomizerProvider.java#L36
this.idGenerator = new AWSXRayIdGenerator();

this.sampler = AwsOpentelemetryConfigurator.customizeSampler(customBuildSamplerFromEnv(this.resource));
this.sampler = AwsOpentelemetryConfigurator.customizeSampler(
customBuildSamplerFromEnv(this.resource, useXraySampler)
);

// default SpanProcessors with Span Exporters wrapped inside AwsMetricAttributesSpanExporter
const awsSpanProcessorProvider: AwsSpanProcessorProvider = new AwsSpanProcessorProvider(this.resource);
Expand Down Expand Up @@ -291,37 +293,36 @@ export class AwsOpentelemetryConfigurator {
}
}

export function customBuildSamplerFromEnv(resource: Resource): Sampler {
switch (process.env.OTEL_TRACES_SAMPLER) {
case 'xray': {
const samplerArgumentEnv: string | undefined = process.env.OTEL_TRACES_SAMPLER_ARG;
let endpoint: string | undefined = undefined;
let pollingInterval: number | undefined = undefined;

if (samplerArgumentEnv !== undefined) {
const args: string[] = samplerArgumentEnv.split(',');
for (const arg of args) {
const equalIndex: number = arg.indexOf('=');
if (equalIndex === -1) {
continue;
}
const keyValue: string[] = [arg.substring(0, equalIndex), arg.substring(equalIndex + 1)];
if (keyValue[0] === 'endpoint') {
endpoint = keyValue[1];
} else if (keyValue[0] === 'polling_interval') {
pollingInterval = Number(keyValue[1]);
if (isNaN(pollingInterval)) {
pollingInterval = undefined;
diag.error('polling_interval in OTEL_TRACES_SAMPLER_ARG must be a valid number');
}
export function customBuildSamplerFromEnv(resource: Resource, useXraySampler: boolean = false): Sampler {
if (useXraySampler || process.env.OTEL_TRACES_SAMPLER === 'xray') {
const samplerArgumentEnv: string | undefined = process.env.OTEL_TRACES_SAMPLER_ARG;
let endpoint: string | undefined = undefined;
let pollingInterval: number | undefined = undefined;

if (samplerArgumentEnv !== undefined) {
const args: string[] = samplerArgumentEnv.split(',');
for (const arg of args) {
const equalIndex: number = arg.indexOf('=');
if (equalIndex === -1) {
continue;
}
const keyValue: string[] = [arg.substring(0, equalIndex), arg.substring(equalIndex + 1)];
if (keyValue[0] === 'endpoint') {
endpoint = keyValue[1];
} else if (keyValue[0] === 'polling_interval') {
pollingInterval = Number(keyValue[1]);
if (isNaN(pollingInterval)) {
pollingInterval = undefined;
diag.error('polling_interval in OTEL_TRACES_SAMPLER_ARG must be a valid number');
}
}
}

diag.debug(`XRay Sampler Endpoint: ${endpoint}`);
diag.debug(`XRay Sampler Polling Interval: ${pollingInterval}`);
return new AwsXRayRemoteSampler({ resource: resource, endpoint: endpoint, pollingInterval: pollingInterval });
}

diag.info('AWS XRay Sampler enabled');
diag.debug(`XRay Sampler Endpoint: ${endpoint}`);
diag.debug(`XRay Sampler Polling Interval: ${pollingInterval}`);
return new AwsXRayRemoteSampler({ resource: resource, endpoint: endpoint, pollingInterval: pollingInterval });
}

return buildSamplerFromEnv();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@
// SPDX-License-Identifier: Apache-2.0
// Modifications Copyright The OpenTelemetry Authors. Licensed under the Apache License 2.0 License.

import { DiagConsoleLogger, diag, trace } from '@opentelemetry/api';
// Short-term workaround to avoid Upsteam OTel emitting logs such as:
// - `OTEL_TRACES_SAMPLER value "xray invalid, defaulting to always_on".`
// OTel dependencies will always load a default Sampler configuration. Although unused, that
// load process will read the `OTEL_TRACES_SAMPLER` value and may emit the above log, which is
// unwanted for `xray` value. Thus we temporarily remove this env var to avoid the unwanted log.
let useXraySampler = false;
if (process.env.OTEL_TRACES_SAMPLER === 'xray') {
delete process.env.OTEL_TRACES_SAMPLER;
useXraySampler = true;
}

import { diag, DiagConsoleLogger, trace } from '@opentelemetry/api';
import { getNodeAutoInstrumentations, InstrumentationConfigMap } from '@opentelemetry/auto-instrumentations-node';
import { Instrumentation } from '@opentelemetry/instrumentation';
import * as opentelemetry from '@opentelemetry/sdk-node';
Expand Down Expand Up @@ -56,7 +67,7 @@ const instrumentations: Instrumentation[] = getNodeAutoInstrumentations(instrume
// Apply instrumentation patches
applyInstrumentationPatches(instrumentations);

const configurator: AwsOpentelemetryConfigurator = new AwsOpentelemetryConfigurator(instrumentations);
const configurator: AwsOpentelemetryConfigurator = new AwsOpentelemetryConfigurator(instrumentations, useXraySampler);
const configuration: Partial<opentelemetry.NodeSDKConfiguration> = configurator.configure();

const sdk: opentelemetry.NodeSDK = new opentelemetry.NodeSDK(configuration);
Expand All @@ -67,14 +78,15 @@ const sdk: opentelemetry.NodeSDK = new opentelemetry.NodeSDK(configuration);
// we wish to make contributions to upstream to improve customizability of the Node auto-instrumentation.
try {
sdk.start();

diag.info('Setting TraceProvider for instrumentations at the end of initialization');
for (const instrumentation of instrumentations) {
diag.info('Set TraceProvider for instrumentations at the end of initialization');
instrumentation.setTracerProvider(trace.getTracerProvider());
}

diag.info('AWS Distro of OpenTelemetry automatic instrumentation started successfully');
diag.debug(`Environment variable OTEL_PROPAGATORS is set to '${process.env.OTEL_PROPAGATORS}'`);
diag.debug(`Environment variable OTEL_EXPORTER_OTLP_PROTOCOL is set to '${process.env.OTEL_EXPORTER_OTLP_PROTOCOL}'`);
diag.info('AWS Distro of OpenTelemetry automatic instrumentation started successfully');
} catch (error) {
diag.error(
'Error initializing AWS Distro of OpenTelemetry SDK. Your application is not instrumented and will not produce telemetry',
Expand All @@ -90,3 +102,8 @@ process.on('SIGTERM', () => {
});

// END The OpenTelemetry Authors code

// Respect original `OTEL_TRACES_SAMPLER` as we previously deleted it temporarily for value `xray`
if (useXraySampler) {
process.env.OTEL_TRACES_SAMPLER = 'xray';
}
Loading