2014-04-28 7 views
2

이제 cluster를 기반으로하는 node.js 프로젝트에서 작업하고 있습니다. 벌목에 막혔어요. 몇 가지 조사를 한 후에 해결책을 찾았습니다. 여기 있습니다. 나는 그것이 좋은 생각인지 모른다. 아이디어는 이것과 같습니다. 현재 프로세스가 작업자 인 경우 마스터 프로세스 만 로그 파일에 기록 할 수 있으며 로그 파일을 마스터로 보내고 로그 파일에 기록한 후 마스터가 직접 로그 파일에 기록 할 수 있습니다. 이렇게하면 여러 프로세스가 열리지 않고 동일한 파일에 쓸 수 있습니다. 마스터 파일을 n 근로자의 메시지를 기록 할 수있는 유일한 장소이기 때문에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. 는 그것은 병목 문제를 가지고 있어야합니다. 작업자는 파일에 메시지를 직접 쓸 수 있으므로 마스터와 작업자 간의 통신은 필요하지 않습니다. 메시지 길이가 파이프 버퍼보다 ​​작은 한 쓰기 조작은 안전합니다.

  2. "드레인"이벤트를 처리하지 않았습니다. 스트림에 버퍼를 플러시하고 디스크에 쓸 시간이 충분하지 않기 때문에 많은 양의 메시지를 기록해야 할 때 스트림 버퍼가 가득 채워집니다. 한편, 버퍼에 메시지를 보관합니다. 마지막으로 메시지를 파일에 완전히 기록 할 수는 없습니다. "drain"이벤트는 버퍼가 플러시 될 때 트리거됩니다. "드레인"에 대한 자세한 내용은 "http://nodejs.org/api/stream.html#stream_event_drain"

P.S.를 참조하십시오. 시간이 있다면, 제 lib를 사용해보십시오. 다중 프로세스 로깅 및 로그 로테이션에 중점을 둡니다. 파일 로깅 및 메모리 소비량이 매우 빠릅니다. https://github.com/wood1986/ln