UNPKG

@opentelemetry/instrumentation-winston

Version:
282 lines 11.9 kB
"use strict"; /* * Copyright The OpenTelemetry Authors * SPDX-License-Identifier: Apache-2.0 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.WinstonInstrumentation = void 0; const api_1 = require("@opentelemetry/api"); const api_logs_1 = require("@opentelemetry/api-logs"); const instrumentation_1 = require("@opentelemetry/instrumentation"); /** @knipignore */ const version_1 = require("./version"); const winston3Versions = ['>=3 <4']; const winstonPre3Versions = ['>=1 <3']; class WinstonInstrumentation extends instrumentation_1.InstrumentationBase { constructor(config = {}) { super(version_1.PACKAGE_NAME, version_1.PACKAGE_VERSION, config); } init() { const winstons3instrumentationNodeModuleDefinition = new instrumentation_1.InstrumentationNodeModuleDefinition('winston', winston3Versions, moduleExports => moduleExports, () => { }, [ new instrumentation_1.InstrumentationNodeModuleFile('winston/lib/winston/logger.js', winston3Versions, (logger) => { if ((0, instrumentation_1.isWrapped)(logger.prototype['write'])) { this._unwrap(logger.prototype, 'write'); } this._wrap(logger.prototype, 'write', this._getPatchedWrite()); // Wrap configure if ((0, instrumentation_1.isWrapped)(logger.prototype['configure'])) { this._unwrap(logger.prototype, 'configure'); } this._wrap(logger.prototype, 'configure', this._getPatchedConfigure()); return logger; }, (logger) => { if (logger === undefined) return; this._unwrap(logger.prototype, 'write'); this._unwrap(logger.prototype, 'configure'); }), ]); const winstons2instrumentationNodeModuleDefinition = new instrumentation_1.InstrumentationNodeModuleDefinition('winston', winstonPre3Versions, moduleExports => moduleExports, () => { }, [ new instrumentation_1.InstrumentationNodeModuleFile('winston/lib/winston/logger.js', winstonPre3Versions, (fileExports) => { const proto = fileExports.Logger.prototype; if ((0, instrumentation_1.isWrapped)(proto.log)) { this._unwrap(proto, 'log'); } this._wrap(proto, 'log', this._getPatchedLog()); return fileExports; }, (fileExports) => { if (fileExports === undefined) return; this._unwrap(fileExports.Logger.prototype, 'log'); }), ]); return [ winstons3instrumentationNodeModuleDefinition, winstons2instrumentationNodeModuleDefinition, ]; } _callHook(span, record) { const { logHook } = this.getConfig(); if (!logHook) { return; } (0, instrumentation_1.safeExecuteInTheMiddle)(() => logHook(span, record), err => { if (err) { this._diag.error('error calling logHook', err); } }, true); } _getPatchedWrite() { return (original) => { const instrumentation = this; return function patchedWrite(...args) { const record = args[0]; instrumentation._handleLogCorrelation(record); return original.apply(this, args); }; }; } _getPatchedLog() { return (original) => { const instrumentation = this; return function patchedLog(...args) { const record = {}; instrumentation._handleLogCorrelation(record); // Inject in metadata argument let isDataInjected = false; for (let i = args.length - 1; i >= 0; i--) { if (typeof args[i] === 'object') { args[i] = Object.assign(args[i], record); isDataInjected = true; break; } } if (!isDataInjected) { const insertAt = typeof args[args.length - 1] === 'function' ? args.length - 1 : args.length; args.splice(insertAt, 0, record); } return original.apply(this, args); }; }; } _getPatchedConfigure() { return (original) => { const instrumentation = this; return function patchedConfigure(...args) { const config = instrumentation.getConfig(); if (!config.disableLogSending) { if (args && args.length > 0) { // Try to load Winston transport try { const { OpenTelemetryTransportV3, } = require('@opentelemetry/winston-transport'); const originalTransports = args[0].transports; let newTransports = Array.isArray(originalTransports) ? originalTransports : []; let transportOptions = {}; if (config.logSeverity) { const winstonLevel = instrumentation._winstonLevelFromSeverity(config.logSeverity, args[0].levels); transportOptions = { level: winstonLevel }; } const openTelemetryTransport = new OpenTelemetryTransportV3(transportOptions); if (originalTransports && !Array.isArray(originalTransports)) { newTransports = [originalTransports]; } newTransports.push(openTelemetryTransport); args[0].transports = newTransports; } catch (err) { instrumentation._diag.warn('@opentelemetry/winston-transport is not available, log records will not be automatically sent.'); } } } return original.apply(this, args); }; }; } _handleLogCorrelation(record) { if (!this.getConfig().disableLogCorrelation) { const span = api_1.trace.getSpan(api_1.context.active()); if (span) { const spanContext = span.spanContext(); if ((0, api_1.isSpanContextValid)(spanContext)) { const fields = { trace_id: spanContext.traceId, span_id: spanContext.spanId, trace_flags: `0${spanContext.traceFlags.toString(16)}`, }; const enhancedRecord = Object.assign(record, fields); this._callHook(span, enhancedRecord); return enhancedRecord; } } } return record; } _winstonLevelFromSeverity(severity, winstonLevels) { if (winstonLevels) { if (isNpmLevels(winstonLevels)) { if (severity >= api_logs_1.SeverityNumber.ERROR) { return 'error'; } else if (severity >= api_logs_1.SeverityNumber.WARN) { return 'warn'; } else if (severity >= api_logs_1.SeverityNumber.INFO) { return 'info'; } else if (severity >= api_logs_1.SeverityNumber.DEBUG3) { return 'http'; } else if (severity >= api_logs_1.SeverityNumber.DEBUG2) { return 'verbose'; } else if (severity >= api_logs_1.SeverityNumber.DEBUG) { return 'debug'; } else if (severity >= api_logs_1.SeverityNumber.TRACE) { return 'silly'; } } else if (isCliLevels(winstonLevels)) { if (severity >= api_logs_1.SeverityNumber.ERROR) { return 'error'; } else if (severity >= api_logs_1.SeverityNumber.WARN) { return 'warn'; } else if (severity >= api_logs_1.SeverityNumber.INFO3) { return 'help'; } else if (severity >= api_logs_1.SeverityNumber.INFO2) { return 'data'; } else if (severity >= api_logs_1.SeverityNumber.INFO) { return 'info'; } else if (severity >= api_logs_1.SeverityNumber.DEBUG) { return 'debug'; } else if (severity >= api_logs_1.SeverityNumber.TRACE4) { return 'prompt'; } else if (severity >= api_logs_1.SeverityNumber.TRACE3) { return 'verbose'; } else if (severity >= api_logs_1.SeverityNumber.TRACE2) { return 'input'; } else if (severity >= api_logs_1.SeverityNumber.TRACE) { return 'silly'; } } else if (isSyslogLevels(winstonLevels)) { if (severity >= api_logs_1.SeverityNumber.FATAL2) { return 'emerg'; } else if (severity >= api_logs_1.SeverityNumber.FATAL) { return 'alert'; } else if (severity >= api_logs_1.SeverityNumber.ERROR2) { return 'crit'; } else if (severity >= api_logs_1.SeverityNumber.ERROR) { return 'error'; } else if (severity >= api_logs_1.SeverityNumber.WARN) { return 'warning'; } else if (severity >= api_logs_1.SeverityNumber.INFO2) { return 'notice'; } else if (severity >= api_logs_1.SeverityNumber.INFO) { return 'info'; } else if (severity >= api_logs_1.SeverityNumber.TRACE) { return 'debug'; } } // Unknown level this._diag.warn('failed to configure severity with existing winston levels'); } function isCliLevels(arg) { return (arg && arg.error !== undefined && arg.warn && arg.help && arg.data && arg.info && arg.debug && arg.prompt && arg.verbose && arg.input && arg.silly); } function isNpmLevels(arg) { return (arg && arg.error !== undefined && arg.warn && arg.info && arg.http && arg.verbose && arg.debug && arg.silly); } function isSyslogLevels(arg) { return (arg && arg.emerg !== undefined && arg.alert && arg.crit && arg.error && arg.warning && arg.notice && arg.info && arg.debug); } return; } } exports.WinstonInstrumentation = WinstonInstrumentation; //# sourceMappingURL=instrumentation.js.map