2014-04-28 118 views
2

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

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);} 
+0

我喜欢的日志库是[bunyan](https://www.npmjs.org/package/bunyan)。尽管如此,我还没有使用它。 – clay

回答

3
  1. 因为主是谁可以登录从n个工人的消息到文件的唯一地方。它必须有一个瓶颈问题。主人与工人之间的沟通并非必要,因为工作人员可以直接将信息写入文件。只要消息长度小于管道缓冲区,写操作是安全的。

  2. 您没有处理“排水”事件。当有多个需要记录的消息时,流缓冲区将变得很容易,因为流没有足够的时间来刷新并将缓冲区写入磁盘。同时,你不断地将消息放入缓冲区。最后,您无法将消息完全记录到文件中。当缓冲区被刷新时,“drain”事件将被触发。 “排水”详情请参考“http://nodejs.org/api/stream.html#stream_event_drain

P.S.如果你有时间,请尝试我的lib。它侧重于多进程日志记录和日志轮换。它在文件记录和内存消耗很小的情况下非常快速 https://github.com/wood1986/ln