【问题标题】:Node logging uncaught exception (Winston V3)节点记录未捕获的异常 (Winston V3)
【发布时间】:2019-04-28 15:25:06
【问题描述】:

我是 Winston 的新手,我正在尝试使用它来记录未捕获的异常,然后退出。它正在登录到控制台,但似乎没有时间在退出之前登录到文件

这是一个例子:

index.js

const express = require('express');
const app = express();
const logger = require('./startup/logging');

process.on('uncaughtException', (ex) => {
    logger.error("Won't be logged in the File");
    process.exit(1);
});

throw new Error("Uncaught");

logging.js

const { createLogger, format, transports } = require('winston');

const logger = createLogger({     
    format: format.combine(
        format.timestamp({
            format: 'YYYY-MM-DD hh:mm:ss |'
        }),
        format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)
    ),
    transports: [
        new transports.Console({
            format: format.combine(
                format.colorize({
                    // all: true
                }),
                // this is repeated because for some reason colorize() won't work otherwise
                format.printf(info => `${info.timestamp} ${info.level}: ${info.message}`)            
            )
        }),
        new transports.File({ filename: './exceptions.log' })
    ]
});

module.exports = logger;

如前所述,未捕获的异常会记录到控制台,但不会记录到文件中。删除process.exit(1) 解决了日志记录问题,但我确实希望程序退出。

将handleExceptions: true 添加到文件传输会导致相同的问题 - 它会在记录异常之前退出。我假设这是原因,添加 exitOnError: false 然后记录异常。

这是预期的行为吗?我觉得这很奇怪,即使是初学者。

编辑:

process.on('uncaughtException', (ex) => {
    logger.log('error', 'Will be logged');
    setTimeout(function(){process.exit(1)}, 1000);
});

这可行,但肯定不是修复,只是显示我遇到的问题

【问题讨论】:

  • 为process.exit(1) 设置一秒的超时时间可以解决问题 - 但肯定不理想

标签: javascript node.js logging winston


【解决方案1】:

logging.error 可能是一个 IO(异步)操作并在调用后产生:

process.on('uncaughtException', (ex) => {
    logger.error("Won't be logged in the File"); # registers operation with node event loop and continues
    process.exit(1);
});

node documentation shows 是同步写入,但我不确定如何将其插入到 winston:

process.on('uncaughtException', (err) => {
  fs.writeSync(1, `Caught exception: ${err}\n`);
  process.exit(1)
});

【讨论】:

  • 不幸的是,我也不是。超过我的知识水平。
【解决方案2】:

你用的是什么版本?在 v2 中,您可以使用在写入日志条目后执行的 callback。

process.on('uncaughtException', (ex) => {
    logger.error("Will be logged in the File", function() {
        process.exit(1);
    });
});

在 v3 中,您是 supposed to do:

logger.log('info', 'some message');
logger.on('finish', () => process.exit());
logger.end();

【讨论】:

  • 这太奇怪了。除非您调用“logger.end()”,否则回调似乎不起作用,但代码只有 once 才能工作。
  • 哪个回调? onFinish?这是有道理的,不是吗?您只需要调用一次,这样您就不会退出进程,直到日志被刷新。
  • 不,我的意思是它似乎只在第一次添加对 end() 的调用时才起作用,如果有的话。我认为那是巧合。重新启动服务器并遇到另一个异常不会记录任何内容。看了下面的链接后,我不认为这是解决问题的方法,但我想我可能实施错了
【解决方案3】:

对 2013 年至今的问题进行了很好的阅读。

https://github.com/winstonjs/winston/issues/228

提到了各种变通方法,但似乎永远不会解决这个问题。这很烦人。改为查看 log4js-node,它显然已经解决了这个问题。

【讨论】:

    猜你喜欢
    • 2010-11-08
    • 2011-10-02
    • 2021-10-05
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    • 2015-03-01
    • 2013-05-02
    • 2014-05-31
    相关资源
    最近更新 更多