UNPKG

autotel

Version:
172 lines (170 loc) 7.33 kB
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); const require_node_require = require('./node-require-CZ_PU448.cjs'); const require_init = require('./init-BXiuPK6j.cjs'); const require_tail_sampling_processor = require('./tail-sampling-processor.cjs'); let _opentelemetry_sdk_node = require("@opentelemetry/sdk-node"); let _opentelemetry_sdk_trace_base = require("@opentelemetry/sdk-trace-base"); let _opentelemetry_resources = require("@opentelemetry/resources"); let _opentelemetry_sdk_metrics = require("@opentelemetry/sdk-metrics"); let _opentelemetry_exporter_metrics_otlp_http = require("@opentelemetry/exporter-metrics-otlp-http"); let _opentelemetry_exporter_trace_otlp_http = require("@opentelemetry/exporter-trace-otlp-http"); let _opentelemetry_exporter_logs_otlp_http = require("@opentelemetry/exporter-logs-otlp-http"); let _opentelemetry_sdk_logs = require("@opentelemetry/sdk-logs"); let _opentelemetry_semantic_conventions_incubating = require("@opentelemetry/semantic-conventions/incubating"); //#region src/instrumentation.ts /** * Parse OTLP headers string into object format * @param headersString - Headers as "key1=value1,key2=value2" or "Authorization=Basic ..." * @returns Headers object for OTLP exporters */ function parseOtlpHeaders(headersString) { if (!headersString) return {}; const headers = {}; const pairs = headersString.split(","); for (const pair of pairs) { const [key, ...valueParts] = pair.split("="); if (key && valueParts.length > 0) headers[key.trim()] = valueParts.join("=").trim(); } return headers; } /** * Parse resource attributes string into object format * @param attributesString - Attributes as "key1=value1,key2=value2" * @returns Resource attributes object */ function parseResourceAttributes(attributesString) { if (!attributesString) return {}; const attributes = {}; const pairs = attributesString.split(","); for (const pair of pairs) { const [key, ...valueParts] = pair.split("="); if (key && valueParts.length > 0) attributes[key.trim()] = valueParts.join("=").trim(); } return attributes; } /** * Initialize OpenTelemetry instrumentation with OTLP exporters * * This sets up: * - Traces (OTLP HTTP) * - Metrics (OTLP HTTP) * - Logs (OTLP HTTP) * - Auto-instrumentation for common Node.js libraries * * @example * // Call this at the very start of your application * import { initInstrumentation } from '@your-org/otel-decorators' * * initInstrumentation({ * serviceName: 'my-service' } * serviceVersion: '1.0.0', * deploymentEnvironment: 'production', * otlpEndpoint: 'http://localhost:4318' * }) * * // Or with async resource detection (top-level await required) * await initInstrumentation({ * serviceName: 'my-service' } * detectResources: true * }) */ let currentSDK = null; let shutdownHandlerRegistered = false; /** * Shutdown the OpenTelemetry SDK gracefully * Call this before process exit or during hot-reloads */ async function shutdownInstrumentation(sdk) { const sdkToShutdown = sdk || currentSDK; if (!sdkToShutdown) { require_init.getLogger().warn({}, "No SDK to shutdown"); return; } try { await sdkToShutdown.shutdown(); require_init.getLogger().info({}, "OpenTelemetry terminated successfully"); if (sdkToShutdown === currentSDK) currentSDK = null; } catch (error) { require_init.getLogger().error({ err: error instanceof Error ? error : void 0 }, "Error terminating OpenTelemetry"); throw error; } } async function initInstrumentation(config) { if (currentSDK) { require_init.getLogger().info({}, "Shutting down existing OpenTelemetry SDK before reinitializing..."); await shutdownInstrumentation(currentSDK); } const otlpHeaders = parseOtlpHeaders(config.headers); const customResourceAttributes = parseResourceAttributes(config.resourceAttributes); let resource; const detectors = [_opentelemetry_resources.processDetector, _opentelemetry_resources.hostDetector]; try { const awsDetectors = await import("@opentelemetry/resource-detector-aws"); detectors.push(awsDetectors.awsEc2Detector, awsDetectors.awsEcsDetector, awsDetectors.awsEksDetector); } catch {} try { const gcpDetectors = await import("@opentelemetry/resource-detector-gcp"); detectors.push(gcpDetectors.gcpDetector); } catch {} try { const containerDetectors = await import("@opentelemetry/resource-detector-container"); detectors.push(containerDetectors.containerDetector); } catch {} if (config.detectResources) resource = (await (0, _opentelemetry_resources.detectResources)({ detectors })).merge((0, _opentelemetry_resources.resourceFromAttributes)({ [_opentelemetry_semantic_conventions_incubating.ATTR_SERVICE_NAME]: config.serviceName, [_opentelemetry_semantic_conventions_incubating.ATTR_SERVICE_VERSION]: config.serviceVersion || "1.0.0", "deployment.environment": config.deploymentEnvironment || "development", ...customResourceAttributes })); else resource = (0, _opentelemetry_resources.resourceFromAttributes)({ [_opentelemetry_semantic_conventions_incubating.ATTR_SERVICE_NAME]: config.serviceName, [_opentelemetry_semantic_conventions_incubating.ATTR_SERVICE_VERSION]: config.serviceVersion || "1.0.0", "deployment.environment": config.deploymentEnvironment || "development", ...customResourceAttributes }); let instrumentations = config.instrumentations || []; if (config.selectiveInstrumentation === false) instrumentations = [require_node_require.requireModule("@opentelemetry/auto-instrumentations-node").getNodeAutoInstrumentations()]; const spanProcessor = new require_tail_sampling_processor.TailSamplingSpanProcessor(new _opentelemetry_sdk_trace_base.BatchSpanProcessor(new _opentelemetry_exporter_trace_otlp_http.OTLPTraceExporter({ url: `${config.otlpEndpoint || "http://localhost:4318"}/v1/traces`, headers: otlpHeaders }))); const sdk = new _opentelemetry_sdk_node.NodeSDK({ resource, spanProcessor, metricReader: new _opentelemetry_sdk_metrics.PeriodicExportingMetricReader({ exporter: new _opentelemetry_exporter_metrics_otlp_http.OTLPMetricExporter({ url: `${config.otlpEndpoint || "http://localhost:4318"}/v1/metrics`, headers: otlpHeaders }) }), logRecordProcessors: [new _opentelemetry_sdk_logs.BatchLogRecordProcessor(new _opentelemetry_exporter_logs_otlp_http.OTLPLogExporter({ url: `${config.otlpEndpoint || "http://localhost:4318"}/v1/logs`, headers: otlpHeaders }))], instrumentations }); try { await sdk.start(); require_init.getLogger().info({}, "OpenTelemetry instrumentation started successfully"); } catch (error) { require_init.getLogger().error({ err: error instanceof Error ? error : void 0 }, "Failed to start OpenTelemetry SDK"); throw error; } currentSDK = sdk; if (!shutdownHandlerRegistered) { shutdownHandlerRegistered = true; const shutdownHandler = () => { shutdownInstrumentation().then(() => { process.exit(0); }).catch((error) => { require_init.getLogger().error({ err: error instanceof Error ? error : void 0 }, "Shutdown error"); process.exit(1); }); }; process.on("SIGTERM", shutdownHandler); process.on("SIGINT", shutdownHandler); } return sdk; } //#endregion exports.initInstrumentation = initInstrumentation; exports.shutdownInstrumentation = shutdownInstrumentation; //# sourceMappingURL=instrumentation.cjs.map