UNPKG

@azure/monitor-opentelemetry

Version:
159 lines 8.12 kB
"use strict"; // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. Object.defineProperty(exports, "__esModule", { value: true }); exports.useAzureMonitor = useAzureMonitor; exports.shutdownAzureMonitor = shutdownAzureMonitor; exports._getSdkInstance = _getSdkInstance; const api_1 = require("@opentelemetry/api"); const api_logs_1 = require("@opentelemetry/api-logs"); const sdk_node_1 = require("@opentelemetry/sdk-node"); const config_js_1 = require("./shared/config.js"); const index_js_1 = require("./metrics/index.js"); const handler_js_1 = require("./traces/handler.js"); const index_js_2 = require("./logs/index.js"); const types_js_1 = require("./types.js"); const browserSdkLoader_js_1 = require("./browserSdkLoader/browserSdkLoader.js"); const utils_js_1 = require("./metrics/quickpulse/utils.js"); const statsbeat_js_1 = require("./utils/statsbeat.js"); const opentelemetryInstrumentationPatcher_js_1 = require("./utils/opentelemetryInstrumentationPatcher.js"); const azureSdkTracingBridge_js_1 = require("./utils/azureSdkTracingBridge.js"); const common_js_1 = require("./utils/common.js"); const index_js_3 = require("./shared/logging/index.js"); const types_js_2 = require("./types.js"); const semantic_conventions_1 = require("@opentelemetry/semantic-conventions"); /** * Semantic attribute for cloud resource ID, defined by \@opentelemetry/resource-detector-azure * @internal */ const CLOUD_RESOURCE_ID_ATTRIBUTE = "cloud.resource_id"; process.env["AZURE_MONITOR_DISTRO_VERSION"] = types_js_1.AZURE_MONITOR_OPENTELEMETRY_VERSION; let sdk; let browserSdkLoader; /** * Check if auto-attach (autoinstrumentation) is enabled and warn about double instrumentation. */ function sendAttachWarning() { if (process.env[types_js_2.AZURE_MONITOR_AUTO_ATTACH] === "true" && !(0, common_js_1.isFunctionApp)()) { // TODO: When AKS attach is public, update this message with disablement instructions for AKS const message = "Distro detected that automatic instrumentation may have occurred. Only use autoinstrumentation if you " + "are not using manual instrumentation of OpenTelemetry in your code, such as with " + "@azure/monitor-opentelemetry or @azure/monitor-opentelemetry-exporter. For App Service resources, disable " + "autoinstrumentation in the Application Insights experience on your App Service resource or by setting " + "the ApplicationInsightsAgent_EXTENSION_VERSION app setting to 'disabled'."; // Surface in the log stream console.warn(message); // Also log via diagnostic logging index_js_3.Logger.getInstance().warn(message); } } /** * Initialize Azure Monitor Distro * @param options - Azure Monitor OpenTelemetry Options */ function useAzureMonitor(options) { const config = new config_js_1.InternalConfig(options); (0, opentelemetryInstrumentationPatcher_js_1.patchOpenTelemetryInstrumentationEnable)(); const statsbeatInstrumentations = { // Instrumentations azureSdk: config.instrumentationOptions?.azureSdk?.enabled, mongoDb: config.instrumentationOptions?.mongoDb?.enabled, mySql: config.instrumentationOptions?.mySql?.enabled, postgreSql: config.instrumentationOptions?.postgreSql?.enabled, redis: config.instrumentationOptions?.redis?.enabled, bunyan: config.instrumentationOptions?.bunyan?.enabled, winston: config.instrumentationOptions?.winston?.enabled, }; // Check if the AKS resource detector successfully populated specific resource attributes // (k8s.cluster.name or cloud.resource_id) beyond the basic cloud.platform/cloud.provider // Derive from config.resource.attributes which already includes the AKS detector results const resourceAttributes = config.resource.attributes; const aksResourceDetected = semantic_conventions_1.SEMRESATTRS_K8S_CLUSTER_NAME in resourceAttributes || CLOUD_RESOURCE_ID_ATTRIBUTE in resourceAttributes; const statsbeatFeatures = { browserSdkLoader: config.browserSdkLoaderOptions.enabled, aadHandling: !!config.azureMonitorExporterOptions?.credential, diskRetry: !config.azureMonitorExporterOptions?.disableOfflineStorage, customerSdkStats: process.env[types_js_1.APPLICATIONINSIGHTS_SDKSTATS_DISABLED]?.toLowerCase() === "true", aksResourceDetectorPopulation: aksResourceDetected, }; (0, statsbeat_js_1.getInstance)().setStatsbeatFeatures(statsbeatInstrumentations, statsbeatFeatures); if (config.browserSdkLoaderOptions.enabled) { browserSdkLoader = new browserSdkLoader_js_1.BrowserSdkLoader(config); } // Remove global providers in OpenTelemetry, these would be overridden if present api_1.metrics.disable(); api_1.trace.disable(); api_logs_1.logs.disable(); // Clear the entire OpenTelemetry API global state to avoid version conflicts. // The disable() calls above remove individual providers but leave the `version` field // on the global object intact. If a different version of @opentelemetry/api was loaded // first (e.g. by a VS Code extension host or another extension), the stale version // causes registerGlobal() in sdk.start() to fail with "All API registration versions // must match", resulting in Noop providers. Deleting the global object forces // registerGlobal() to create a fresh one with the correct version. const globalOpentelemetryApiKey = Symbol.for("opentelemetry.js.api.1"); Reflect.deleteProperty(globalThis, globalOpentelemetryApiKey); // Create internal handlers const metricHandler = new index_js_1.MetricHandler(config); const traceHandler = new handler_js_1.TraceHandler(config, metricHandler); const logHandler = new index_js_2.LogHandler(config, metricHandler); const instrumentations = traceHandler .getInstrumentations() .concat(logHandler.getInstrumentations()); const resourceDetectorsList = (0, common_js_1.parseResourceDetectorsFromEnvVar)(); // Add extra SpanProcessors, and logRecordProcessors from user configuration const spanProcessors = options?.spanProcessors || []; const logRecordProcessors = options?.logRecordProcessors || []; const customViews = options?.views || []; // Prepare metric readers - always include Azure Monitor const metricReaders = [ metricHandler.getMetricReader(), ...(options?.metricReaders || []), ]; const views = metricHandler.getViews().concat(customViews); // Initialize OpenTelemetry SDK const sdkConfig = { autoDetectResources: true, metricReaders: metricReaders, views, instrumentations: instrumentations, logRecordProcessors: [ logHandler.getAzureLogRecordProcessor(), ...logRecordProcessors, logHandler.getBatchLogRecordProcessor(), ], resource: config.resource, sampler: traceHandler.getSampler(), spanProcessors: [ traceHandler.getAzureMonitorSpanProcessor(), ...spanProcessors, traceHandler.getBatchSpanProcessor(), ], resourceDetectors: resourceDetectorsList, }; sdk = new sdk_node_1.NodeSDK(sdkConfig); (0, utils_js_1.setSdkPrefix)(); sendAttachWarning(); sdk.start(); // Eagerly install the Azure SDK tracing bridge in case @azure/core-tracing // was loaded before useAzureMonitor() (the RITM hook misses it otherwise). (0, azureSdkTracingBridge_js_1.ensureAzureSdkTracingBridge)(); } /** * Shutdown Azure Monitor Open Telemetry Distro * @see https://github.com/open-telemetry/opentelemetry-js/blob/0229434cb5a3179f63c021105f36270ae7897929/experimental/packages/opentelemetry-sdk-node/src/sdk.ts#L398 */ function shutdownAzureMonitor() { browserSdkLoader?.dispose(); return sdk?.shutdown(); } /** * Get the internal SDK instance for testing purposes * @internal */ // eslint-disable-next-line no-underscore-dangle function _getSdkInstance() { return sdk; } //# sourceMappingURL=index.js.map