将标准输出重定向到文件 nodejs
Redirecting stdout to file nodejs
我创建了:
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');
有人可以解释我做错了什么吗?
process.stdout
是可写的。 pipe
是 Readable
的一种方法(参见 StreamAPI 文档:https://nodejs.org/api/stream.html
您可以在此处查看 process.stdout
的文档:https://nodejs.org/api/process.html#process_process_stdout
令人惊讶的是,您可以毫无错误地执行 process.stdout.pipe(...);
。但我想这个电话什么都不做。除了返回绑定到 stdout 的新可写流(或者可能是 returns process.stdout
本身。文档中没有相关说明)。
如果你想将 stdout 重定向到一个文件,你有很多解决方案:
- 只需使用您的命令行即可。 Windows 风格:
node myfile.js > api.access.log
.
- 用您自己的对象替换控制台对象。你可以重写控制台方法。
- 我不确定,但可以用你自己的流替换
process.stdout
(你可以用它做任何你想做的事)
我通过以下方式解决了这个问题:
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);
});
这将涵盖以下情况:
- process.stdout.write
- process.stderr.write
- console.log
- console.dir
- console.error
- someStream.pipe(process.stdout);
- 抛出新错误('Crash');
- 扔 'never do this';
- 抛出未定义;
结帐 console.Console
,正常 console
的父 class。
var myLogFileStream = fs.createWriteStream(pathToMyLogFile);
var myConsole = new console.Console(myLogFileStream, myLogFileStream);
然后您可以使用 myConsole.log
、myConsole.error
、myConsole.dir
等直接写入您的文件。
您也可以monkey patchprocess.stdout.write
如下:
var fn = process.stdout.write;
function write() {
fn.apply(process.stdout, arguments);
myLogFileStream.write.apply(myLogFileStream, arguments);
}
process.stdout.write = write;
根据将 stdout
记录到文件的动机,还有其他选项可以覆盖 console._stdout
。
@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()
return 具有正常功能并且当 fs.Writestream.end
被调用时 writestream 关闭。开发人员将如何着手这样做我做到了
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()
它有效,你使用 once 方法,因为 process.stdout
似乎做了很多工作
此时。
这是好习惯吗,在这种情况下你会这样做吗?
任何人都可以随时回复。
最初基于@Anatol-user3173842 的回答
但在我的例子中,我需要挂钩 stdout & stderr 并写入文件。
所以对于那些除了写入文件之外还需要保持正常标准输出行为的人。使用以下内容。
对于非错误:
// 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;
}
}
我创建了:
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');
有人可以解释我做错了什么吗?
process.stdout
是可写的。 pipe
是 Readable
的一种方法(参见 StreamAPI 文档:https://nodejs.org/api/stream.html
您可以在此处查看 process.stdout
的文档:https://nodejs.org/api/process.html#process_process_stdout
令人惊讶的是,您可以毫无错误地执行 process.stdout.pipe(...);
。但我想这个电话什么都不做。除了返回绑定到 stdout 的新可写流(或者可能是 returns process.stdout
本身。文档中没有相关说明)。
如果你想将 stdout 重定向到一个文件,你有很多解决方案:
- 只需使用您的命令行即可。 Windows 风格:
node myfile.js > api.access.log
. - 用您自己的对象替换控制台对象。你可以重写控制台方法。
- 我不确定,但可以用你自己的流替换
process.stdout
(你可以用它做任何你想做的事)
我通过以下方式解决了这个问题:
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);
});
这将涵盖以下情况:
- process.stdout.write
- process.stderr.write
- console.log
- console.dir
- console.error
- someStream.pipe(process.stdout);
- 抛出新错误('Crash');
- 扔 'never do this';
- 抛出未定义;
结帐 console.Console
,正常 console
的父 class。
var myLogFileStream = fs.createWriteStream(pathToMyLogFile);
var myConsole = new console.Console(myLogFileStream, myLogFileStream);
然后您可以使用 myConsole.log
、myConsole.error
、myConsole.dir
等直接写入您的文件。
您也可以monkey patchprocess.stdout.write
如下:
var fn = process.stdout.write;
function write() {
fn.apply(process.stdout, arguments);
myLogFileStream.write.apply(myLogFileStream, arguments);
}
process.stdout.write = write;
根据将 stdout
记录到文件的动机,还有其他选项可以覆盖 console._stdout
。
@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()
return 具有正常功能并且当 fs.Writestream.end
被调用时 writestream 关闭。开发人员将如何着手这样做我做到了
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()
它有效,你使用 once 方法,因为 process.stdout
似乎做了很多工作
此时。
这是好习惯吗,在这种情况下你会这样做吗?
任何人都可以随时回复。
最初基于@Anatol-user3173842 的回答
但在我的例子中,我需要挂钩 stdout & stderr 并写入文件。
所以对于那些除了写入文件之外还需要保持正常标准输出行为的人。使用以下内容。
对于非错误:
// 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;
}
}