将process.stdout设置为每个node.js核心集群工作者的文件
我正在尝试使用节点核心的集群function。
我想stdout
和stderr
stream输出到一个文件,每个工人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); };
忘记外部脚本。