将process.stdout设置为每个node.js核心集群工作者的文件

我正在尝试使用节点核心的集群function。

我想stdoutstderrstream输出到一个文件,每个工人ID一个。

非常像以下内容:

 var fs = require('fs'), env = process.env, workerId = env.NODE_WORKER_ID || env.NODE_UNIQUE_ID; process.stdout = fs.createWriteStream(__dirname + '/app#' + workerId + '.log', { encoding: 'utf8' }); 

不幸的是,似乎没有像这样重写process.stdout。

有没有办法做到这一点,还是应该这样做是不同的? 目前,当我运行我的集群时,我在一个控制台中获取所有进程的所有输出,这非常混乱。

我结束了以下工作:

  //create a new stdout file stream var stdoutFS = fs.createWriteStream(stdoutFile, { encoding: 'utf8', flags : 'a+' }); //create a new stderr file stream var stderrFS = fs.createWriteStream(stderrFile, { encoding: 'utf8', flags : 'a+' }); //pipe stdout to a worker file var unhookStdout = hookWriteStream(stdout, function(string, encoding, fd) { stdoutFS.write(string, encoding || 'utf8'); }); console.log('\n\nPrepared new stdout hook to worker file.'); //pipe stderr to a worker file var unhookStderr = hookWriteStream(stderr, function(string, encoding, fd) { stderrFS.write(string, encoding || 'utf8'); }); console.log('Prepared new stderr hook to worker file.'); //unhook when things go wrong stdoutFS.once('close', function() { unhookStdout(); console.log('Unhooked stdout.'); }); stdoutFS.once('error', function(err) { unhookStdout(); console.error('Error: Unhooked stdout due to error %j.', err); }); stderrFS.once('close', function() { unhookStderr(); console.log('Unhooked stderr.'); }); stderrFS.once('error', function(err) { unhookStderr(); console.error('Error: Unhooked stderr due to error %j.', err); }); }); function hookWriteStream(stream, callback) { var oldWrite = stream.write; stream.write = (function(write) { return function(string, encoding, fd) { write.apply(stream, arguments); callback(string, encoding, fd); }; })(stream.write); return function() { stream.write = oldWrite; }; } 

这可能不是很优雅,但到目前为止,这是我find的最好的解决scheme。

看起来我的想法在一定程度上起作用。 只要大多数日志logging是使用console.log完成的,而不是直接写入到stdout,那么你会很好。

就像我在下面的评论中所说的,使用这样的脚本:

 fs = require 'fs' {exec} = require 'child_process' execAndPipe = (execString) -> piper = exec execString piper.stdout.on 'data', (data) -> if data[0...'PROCESS'.length] == 'PROCESS' # extract the worker ID and output # to a corresponding file piper.stderr.on 'data', (data) -> if data[0...'PROCESS'.length] == 'PROCESS' # extract the worker ID and output # to a corresponding file task 'run', 'Run the server', -> execAndPipe 'node blah.js' 

运行你的服务器。 然后重新定义console.log,如:

 console.log = function (d) { process.stdout.write('PROCESS' + WORKERID + d + '\n'); }; 

我有点怀疑你可以直接重新绑定stdout,所以这可能是你最好的select之一。

如果你不想要任何东西输出到所有的控制台,你可以重新绑定console.log如:

 console.log = function (d) { var str = fs.createWriteStream(__dirname + '/app#' + workerId + '.log', { encoding: 'utf8' }); process.stdout.pipe(str); }; 

忘记外部脚本。