使用 process.exit() 时并不总是保存 Winston 日志文件 - Node js

5 javascript asynchronous process node.js winston

我无法理解这个概念...在将日志文件保存到控制台和实际文件的程序上使用 process.exit() 时,日志事件全部打印在控制台中,但仅打印第一个(或者在所有)都保存到文件中。这是该问题的快速演示:

在下面的代码中,创建了一个 Winston 记录器。然后在 numberScore 函数中,我为数组中的每个数字创建一个日志,最后我并行记录所有事件 - 只是一个演示!

var async = require('async')
var winston = require('winston')
var moment = require('moment')

var logger = new (winston.Logger)({
  transports: [
    new (winston.transports.Console)({
      timestamp: function () {
        return moment().format('D/MM/YYYY HH:mm:ss:SSS')
      },
      colorize: true
    }),
    new (require('winston-daily-rotate-file'))({
      filename: 'logs/-system.log',
      datePattern: 'dd-MM-yyyy',
      prepend: true,
      json: false,
      timestamp: function () {
        return moment().format('D/MM/YYYY HH:mm:ss:SSS')
      }
    })
  ]
})


var values = [1,2,3,4,5]

var numbersScore = function(done) {
var array = []
    array.push(function(callback) {
        logger.info('test1')
        callback()
      })

values.forEach(function(number){
    number += 1 
    console.log(number)


    array.push(function(callback) {
        logger.info('test2', number)
        callback()
      })
})

async.parallel(array, function(error, data){
    console.log('done')
    process.exit()
})
}
numbersScore()
Run Code Online (Sandbox Code Playgroud)

上面的代码运行时会在控制台中打印出来 - 这意味着一切都很好 - 但是在日志文件中没有保存任何内容。

2
3
4
5
6
28/09/2016 10:57:45:911 - info: test1
28/09/2016 11:01:22:677 - info: Numbers are 2
28/09/2016 11:01:22:678 - info: Numbers are 3
28/09/2016 11:01:22:678 - info: Numbers are 4
28/09/2016 11:01:22:678 - info: Numbers are 5
28/09/2016 11:01:22:678 - info: Numbers are 6
done
Run Code Online (Sandbox Code Playgroud)

一旦注释掉,process.exit()日志文件就会正确保存所有必需的数据。但是......在我的场景中,我需要 process.exit() - 那么解决方法是什么?

我尝试过的:

  1. 使用 Winston 回调 - https://github.com/winstonjs/winston#events-and-callbacks-in-winston - 失败

  2. 添加 setTimeout - 失败(process.exit 似乎没有等待 setTimeout - 它无论如何都会退出程序)

  3. 正如您在上面的示例中看到的,使用 async.parallel 但仍然没有运气

对此还有其他解决方案吗?

同样的问题在 github 上公开 - https://github.com/winstonjs/winston/issues/228 - 但尚未确定完全有效的解决方案。

Dra*_*SAN 0

来自github 问题

注意:这是该问题相关部分的复制粘贴,由用户 Kegsay 编写。

对于它的价值,您可以绕过使用,setTimeout但您需要抓住底层_stream

// log then exit(1)
logger.error("The thing to log", function(err) {
  var numFlushes = 0;
  var numFlushed = 0;
  Object.keys(logger.transports).forEach(function(k) {
    if (logger.transports[k]._stream) {
      numFlushes += 1;
      logger.transports[k]._stream.once("finish", function() {
        numFlushed += 1;
        if (numFlushes === numFlushed) {
          process.exit(1);
        }
      });
      logger.transports[k]._stream.end();
    }
  });
  if (numFlushes === 0) {
    process.exit(1);
  }
});
Run Code Online (Sandbox Code Playgroud)

如上所述,单独使用回调函数不足以使其正确刷新到文件。这对我来说就像一个错误。

请注意,我实际上正在侦听完成事件: https: //nodejs.org/api/stream.html#stream_event_finish,而不是使用温斯顿的刷新或关闭事件,因为这也不足以使其正确记录:/