在使用process.exit() – 节点js时,Winston日志文件并不总是保存

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

在下面的代码中,winstonlogging器是创build。 然后在numberScore函数中,为数组中的每个数字创build一个日志,最后我并行logging所有事件 – 只是一个演示!

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() 

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

 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 

只要注释掉process.exit() ,日志文件就可以正确保存所有需要的数据。 然而….在我的情况下,我需要有process.exit() – 所以什么是解决方法?

我曾尝试过:

  1. 使用Winstoncallback – https://github.com/winstonjs/winston#events-and-callbacks-in-winston – 失败

  2. 添加setTimeout – 失败(process.exit似乎没有等待setTimeout – 它退出程序反正)

  3. 正如你在上面的例子中看到的那样,使用async.parallel却依然没有运气

任何其他解决scheme呢?

同样的问题是在github上打开 – https://github.com/winstonjs/winston/issues/228 – 但是没有find完整的解决scheme。

从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); } }); 

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

请注意,我实际上正在监听结束事件: https : //nodejs.org/api/stream.html#stream_event_finish,而不是使用Winston的刷新或closures事件,因为这也不足以让它logging正确:/

尝试这样的事情,它为我工作(基于温斯顿):

 logger.on('logging', function (transport, level, msg, meta) { if (msg == "equal your message" && transport.name == "file") { var id = setInterval(function () { //when it is done to write the file, it will enter the id condition if (transport._stream._writableState.bufferedRequestCount==0) { exitProcess(0); } },1000) } });