UNPKG

@opentelemetry/sdk-node

Version:
353 lines 17.8 kB
"use strict"; /* * Copyright The 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. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.NodeSDK = void 0; const api_1 = require("@opentelemetry/api"); const api_logs_1 = require("@opentelemetry/api-logs"); const instrumentation_1 = require("@opentelemetry/instrumentation"); const resources_1 = require("@opentelemetry/resources"); const sdk_logs_1 = require("@opentelemetry/sdk-logs"); const exporter_logs_otlp_http_1 = require("@opentelemetry/exporter-logs-otlp-http"); const exporter_logs_otlp_grpc_1 = require("@opentelemetry/exporter-logs-otlp-grpc"); const exporter_logs_otlp_proto_1 = require("@opentelemetry/exporter-logs-otlp-proto"); const exporter_metrics_otlp_grpc_1 = require("@opentelemetry/exporter-metrics-otlp-grpc"); const exporter_metrics_otlp_proto_1 = require("@opentelemetry/exporter-metrics-otlp-proto"); const exporter_metrics_otlp_http_1 = require("@opentelemetry/exporter-metrics-otlp-http"); const exporter_prometheus_1 = require("@opentelemetry/exporter-prometheus"); const sdk_metrics_1 = require("@opentelemetry/sdk-metrics"); const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base"); const sdk_trace_node_1 = require("@opentelemetry/sdk-trace-node"); const semantic_conventions_1 = require("@opentelemetry/semantic-conventions"); const core_1 = require("@opentelemetry/core"); const utils_1 = require("./utils"); /** * @Returns param value, if set else returns the default value */ function getValueInMillis(envName, defaultValue) { return parseInt(process.env[envName] || '') || defaultValue; } /** * * @returns MetricReader[] if appropriate environment variables are configured */ function configureMetricProviderFromEnv() { var _a; const metricReaders = []; const metricsExporterList = (_a = process.env.OTEL_METRICS_EXPORTER) === null || _a === void 0 ? void 0 : _a.trim(); if (!metricsExporterList) { return metricReaders; } const enabledExporters = (0, utils_1.filterBlanksAndNulls)(metricsExporterList.split(',')); if (enabledExporters.length === 0) { api_1.diag.info('OTEL_METRICS_EXPORTER is empty. Using default otlp exporter.'); } if (enabledExporters.includes('none')) { api_1.diag.info(`OTEL_METRICS_EXPORTER contains "none". Metric provider will not be initialized.`); return metricReaders; } enabledExporters.forEach(exporter => { var _a, _b; if (exporter === 'otlp') { const protocol = ((_a = process.env.OTEL_EXPORTER_OTLP_METRICS_PROTOCOL) === null || _a === void 0 ? void 0 : _a.trim()) || ((_b = process.env.OTEL_EXPORTER_OTLP_PROTOCOL) === null || _b === void 0 ? void 0 : _b.trim()); const exportIntervalMillis = getValueInMillis('OTEL_METRIC_EXPORT_INTERVAL', 60000); const exportTimeoutMillis = getValueInMillis('OTEL_METRIC_EXPORT_TIMEOUT', 30000); switch (protocol) { case 'grpc': metricReaders.push(new sdk_metrics_1.PeriodicExportingMetricReader({ exporter: new exporter_metrics_otlp_grpc_1.OTLPMetricExporter(), exportIntervalMillis: exportIntervalMillis, exportTimeoutMillis: exportTimeoutMillis, })); break; case 'http/json': metricReaders.push(new sdk_metrics_1.PeriodicExportingMetricReader({ exporter: new exporter_metrics_otlp_http_1.OTLPMetricExporter(), exportIntervalMillis: exportIntervalMillis, exportTimeoutMillis: exportTimeoutMillis, })); break; case 'http/protobuf': metricReaders.push(new sdk_metrics_1.PeriodicExportingMetricReader({ exporter: new exporter_metrics_otlp_proto_1.OTLPMetricExporter(), exportIntervalMillis: exportIntervalMillis, exportTimeoutMillis: exportTimeoutMillis, })); break; default: api_1.diag.warn(`Unsupported OTLP metrics protocol: "${protocol}". Using http/protobuf.`); metricReaders.push(new sdk_metrics_1.PeriodicExportingMetricReader({ exporter: new exporter_metrics_otlp_proto_1.OTLPMetricExporter(), exportIntervalMillis: exportIntervalMillis, exportTimeoutMillis: exportTimeoutMillis, })); } } else if (exporter === 'console') { metricReaders.push(new sdk_metrics_1.PeriodicExportingMetricReader({ exporter: new sdk_metrics_1.ConsoleMetricExporter(), })); } else if (exporter === 'prometheus') { metricReaders.push(new exporter_prometheus_1.PrometheusExporter()); } else { api_1.diag.warn(`Unsupported OTEL_METRICS_EXPORTER value: "${exporter}". Supported values are: otlp, console, prometheus, none.`); } }); return metricReaders; } class NodeSDK { /** * Create a new NodeJS SDK instance */ constructor(configuration = {}) { var _a, _b, _c, _d, _e, _f, _g; const env = (0, core_1.getEnv)(); const envWithoutDefaults = (0, core_1.getEnvWithoutDefaults)(); if (env.OTEL_SDK_DISABLED) { this._disabled = true; // Functions with possible side-effects are set // to no-op via the _disabled flag } // Default is INFO, use environment without defaults to check // if the user originally set the environment variable. if (envWithoutDefaults.OTEL_LOG_LEVEL) { api_1.diag.setLogger(new api_1.DiagConsoleLogger(), { logLevel: envWithoutDefaults.OTEL_LOG_LEVEL, }); } this._configuration = configuration; this._resource = (_a = configuration.resource) !== null && _a !== void 0 ? _a : new resources_1.Resource({}); this._mergeResourceWithDefaults = (_b = configuration.mergeResourceWithDefaults) !== null && _b !== void 0 ? _b : true; this._autoDetectResources = (_c = configuration.autoDetectResources) !== null && _c !== void 0 ? _c : true; if (!this._autoDetectResources) { this._resourceDetectors = []; } else if (configuration.resourceDetectors != null) { this._resourceDetectors = configuration.resourceDetectors; } else if (process.env.OTEL_NODE_RESOURCE_DETECTORS != null) { this._resourceDetectors = (0, utils_1.getResourceDetectorsFromEnv)(); } else { this._resourceDetectors = [resources_1.envDetector, resources_1.processDetector, resources_1.hostDetector]; } this._serviceName = configuration.serviceName; // If a tracer provider can be created from manual configuration, create it if (configuration.traceExporter || configuration.spanProcessor || configuration.spanProcessors) { const tracerProviderConfig = {}; if (configuration.sampler) { tracerProviderConfig.sampler = configuration.sampler; } if (configuration.spanLimits) { tracerProviderConfig.spanLimits = configuration.spanLimits; } if (configuration.idGenerator) { tracerProviderConfig.idGenerator = configuration.idGenerator; } if (configuration.spanProcessor) { api_1.diag.warn("The 'spanProcessor' option is deprecated. Please use 'spanProcessors' instead."); } const spanProcessor = (_d = configuration.spanProcessor) !== null && _d !== void 0 ? _d : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion new sdk_trace_base_1.BatchSpanProcessor(configuration.traceExporter); const spanProcessors = (_e = configuration.spanProcessors) !== null && _e !== void 0 ? _e : [spanProcessor]; this._tracerProviderConfig = { tracerConfig: tracerProviderConfig, spanProcessors, contextManager: configuration.contextManager, textMapPropagator: configuration.textMapPropagator, }; } if (configuration.logRecordProcessors) { this._loggerProviderConfig = { logRecordProcessors: configuration.logRecordProcessors, }; } else if (configuration.logRecordProcessor) { this._loggerProviderConfig = { logRecordProcessors: [configuration.logRecordProcessor], }; api_1.diag.warn("The 'logRecordProcessor' option is deprecated. Please use 'logRecordProcessors' instead."); } else { this.configureLoggerProviderFromEnv(); } if (configuration.metricReader || configuration.views) { const meterProviderConfig = {}; if (configuration.metricReader) { meterProviderConfig.reader = configuration.metricReader; } if (configuration.views) { meterProviderConfig.views = configuration.views; } this._meterProviderConfig = meterProviderConfig; } this._instrumentations = (_g = (_f = configuration.instrumentations) === null || _f === void 0 ? void 0 : _f.flat()) !== null && _g !== void 0 ? _g : []; } /** * Call this method to construct SDK components and register them with the OpenTelemetry API. */ start() { var _a, _b, _c, _d, _e, _f, _g; if (this._disabled) { return; } (0, instrumentation_1.registerInstrumentations)({ instrumentations: this._instrumentations, }); if (this._autoDetectResources) { const internalConfig = { detectors: this._resourceDetectors, }; this._resource = this._resource.merge((0, resources_1.detectResourcesSync)(internalConfig)); } this._resource = this._serviceName === undefined ? this._resource : this._resource.merge(new resources_1.Resource({ [semantic_conventions_1.SEMRESATTRS_SERVICE_NAME]: this._serviceName, })); const spanProcessors = this._tracerProviderConfig ? this._tracerProviderConfig.spanProcessors : (0, utils_1.getSpanProcessorsFromEnv)(); // If the Provider is configured with Env Exporters, we need to check if the SDK had any manual configurations and set them here this._tracerProvider = new sdk_trace_node_1.NodeTracerProvider(Object.assign(Object.assign({}, this._configuration), { resource: this._resource, mergeResourceWithDefaults: this._mergeResourceWithDefaults, spanProcessors })); // Only register if there is a span processor if (spanProcessors.length > 0) { this._tracerProvider.register({ contextManager: (_b = (_a = this._tracerProviderConfig) === null || _a === void 0 ? void 0 : _a.contextManager) !== null && _b !== void 0 ? _b : // _tracerProviderConfig may be undefined if trace-specific settings are not provided - fall back to raw config (_c = this._configuration) === null || _c === void 0 ? void 0 : _c.contextManager, propagator: (_d = this._tracerProviderConfig) === null || _d === void 0 ? void 0 : _d.textMapPropagator, }); } if (this._loggerProviderConfig) { const loggerProvider = new sdk_logs_1.LoggerProvider({ resource: this._resource, mergeResourceWithDefaults: this._mergeResourceWithDefaults, }); for (const logRecordProcessor of this._loggerProviderConfig .logRecordProcessors) { loggerProvider.addLogRecordProcessor(logRecordProcessor); } this._loggerProvider = loggerProvider; api_logs_1.logs.setGlobalLoggerProvider(loggerProvider); } const metricReadersFromEnv = configureMetricProviderFromEnv(); if (this._meterProviderConfig || metricReadersFromEnv.length > 0) { const readers = []; if ((_e = this._meterProviderConfig) === null || _e === void 0 ? void 0 : _e.reader) { readers.push(this._meterProviderConfig.reader); } if (readers.length === 0) { metricReadersFromEnv.forEach((r) => readers.push(r)); } const meterProvider = new sdk_metrics_1.MeterProvider({ resource: this._resource, views: (_g = (_f = this._meterProviderConfig) === null || _f === void 0 ? void 0 : _f.views) !== null && _g !== void 0 ? _g : [], readers: readers, mergeResourceWithDefaults: this._mergeResourceWithDefaults, }); this._meterProvider = meterProvider; api_1.metrics.setGlobalMeterProvider(meterProvider); // TODO: This is a workaround to fix https://github.com/open-telemetry/opentelemetry-js/issues/3609 // If the MeterProvider is not yet registered when instrumentations are registered, all metrics are dropped. // This code is obsolete once https://github.com/open-telemetry/opentelemetry-js/issues/3622 is implemented. for (const instrumentation of this._instrumentations) { instrumentation.setMeterProvider(api_1.metrics.getMeterProvider()); } } } shutdown() { const promises = []; if (this._tracerProvider) { promises.push(this._tracerProvider.shutdown()); } if (this._loggerProvider) { promises.push(this._loggerProvider.shutdown()); } if (this._meterProvider) { promises.push(this._meterProvider.shutdown()); } return (Promise.all(promises) // return void instead of the array from Promise.all .then(() => { })); } configureLoggerProviderFromEnv() { var _a; const logExportersList = (_a = process.env.OTEL_LOGS_EXPORTER) !== null && _a !== void 0 ? _a : ''; const enabledExporters = (0, utils_1.filterBlanksAndNulls)(logExportersList.split(',')); if (enabledExporters.length === 0) { api_1.diag.info('OTEL_LOGS_EXPORTER is empty. Using default otlp exporter.'); enabledExporters.push('otlp'); } if (enabledExporters.includes('none')) { api_1.diag.info(`OTEL_LOGS_EXPORTER contains "none". Logger provider will not be initialized.`); return; } const exporters = []; enabledExporters.forEach(exporter => { var _a, _b; if (exporter === 'otlp') { const protocol = (_b = ((_a = process.env.OTEL_EXPORTER_OTLP_LOGS_PROTOCOL) !== null && _a !== void 0 ? _a : process.env.OTEL_EXPORTER_OTLP_PROTOCOL)) === null || _b === void 0 ? void 0 : _b.trim(); switch (protocol) { case 'grpc': exporters.push(new exporter_logs_otlp_grpc_1.OTLPLogExporter()); break; case 'http/json': exporters.push(new exporter_logs_otlp_http_1.OTLPLogExporter()); break; case 'http/protobuf': exporters.push(new exporter_logs_otlp_proto_1.OTLPLogExporter()); break; case undefined: case '': exporters.push(new exporter_logs_otlp_proto_1.OTLPLogExporter()); break; default: api_1.diag.warn(`Unsupported OTLP logs protocol: "${protocol}". Using http/protobuf.`); exporters.push(new exporter_logs_otlp_proto_1.OTLPLogExporter()); } } else if (exporter === 'console') { exporters.push(new sdk_logs_1.ConsoleLogRecordExporter()); } else { api_1.diag.warn(`Unsupported OTEL_LOGS_EXPORTER value: "${exporter}". Supported values are: otlp, console, none.`); } }); if (exporters.length > 0) { this._loggerProviderConfig = { logRecordProcessors: exporters.map(exporter => { if (exporter instanceof sdk_logs_1.ConsoleLogRecordExporter) { return new sdk_logs_1.SimpleLogRecordProcessor(exporter); } else { return new sdk_logs_1.BatchLogRecordProcessor(exporter); } }), }; } } } exports.NodeSDK = NodeSDK; //# sourceMappingURL=sdk.js.map