如何使用 Winston 3 记录完整的堆栈跟踪?
Posted
技术标签:
【中文标题】如何使用 Winston 3 记录完整的堆栈跟踪?【英文标题】:How to Log Full Stack Trace with Winston 3? 【发布时间】:2018-04-24 04:59:21 【问题描述】:我的记录器设置如下:
const myFormat = printf(info =>
return `$info.timestamp: $info.level: $info.message: $info.err`;
);
const logger =
winston.createLogger(
level: "info",
format: combine(timestamp(), myFormat),
transports: [
new winston.transports.File(
filename:
"./logger/error.log",
level: "error"
),
new winston.transports.File(
filename:
"./logger/info.log",
level: "info"
)
]
)
然后我正在注销一些这样的错误:
logger.error(`GET on /history`, err );
如何通过错误传输记录错误的完整堆栈跟踪?我尝试传入 err.stack,结果显示为未定义。
谢谢!
【问题讨论】:
【参考方案1】:您可以编写一个格式化程序将error.stack
传递给日志。
const errorStackFormat = winston.format(info =>
if (info instanceof Error)
return Object.assign(, info,
stack: info.stack,
message: info.message
)
return info
)
const logger = winston.createLogger(
transports: [ ... ],
format: winston.format.combine(errorStackFormat(), myFormat)
)
logger.info(new Error('yo')) // => message: 'yo', stack: "Error blut at xxx.js:xx ......"
(输出将取决于您的配置)
【讨论】:
什么是myFormat
?
如果我们需要记录一条消息,然后是一个错误(类似于 Java 的 log4j 等):logger.error('Failed to do sth', e)
?【参考方案2】:
2021 年 1 月 14 日更新 - 这不再适用于新版本的 Winston。
原答案
@Ming 的回答让我部分明白了,但是要对错误进行字符串描述,这就是我在我们的问题上进行完整堆栈跟踪的方式:
import winston from "winston";
const errorStackTracerFormat = winston.format(info =>
if (info.meta && info.meta instanceof Error)
info.message = `$info.message $info.meta.stack`;
return info;
);
const logger = winston.createLogger(
format: winston.format.combine(
winston.format.splat(), // Necessary to produce the 'meta' property
errorStackTracerFormat(),
winston.format.simple()
)
);
logger.error("Does this work?", new Error("Yup!"));
// The log output:
// error: Does this work? Error: Yup!
// at Object.<anonymous> (/path/to/file.ts:18:33)
// at ...
// at ...
【讨论】:
我注意到这是可行的,但是文档在哪里说需要将错误对象放在第二个参数中? @5413668060 您不应该将错误对象放在第二个参数中。那是给meta data的。如果您将错误对象作为第一个参数传递,那么您必须将errorStackTracerFormat
函数中的info.meta.XXX
引用更改为info.XXX
抱歉,您的示例并没有做到它声称的那样。
是的,info 对象的 console.dir 不显示任何元数据。相反,它显示了一些 splat 符号。内部肯定发生了变化。【参考方案3】:
这是我的logger.js
和winston": "^3.1.0
const createLogger, format, transports = require('winston');
const combine, timestamp, printf, colorize, splat = format;
const myFormat = printf((info) =>
if (info.meta && info.meta instanceof Error)
return `$info.timestamp $info.level $info.message : $info.meta.stack`;
return `$info.timestamp $info.level: $info.message`;
);
const LOG_LEVEL = process.env.LOG_LEVEL || 'debug';
const logger = createLogger(
transports: [
new (transports.Console)(
level: LOG_LEVEL,
format: combine(
colorize(),
timestamp(),
splat(),
myFormat
)
)
]
);
module.exports = logger;
【讨论】:
【参考方案4】:对于winston 版本3.2.0+
,以下将添加堆栈跟踪到日志输出:
import createLogger, format, transports from 'winston';
const combine, timestamp, prettyPrint, colorize, errors, = format;
const logger = createLogger(
format: combine(
errors( stack: true ), // <-- use errors format
colorize(),
timestamp(),
prettyPrint()
),
transports: [new transports.Console()],
);
参考:https://github.com/winstonjs/winston/issues/1338#issuecomment-482784056
【讨论】:
【参考方案5】:这是我的记录器配置。添加了errors( stack: true )
,感谢Murli Prajapati ans 和printf 函数中的小技巧。我的温斯顿版本是3.2.1
。
const format, transports = require('winston');
const timestamp, colorize, printf, errors = format;
const Console, File = transports;
LoggerConfig =
level: process.env.LOGGER_LEVEL || 'debug',
transports: [
new Console(),
new File(filename: 'application.log')
],
format: format.combine(
errors( stack: true ),
timestamp(),
colorize(),
printf(( level, message, timestamp, stack ) =>
if (stack)
// print log trace
return `$timestamp $level: $message - $stack`;
return `$timestamp $level: $message`;
),
),
expressFormat: true, // Use the default Express/morgan request formatting. Enabling this will override any msg if true. Will only output colors with colorize set to true
colorize: false, // Color the text and status code, using the Express/morgan color palette (text: gray, status: default green, 3XX cyan, 4XX yellow, 5XX red).
ignoreRoute: function (req, res)
return false;
// optional: allows to skip some log messages based on request and/or response
我在 express-winston
和一般日志中使用相同的配置。
const winston = require('winston');
const expressWinston = require('express-winston');
/**
* winston.Logger
* logger for specified log message like console.log
*/
global.__logger = winston.createLogger(LoggerConfig);
/**
* logger for every HTTP request comes to app
*/
app.use(expressWinston.logger(LoggerConfig));
【讨论】:
【参考方案6】:这是 Winston 3.2 的另一个版本。
现在 Winston 带有一个内置的堆栈跟踪格式化程序,但如果相同的格式化程序有 winston.format.simple()
组合,它似乎不会触发。因此,您需要使用 winston.format.printf
来代替 Kirai Mali 的回答。我不知道如何在同一配置中同时配置 winston.format.errors()
和 winston.format.simple()
。
基于当前 Winston README 示例和上面的答案,这是我使用 JSON 格式日志文件的配置,但对于本地开发控制台,它仍然提供彩色日志行和良好的堆栈跟踪。
// Use JSON logging for log files
// Here winston.format.errors() just seem to work
// because there is no winston.format.simple()
const jsonLogFileFormat = winston.format.combine(
winston.format.errors( stack: true ),
winston.format.timestamp(),
winston.format.prettyPrint(),
);
// Create file loggers
const logger = winston.createLogger(
level: 'debug',
format: jsonLogFileFormat,
transports: [
//
// - Write to all logs with level `info` and below to `combined.log`
// - Write all logs error (and below) to `error.log`.
//
new winston.transports.File( filename: 'error.log', level: 'error' ),
new winston.transports.File( filename: 'combined.log' )
],
expressFormat: true,
);
// When running locally, write everything to the console
// with proper stacktraces enabled
if (process.env.NODE_ENV !== 'production')
logger.add(new winston.transports.Console(
format: winston.format.combine(
winston.format.errors( stack: true ),
winston.format.colorize(),
winston.format.printf(( level, message, timestamp, stack ) =>
if (stack)
// print log trace
return `$timestamp $level: $message - $stack`;
return `$timestamp $level: $message`;
),
)
));
【讨论】:
请注意:The prettyPrint format should not be used in production because it may impact performance negatively and block the event loop.
github.com/winstonjs/logform#prettyprint以上是关于如何使用 Winston 3 记录完整的堆栈跟踪?的主要内容,如果未能解决你的问题,请参考以下文章