mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 04:04:06 -08:00
chore(core): Better debug logs for local dev (#11096)
This commit is contained in:
parent
19fb728da0
commit
4c7caf734c
|
@ -3,9 +3,11 @@ import callsites from 'callsites';
|
|||
import { InstanceSettings } from 'n8n-core';
|
||||
import { LoggerProxy, LOG_LEVELS } from 'n8n-workflow';
|
||||
import path, { basename } from 'node:path';
|
||||
import pc from 'picocolors';
|
||||
import { Service } from 'typedi';
|
||||
import winston from 'winston';
|
||||
|
||||
import { inDevelopment, inProduction } from '@/constants';
|
||||
import { isObjectLiteral } from '@/utils';
|
||||
|
||||
import { noOp } from './constants';
|
||||
|
@ -61,8 +63,7 @@ export class Logger {
|
|||
|
||||
for (const logLevel of LOG_LEVELS) {
|
||||
if (levels[logLevel] > levels[this.level]) {
|
||||
// winston defines `{ error: 0, warn: 1, info: 2, debug: 5 }`
|
||||
// so numerically higher (less severe) log levels become no-op
|
||||
// numerically higher (less severe) log levels become no-op
|
||||
// to prevent overhead from `callsites` calls
|
||||
Object.defineProperty(this, logLevel, { value: noOp });
|
||||
}
|
||||
|
@ -71,24 +72,60 @@ export class Logger {
|
|||
|
||||
private setConsoleTransport() {
|
||||
const format =
|
||||
this.level === 'debug'
|
||||
? winston.format.combine(
|
||||
winston.format.metadata(),
|
||||
winston.format.timestamp(),
|
||||
winston.format.colorize({ all: true }),
|
||||
winston.format.printf(({ level, message, timestamp, metadata }) => {
|
||||
const _metadata = this.toPrintable(metadata);
|
||||
return `${timestamp} | ${level.padEnd(18)} | ${message}${_metadata}`;
|
||||
}),
|
||||
)
|
||||
this.level === 'debug' && inDevelopment
|
||||
? this.debugDevConsoleFormat()
|
||||
: this.level === 'debug' && inProduction
|
||||
? this.debugProdConsoleFormat()
|
||||
: winston.format.printf(({ message }: { message: string }) => message);
|
||||
|
||||
this.internalLogger.add(new winston.transports.Console({ format }));
|
||||
}
|
||||
|
||||
private debugDevConsoleFormat() {
|
||||
return winston.format.combine(
|
||||
winston.format.metadata(),
|
||||
winston.format.timestamp({ format: () => this.devTsFormat() }),
|
||||
winston.format.colorize({ all: true }),
|
||||
winston.format.printf(({ level: _level, message, timestamp, metadata: _metadata }) => {
|
||||
const SEPARATOR = ' '.repeat(3);
|
||||
const LOG_LEVEL_COLUMN_WIDTH = 15; // 5 columns + ANSI color codes
|
||||
const level = _level.toLowerCase().padEnd(LOG_LEVEL_COLUMN_WIDTH, ' ');
|
||||
const metadata = this.toPrintable(_metadata);
|
||||
return [timestamp, level, message + ' ' + pc.dim(metadata)].join(SEPARATOR);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private debugProdConsoleFormat() {
|
||||
return winston.format.combine(
|
||||
winston.format.metadata(),
|
||||
winston.format.timestamp(),
|
||||
winston.format.printf(({ level, message, timestamp, metadata }) => {
|
||||
const _metadata = this.toPrintable(metadata);
|
||||
return `${timestamp} | ${level.padEnd(5)} | ${message}${_metadata ? ' ' + _metadata : ''}`;
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private devTsFormat() {
|
||||
const now = new Date();
|
||||
const pad = (num: number, digits: number = 2) => num.toString().padStart(digits, '0');
|
||||
const hours = pad(now.getHours());
|
||||
const minutes = pad(now.getMinutes());
|
||||
const seconds = pad(now.getSeconds());
|
||||
const milliseconds = pad(now.getMilliseconds(), 3);
|
||||
return `${hours}:${minutes}:${seconds}.${milliseconds}`;
|
||||
}
|
||||
|
||||
private toPrintable(metadata: unknown) {
|
||||
if (isObjectLiteral(metadata) && Object.keys(metadata).length > 0) {
|
||||
return ' ' + JSON.stringify(metadata);
|
||||
return inProduction
|
||||
? JSON.stringify(metadata)
|
||||
: JSON.stringify(metadata)
|
||||
.replace(/{"/g, '{ "')
|
||||
.replace(/,"/g, ', "')
|
||||
.replace(/:/g, ': ')
|
||||
.replace(/}/g, ' }'); // spacing for readability
|
||||
}
|
||||
|
||||
return '';
|
||||
|
|
|
@ -5,17 +5,13 @@ interface ErrorReporter {
|
|||
report: (error: Error | string, options?: ReportingOptions) => void;
|
||||
}
|
||||
|
||||
const { NODE_ENV } = process.env;
|
||||
const inDevelopment = !NODE_ENV || NODE_ENV === 'development';
|
||||
|
||||
const instance: ErrorReporter = {
|
||||
report: (error) => {
|
||||
if (error instanceof Error) {
|
||||
let e = error;
|
||||
do {
|
||||
const meta = e instanceof ApplicationError ? e.extra : undefined;
|
||||
if (inDevelopment) console.log(e, meta);
|
||||
else Logger.error(`${e.constructor.name}: ${e.message}`, meta);
|
||||
Logger.error(`${e.constructor.name}: ${e.message}`, meta);
|
||||
e = e.cause as Error;
|
||||
} while (e);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue