温斯顿不显示错误详细信息

Bal*_*cze 10 logging node.js express winston

我正在使用winston日志记录,并且在大多数情况下都可以正常运行,但是当出现异常时,它不会打印任何详细信息。

这是我的配置代码winston

// Create logger
const logger = winston.createLogger()

// Create timestamp format
const tsFormat = () => (new Date()).toLocaleTimeString()

// Attach transports based on app mode
if (process.env.APP_MODE === 'production') {
  // Log to file
  logger.add(new (winston.transports.DailyRotateFile)({
    filename: path.join(__dirname, '../logs/errors-%DATE%.log'),
    datePattern: 'YYYY-MM-DD-HH',
    zippedArchive: true,
    format: winston.format.json(),
    handleExceptions: true
  }))
} else {
  // Log to the console
  logger.add(new (winston.transports.Console)({
    timestamp: tsFormat,
    colorize: true,
    handleExceptions: true
  }))
}

module.exports = logger
Run Code Online (Sandbox Code Playgroud)

我也在使用,Express并且在我的错误处理中间件中,我有以下代码:

const logger = require('../config/winston')
function (err, req, res, next) {
    console.log(err)
    logger.error(err)
    res.status(500).send({ error: 'Please try again later.' })
}
Run Code Online (Sandbox Code Playgroud)

问题是,发生错误时,所有winston日志为:

{“级别”:“错误”}

好的旧console.log()显示:

TypeError: Cannot read property 'filename' of undefined
    at router.post (/Users/balazsvincze/Desktop/testapi/app/routes/upload.js:16:33)
    at Layer.handle [as handle_request] (/Users/de/Desktop/testapi/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/balazsvincze/Desktop/testapi/node_modules/express/lib/router/route.js:137:13)
    at Immediate.<anonymous> (/Users/balazsvincze/Desktop/testapi/node_modules/multer/lib/make-middleware.js:53:37)
    at runCallback (timers.js:814:20)
    at tryOnImmediate (timers.js:768:5)
    at processImmediate [as _immediateCallback] (timers.js:745:5)
Run Code Online (Sandbox Code Playgroud)

我如何winston记录这样的内容,包括堆栈跟踪?

非常感谢!

编辑:如果我将logger.error(err)行更改为logger.error(err.message),至少我得到了:

{“消息”:“无法读取未定义的属性'文件名'”,“级别”:“错误”}

与我追求的目标仍然相去甚远。

小智 7

使用格式。

const { combine, timestamp, label, printf } = winston.format;
const myFormat = printf(info => {
    if(info instanceof Error) {
        return `${info.timestamp} [${info.label}] ${info.level}: ${info.message} ${info.stack}`;
    }
    return `${info.timestamp} [${info.label}] ${info.level}: ${info.message}`;
});
winston.createLogger({
    level: "info",
    format: combine(
        winston.format.splat(),
        label({ label: filename}),
        timestamp(),
        myFormat,
    ),
    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: path.join(os.tmpdir(), "test", "test.log"), level: "info" }),
    ],
});
Run Code Online (Sandbox Code Playgroud)


jtp*_*son 6

我想你错过了什么是format.errors({ stack: true })winston.createLogger

const logger = winston.createLogger({
  level: 'debug',
  format: format.combine(
    format.errors({ stack: true }),
    print,
  ),
  transports: [new transports.Console()],
});
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅此 GitHub 线程

发生这种情况的原因是有趣的Error对象属性,如.stack,是不可枚举的。一些函数检查它们的参数是否是Error实例,如console.error,而其他函数忽略所有不可枚举的属性,如winston.<log-level>JSON.stringify

> console.error(new Error('foo'))
Error: foo
    at repl:1:15
    at Script.runInThisContext (vm.js:124:20)
    ...(abbr)

> JSON.stringify(new Error('foo'))
'{}'
Run Code Online (Sandbox Code Playgroud)

所有这一切说,这是可怕的可用性有一个错误记录仪基本上忽略错误......我只是失去了太多的时间来此。

  • 我们使用像 Winston 这样的记录器的主要原因是什么?查看错误,尽可能详细。遗憾的是它不能像“console.log”一样默认打印错误对象的完整详细信息。 (6认同)

rob*_*lep 5

一种快速而肮脏的方法是记录err.stack

logger.error(err.stack);
Run Code Online (Sandbox Code Playgroud)

一种更精细的方法是专门为实例实现自定义格式Error。在这个 Github issue 中有一些关于如何实现它的示例代码。