如何刷新winston日志?
Posted
技术标签:
【中文标题】如何刷新winston日志?【英文标题】:How to flush winston logs? 【发布时间】:2013-09-17 06:41:54 【问题描述】:我想在 之前 process.exit
刷新winston 记录器。
process.on('uncaughtException', function(err)
logger.error('Fatal uncaught exception crashed cluster', err);
logger.flush(function() // <-
process.exit(1);
);
);
有类似logger.flush
的东西吗?除了有人抱怨 winston 没有得到非常积极的维护之外,我找不到任何关于它的信息。
作为替代方案,是否有任何流行的(积极维护的)多传输日志框架提供刷新功能?
【问题讨论】:
Winston 也有这个问题 - 出现致命异常时文件记录器不会刷新到磁盘。 其他人已经为您的问题提供了解决方案。但您的实际问题的答案似乎是否定的:没有办法刷新 winston 记录器。 【参考方案1】:Winston 实际上允许您传入一个回调,该回调会在所有传输都被记录后执行:
process.on('uncaughtException', function(err)
logger.log('error', 'Fatal uncaught exception crashed cluster', err, function(err, level, msg, meta)
process.exit(1);
);
);
文档:https://github.com/flatiron/winston#events-and-callbacks-in-winston
【讨论】:
正确,这让我等待'fatal exception'
消息,如果我想刷新所有这些怎么办?也许正在记录其他一些消息,并且它使用的传输需要更长的时间才能完成。
没有什么是不刷新的。默认的 winston FileTransport 仅在第一次尝试打开底层文件时缓冲日志。 github.com/flatiron/winston/blob/master/lib/winston/transports/… 否则,如果数据没有立即写入底层文件描述符,我们将等待“drain”事件:github.com/flatiron/winston/blob/master/lib/winston/transports/…
@indexzero 说我记录了一个错误,该错误通过 HTTP 传输或存储在数据库中,然后我记录了一条调试消息,该消息只发送到控制台,然后等待该消息,然后出口。错误消息是否总是被记录?
@indexzero 如果我设置了控制台记录器和文件记录器,记录一些文本,然后使用 ctrl+c 退出,控制台记录器会显示所有记录的文本,而文件记录器只会显示其中的一部分。
真的不清楚 FileTransport 是否缓冲它的写入,遵循这条评论线索。缓冲是否只委托给文件系统?【参考方案2】:
Winston 有更好的方法来处理这种异常。
var logger = new (winston.Logger)(
transports: [
new winston.transports.File( filename: 'path/to/all-logs.log' )
],
handleExceptions: true,
exceptionHandlers: [
new winston.transports.File( filename: 'path/to/exceptions.log' )
]
);
【讨论】:
你还没有解释这是如何回答这个问题的。【参考方案3】:像 Thomas Heymann 建议的那样在日志回调中调用 process.exit
并不能确保日志确实被刷新,尤其是在使用 File
-transport 时。
我会让记录器在刷新日志后调用process.exit
,而不是直接调用 process.exit:
logger.js:
var winston = require('winston');
winston.loggers.add('my-logger',
console:
level: 'debug',
colorize: true,
timestamp: true,
handleExceptions: true
,
file:
level: 'info',
colorize: false,
timestamp: true,
filename: file,
handleExceptions: true
);
var logger = winston.loggers.get('my-logger');
/* ******* *
* EXPORTS
* ******* */
exports.exitAfterFlush = function(code)
logger.transports.file.on('flush', function()
process.exit(code);
);
;
exports.info = function()
logger.info.apply(this, arguments);
;
exports.warn = function()
logger.info.apply(this, arguments);
;
exports.error = function()
logger.info.apply(this, arguments);
;
在你的代码中:
var logger = require('./logger.js');
logger.exitAfterFlush(0);
info('Done!');
在 NodeJS v4.1.2 和 winston 1.1.0 上测试
【讨论】:
我认为这已经停止在 NodeJS 10.x 和 winston 3.2.1 上运行【参考方案4】:不幸的是,Winston 有时会在传输有机会刷新之前调用日志记录回调,因此接受的答案仍然可能导致未保存的日志消息(尤其是在事件循环的第一轮)。在winston-log-and-exit 包/补丁中实现了更好的解决方案。
【讨论】:
【参考方案5】:这可能对某人有所帮助。 logger 是 winston.createLogger 的一个实例,它定义了两个传输(控制台和文件)。退出代码反映在 shell 中。
const logger = require('../library/log');
function exitAfterFlush()
logger.on('finish', function ()
logger.end();
);
;
process.on('exit', (code) =>
console.log(`About to exit with code: $code`);
);
logger.info(`Started with PID:$process.pid`);
logger.error(`*****`);
process.exitCode = 11;
exitAfterFlush();
【讨论】:
以上是关于如何刷新winston日志?的主要内容,如果未能解决你的问题,请参考以下文章
如何将 Winston 限制为每个日志文件只有 1 个文件描述符