我创建了:
var access = fs.createWriteStream('/var/log/node/api.access.log', { flags: 'w' });
然后用管道输送:
process.stdout.pipe(access);
然后尝试了:
console.log("test");
在/var/log/node/api.access.log中没有出现任何内容。但是这种方式有效:
process.stdout.pipe(access).write('test');
有人可以解释我做错了什么吗?
答案 0 :(得分:23)
我通过以下方式解决了这个问题:
var access = fs.createWriteStream('/var/log/node/api.access.log');
process.stdout.write = process.stderr.write = access.write.bind(access);
当然,如果你愿意,你也可以分开stdout和stderr。
我也强烈建议处理未捕获的例外:
process.on('uncaughtException', function(err) {
console.error((err && err.stack) ? err.stack : err);
});
这将涵盖以下情况:
答案 1 :(得分:3)
结帐console.Console
,正常console
的父类。
var myLogFileStream = fs.createWriteStream(pathToMyLogFile);
var myConsole = new console.Console(myLogFileStream, myLogFileStream);
然后,您可以使用myConsole.log
,myConsole.error
,myConsole.dir
等,直接写入您的文件。
您还可以monkey patch process.stdout.write
完成以下操作:
var fn = process.stdout.write;
function write() {
fn.apply(process.stdout, arguments);
myLogFileStream.write.apply(myLogFileStream, arguments);
}
process.stdout.write = write;
还有其他选项可以覆盖console._stdout
,具体取决于将stdout
记录到文件的动机。
答案 2 :(得分:2)
process.stdout
是可写的。 pipe
是Readable
的一种方法(Cf StreamAPI文档:https://nodejs.org/api/stream.html
您可以在此处查看process.stdout
的文档:https://nodejs.org/api/process.html#process_process_stdout
令人惊讶的是,你可以process.stdout.pipe(...);
没有任何错误。但我想这个电话什么都不做。除了返回绑定到stdout的新Writable流(或者它本身返回process.stdout
。文档中没有规范)。
如果要将stdout重定向到文件,则有许多解决方案:
node myfile.js > api.access.log
。process.stdout
(你可以随心所欲地做任何事情)答案 3 :(得分:0)
@ user3173842 为答复 我通过以下方式解决了这个问题:
var access = fs.createWriteStream('/var/log/node/api.access.log');
process.stdout.write = process.stderr.write = access.write.bind(access);
您确实知道process.stdout
在process.on('exit')
之后继续,因此fs.WriteStream
在process.stdout
之后关闭,根据
https://github.com/nodejs/node/issues/7606
因此,现在的问题仍然存在,即开发人员是否希望使fs.Writestream.write()
恢复其正常功能,以及何时调用fs.Writestream.end
时,写流将关闭。开发人员将如何做我做过的事
a_l = asyncify_listener
p_std_stream_m is a process stream manager object
p_std_stream_m.std_info.p_stdout_write = process.stdout.write
process.stdout.write = w_stream.write.bind(w_stream)
process.once('beforeExit', a_l( p_std_stream_m.handler,process.stdout,w_stream ) )
where in the 'beforeExit' event listener I did
process.stdout.write = p_std_stream_m.std_info.p_stdout_write
w_stream.end()
它可以工作,并且您可以使用一次方法,因为process.stdout
似乎可以完成很多工作
此时。
这是好习惯吗,您会这样做还是在这种情况下会做什么?
任何人都可以随时回复。
答案 4 :(得分:0)
最初基于@ Anatol-user3173842答案
但是在我的情况下,我需要钩住stdout和stderr并还要写入文件中。
因此,对于那些除了写入文件外还需要保持正常stdout行为的人。使用以下内容。
对于非错误:
// stdout logging hook
const stdoutWrite0 = process.stdout.write;
process.stdout.write = (args) => { // On stdout write
CustomLogger.writeToLogFile('log', args); // Write to local log file
args = Array.isArray(args) ? args : [args]; // Pass only as array to prevent internal TypeError for arguments
return stdoutWrite0.apply(process.stdout, args);
};
对于错误:
// stderr logging hook
const stderrWrite0 = process.stderr.write;
process.stderr.write = (args) => { // On stderr write
CustomLogger.writeToLogFile('error', args); // Write to local error file
args = Array.isArray(args) ? args : [args]; // Pass only as array to prevent internal TypeError for arguments
return stderrWrite0.apply(process.stderr, args);
};
// uncaught exceptions
process.on('uncaughtException', (err) => {
CustomLogger.writeToLogFile('error', ((err && err.stack) ? err.stack : err));
});
这是CustomLogger
代码,在这里我还按日期分隔了日志文件:
export class CustomLogger {
static LOGS_DIR = 'location-of-my-log-files';
private static logDailyName(prefix: string): string {
const date = new Date().toLocaleDateString().replace(/\//g, '_');
return `${CustomLogger.LOGS_DIR}/${prefix}_${date}.log`;
}
private static writeToLogFile(prefix, originalMsg) {
const timestamp = Date.now();
const fileName = this.logDailyName(prefix);
const logMsg = prepareForLogFile(originalMsg);
fs.appendFileSync(fileName, `${timestamp}\t${logMsg}\n\n`);
return originalMsg;
}
}