2014-04-28 52 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