我现在正在开发基于集群的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);}
答案 0 :(得分:4)
它必须存在瓶颈问题,因为主服务器是唯一可以将消息从n个工作者记录到文件的地方。 master和worker之间的通信不是必需的,因为worker可以直接将消息写入文件。只要消息长度小于管道缓冲区,写入操作就是安全的。
你没有处理&#34;排水&#34;事件。当您有大量需要记录的消息时,流缓冲区将很容易填满,因为流没有足够的时间来刷新并将缓冲区写入磁盘。同时,您继续将消息放入缓冲区。最后,您无法将消息完全记录到文件中。 &#34;漏极&#34;刷新缓冲区时将触发事件。有关&#34; drain&#34;的详细信息,请参阅&#34; http://nodejs.org/api/stream.html#stream_event_drain&#34;
P.S。如果你有时间,请试试我的lib。它侧重于多进程日志记录和日志轮换。它在文件记录和内存消耗方面非常快 https://github.com/wood1986/ln