node.js多进程日志记录

时间:2014-04-28 11:19:48

标签: node.js logging cluster-computing

我现在正在开发基于集群的node.js项目。我被困在伐木上了。在做了一些研究之后,我找到了一个解决方案。就这个。我不知道这是不是一个好主意。这个想法是这样的。只有主进程才能访问日志文件,如果当前进程是一个worker,那么它会向master发送一条日志消息,然后写入日志文件,而master可以直接写入日志文件。这可以避免多个进程打开并写入同一个文件。

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 个答案:

答案 0 :(得分:4)

  1. 它必须存在瓶颈问题,因为主服务器是唯一可以将消息从n个工作者记录到文件的地方。 master和worker之间的通信不是必需的,因为worker可以直接将消息写入文件。只要消息长度小于管道缓冲区,写入操作就是安全的。

  2. 你没有处理&#34;排水&#34;事件。当您有大量需要记录的消息时,流缓冲区将很容易填满,因为流没有足够的时间来刷新并将缓冲区写入磁盘。同时,您继续将消息放入缓冲区。最后,您无法将消息完全记录到文件中。 &#34;漏极&#34;刷新缓冲区时将触发事件。有关&#34; drain&#34;的详细信息,请参阅&#34; http://nodejs.org/api/stream.html#stream_event_drain&#34;

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