enhanced-adot-node-autoinstrumentation
Version:
This package provides Amazon Web Services distribution of the OpenTelemetry Node Instrumentation, which allows for auto-instrumentation of NodeJS applications.
146 lines (143 loc) • 8.1 kB
JavaScript
;
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
// Modifications Copyright The OpenTelemetry Authors. Licensed under the Apache License 2.0 License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.instrumentationConfigs = exports.setAwsDefaultEnvironmentVariables = void 0;
// 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;
}
const api_1 = require("@opentelemetry/api");
const api_logs_1 = require("@opentelemetry/api-logs");
const auto_instrumentations_node_1 = require("@opentelemetry/auto-instrumentations-node");
const opentelemetry = require("@opentelemetry/sdk-node");
const aws_opentelemetry_configurator_1 = require("./aws-opentelemetry-configurator");
const instrumentation_patch_1 = require("./patches/instrumentation-patch");
const utils_1 = require("./utils");
api_1.diag.setLogger(new api_1.DiagConsoleLogger(), opentelemetry.core.getEnv().OTEL_LOG_LEVEL);
/*
Sets up default environment variables and apply patches
Set default OTEL_EXPORTER_OTLP_PROTOCOL to be `http/protobuf` to remain consistent with other ADOT languages. This must be run before
`configurator.configure()`, which will use this value to create an OTel Metric Exporter that is used for the customized AWS Span Procesors.
The default value of OTEL_EXPORTER_OTLP_PROTOCOL should be `http/protobuf`:
https://github.com/open-telemetry/opentelemetry-js/blob/34003c9b7ef7e7e95e86986550d1c7fb6c1c56c6/packages/opentelemetry-core/src/utils/environment.ts#L233
Also sets default OTEL_PROPAGATORS to ensure good compatibility with X-Ray and Application Signals.
This file may also be used to apply patches to upstream instrumentation - usually these are stopgap measures until we can contribute
long-term changes to upstream.
*/
function setAwsDefaultEnvironmentVariables() {
if (!process.env.OTEL_EXPORTER_OTLP_PROTOCOL) {
process.env.OTEL_EXPORTER_OTLP_PROTOCOL = 'http/protobuf';
}
if (!process.env.OTEL_PROPAGATORS) {
process.env.OTEL_PROPAGATORS = 'xray,tracecontext';
}
if (!process.env.OTEL_NODE_DISABLED_INSTRUMENTATIONS) {
if ((0, utils_1.isAgentObservabilityEnabled)()) {
// Assume users only need instrumentations that are manually set-up outside of OpenTelemetry
process.env.OTEL_NODE_DISABLED_INSTRUMENTATIONS =
'amqplib,aws-lambda,aws-sdk,bunyan,cassandra-driver,connect,cucumber,dataloader,dns,express,fastify,fs,generic-pool,graphql,grpc,hapi,http,ioredis,kafkajs,knex,koa,lru-memoizer,memcached,mongodb,mongoose,mysql2,mysql,nestjs-core,net,pg,pino,redis,redis-4,restify,router,socket.io,tedious,undici,winston';
}
else {
// Disable the following instrumentations by default
// This auto-instrumentation for the `fs` module generates many low-value spans. `dns` is similar.
// https://github.com/open-telemetry/opentelemetry-js-contrib/issues/1344#issuecomment-1618993178
process.env.OTEL_NODE_DISABLED_INSTRUMENTATIONS = 'fs,dns';
}
}
if ((0, utils_1.isAgentObservabilityEnabled)()) {
// Set exporter defaults
if (!process.env.OTEL_EXPORTER_OTLP_PROTOCOL) {
process.env.OTEL_TRACES_EXPORTER = 'otlp';
}
if (!process.env.OTEL_LOGS_EXPORTER) {
process.env.OTEL_LOGS_EXPORTER = 'otlp';
}
if (!process.env.OTEL_METRICS_EXPORTER) {
process.env.OTEL_METRICS_EXPORTER = 'awsemf';
}
// Set GenAI capture content default
if (!process.env.OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT) {
process.env.OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT = 'true';
}
// Set sampler default
if (!process.env.OTEL_TRACES_SAMPLER && !useXraySampler) {
process.env.OTEL_TRACES_SAMPLER = 'parentbased_always_on';
}
// Disable AWS Application Signals by default
if (!process.env.OTEL_AWS_APPLICATION_SIGNALS_ENABLED) {
process.env.OTEL_AWS_APPLICATION_SIGNALS_ENABLED = 'false';
}
// Set OTLP endpoints with AWS region if not already set
const region = (0, utils_1.getAwsRegionFromEnvironment)();
if (region) {
if (!process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) {
process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT = `https://xray.${region}.amazonaws.com/v1/traces`;
}
if (!process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) {
process.env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT = `https://logs.${region}.amazonaws.com/v1/logs`;
}
}
else {
api_1.diag.error('AWS region could not be determined. OTLP endpoints will not be automatically configured. Please set AWS_REGION environment variable or configure OTLP endpoints manually.');
}
}
}
exports.setAwsDefaultEnvironmentVariables = setAwsDefaultEnvironmentVariables;
setAwsDefaultEnvironmentVariables();
exports.instrumentationConfigs = {
'@opentelemetry/instrumentation-aws-lambda': {
eventContextExtractor: instrumentation_patch_1.customExtractor,
},
'@opentelemetry/instrumentation-aws-sdk': {
suppressInternalInstrumentation: true,
},
'@opentelemetry/instrumentation-mongoose': {
suppressInternalInstrumentation: true,
},
};
const instrumentations = (0, auto_instrumentations_node_1.getNodeAutoInstrumentations)(exports.instrumentationConfigs);
// Apply instrumentation patches
(0, instrumentation_patch_1.applyInstrumentationPatches)(instrumentations);
const configurator = new aws_opentelemetry_configurator_1.AwsOpentelemetryConfigurator(instrumentations, useXraySampler);
const configuration = configurator.configure();
const sdk = new opentelemetry.NodeSDK(configuration);
// The OpenTelemetry Authors code
// We need to copy OpenTelemetry's register.ts file in order to provide the configuration
// created by AwsOpentelemetryConfigurator, which cannot be done by otherwise. In the long term,
// we wish to make contributions to upstream to improve customizability of the Node auto-instrumentation.
try {
sdk.start();
api_1.diag.info('Setting TraceProvider for instrumentations at the end of initialization');
for (const instrumentation of instrumentations) {
instrumentation.setTracerProvider(api_1.trace.getTracerProvider());
if (instrumentation.setLoggerProvider) {
instrumentation.setLoggerProvider(api_logs_1.logs.getLoggerProvider());
}
}
api_1.diag.debug(`Environment variable OTEL_PROPAGATORS is set to '${process.env.OTEL_PROPAGATORS}'`);
api_1.diag.debug(`Environment variable OTEL_EXPORTER_OTLP_PROTOCOL is set to '${process.env.OTEL_EXPORTER_OTLP_PROTOCOL}'`);
api_1.diag.info('AWS Distro of OpenTelemetry automatic instrumentation started successfully');
}
catch (error) {
api_1.diag.error('Error initializing AWS Distro of OpenTelemetry SDK. Your application is not instrumented and will not produce telemetry', error);
}
process.on('SIGTERM', () => {
sdk
.shutdown()
.then(() => api_1.diag.debug('AWS Distro of OpenTelemetry SDK terminated'))
.catch(error => api_1.diag.error('Error terminating AWS Distro of OpenTelemetry SDK', error));
});
// 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';
}
//# sourceMappingURL=register.js.map