@sentry/node
Version:
Sentry Node SDK using OpenTelemetry for performance instrumentation
150 lines (134 loc) • 3.77 kB
JavaScript
import { captureLog } from '../logs/capture.js';
const DEFAULT_CAPTURED_LEVELS = ['trace', 'debug', 'info', 'warn', 'error', 'fatal'];
// See: https://github.com/winstonjs/triple-beam
const LEVEL_SYMBOL = Symbol.for('level');
const MESSAGE_SYMBOL = Symbol.for('message');
const SPLAT_SYMBOL = Symbol.for('splat');
/**
* Options for the Sentry Winston transport.
*/
/**
* Creates a new Sentry Winston transport that fowards logs to Sentry. Requires `_experiments.enableLogs` to be enabled.
*
* Supports Winston 3.x.x.
*
* @param TransportClass - The Winston transport class to extend.
* @returns The extended transport class.
*
* @experimental This method will experience breaking changes. This is not yet part of
* the stable Sentry SDK API and can be changed or removed without warning.
*
* @example
* ```ts
* const winston = require('winston');
* const Transport = require('winston-transport');
*
* const SentryWinstonTransport = Sentry.createSentryWinstonTransport(Transport);
*
* const logger = winston.createLogger({
* transports: [new SentryWinstonTransport()],
* });
* ```
*/
function createSentryWinstonTransport(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
TransportClass,
sentryWinstonOptions,
) {
// @ts-ignore - We know this is safe because SentryWinstonTransport extends TransportClass
class SentryWinstonTransport extends TransportClass {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
constructor(options) {
super(options);
this._levels = new Set(sentryWinstonOptions?.levels ?? DEFAULT_CAPTURED_LEVELS);
}
/**
* Forwards a winston log to the Sentry SDK.
*/
log(info, callback) {
try {
setImmediate(() => {
// @ts-ignore - We know this is safe because SentryWinstonTransport extends TransportClass
this.emit('logged', info);
});
if (!isObject(info)) {
return;
}
const levelFromSymbol = info[LEVEL_SYMBOL];
// See: https://github.com/winstonjs/winston?tab=readme-ov-file#streams-objectmode-and-info-objects
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { level, message, timestamp, ...attributes } = info;
// Remove all symbols from the remaining attributes
attributes[LEVEL_SYMBOL] = undefined;
attributes[MESSAGE_SYMBOL] = undefined;
attributes[SPLAT_SYMBOL] = undefined;
const logSeverityLevel = WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP[levelFromSymbol ] ?? 'info';
if (this._levels.has(logSeverityLevel)) {
captureLog(logSeverityLevel, message , {
...attributes,
'sentry.origin': 'auto.logging.winston',
});
}
} catch {
// do nothing
}
if (callback) {
callback();
}
}
}
return SentryWinstonTransport ;
}
function isObject(anything) {
return typeof anything === 'object' && anything != null;
}
// npm
// {
// error: 0,
// warn: 1,
// info: 2,
// http: 3,
// verbose: 4,
// debug: 5,
// silly: 6
// }
//
// syslog
// {
// emerg: 0,
// alert: 1,
// crit: 2,
// error: 3,
// warning: 4,
// notice: 5,
// info: 6,
// debug: 7,
// }
const WINSTON_LEVEL_TO_LOG_SEVERITY_LEVEL_MAP = {
// npm
silly: 'trace',
// npm and syslog
debug: 'debug',
// npm
verbose: 'debug',
// npm
http: 'debug',
// npm and syslog
info: 'info',
// syslog
notice: 'info',
// npm
warn: 'warn',
// syslog
warning: 'warn',
// npm and syslog
error: 'error',
// syslog
emerg: 'fatal',
// syslog
alert: 'fatal',
// syslog
crit: 'fatal',
};
export { createSentryWinstonTransport };
//# sourceMappingURL=winston.js.map