node.js多进程日志logging

我现在正在基于群集的node.js项目。 我被卡住了日志。 经过一番研究,我找出了一个解决scheme。 就这个。 我不知道这是不是一个好主意。 这个想法是这样的。 只有主进程可以写入日志文件,如果当前进程是一个工作者,那么它会向主进程发送日志消息,然后写入日志文件,而主进程可以直接写入日志文件。 这可以避免多个进程打开并写入同一个文件。

var util = require('util'); var fs = require('fs'); var cluster = require('cluster'); var logger = module.exports; var levels = ['debug', 'info', 'warn', 'error', 'fatal']; var logLevel = 'debug'; var logfile = null; var errorLogfile = null; if(cluster.isMaster){ logfile = fs.createWriteStream('debug.log', {flags:'a'}); errorLogfile = fs.createWriteStream('error.log', {flags:'a'}); cluster.on('online', function(worker){ //collect log message from child and write to logfile. worker.on('message', function(msg){ if(msg.type == 'logging') { var level = msg.data.level; var logStr = msg.data.msg; if(levels.indexOf(level) >= levels.indexOf('error')){ errorLogfile.write(logStr + '\n'); }else{ logfile.write(logStr + '\n'); } } }); }); } function log(level, args){ if(levels.indexOf(level) < levels.indexOf(logLevel)) return; var args = Array.prototype.slice.call(args); args = args.map(function(a){ if(typeof a !== 'string') return JSON.stringify(a); else return a; }); var msg = util.format.apply(null, args); var out = []; out.push(new Date()); out.push('[' + level.toUpperCase() + ']'); out.push(msg); if(cluster.isMaster){ //write directly to the log file if(levels.indexOf(level) >= levels.indexOf('error')){ errorLogfile.write(out.join(' ') + '\n'); }else{ logfile.write(out.join(' ') + '\n'); } }else{ //send to master cluster.worker.process.send({ type : 'logging', data : { level : level, msg : out.join(' ') } }); } } logger.debug = function(){log('debug', arguments);} logger.info = function(){log('info', arguments);} logger.warn = function(){log('warn', arguments);} logger.error = function(){log('error', arguments);} logger.fatal = function(){log('fatal', arguments);} 

  1. 它必须有一个瓶颈问题,因为主人是唯一可以将来自n个工作人员的消息logging到文件的地方。 主人和工人之间的沟通是不必要的,因为工作人员可以直接将信息写入文件。 只要消息长度小于pipe道缓冲区,写操作是安全的。

  2. 你没有处理“stream失”事件。 当有多个需要logging的消息时,stream缓冲区将变得很容易,因为stream没有足够的时间来刷新并将缓冲区写入磁盘。 同时,你不断地把消息放到缓冲区。 最后,你不能完全logging到文件的消息。 当缓冲区被刷新时,“drain”事件将被触发。 有关“stream失”的详细信息,请参阅“ http://nodejs.org/api/stream.html#stream_event_drain

PS如果你有时间,请尝试我的lib。 它着重于多进程logging和日志循环。 而且在文件logging方面非常快,而且内存消耗小https://github.com/wood1986/ln