Перенаправление stdout в файл 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');
Может кто-нибудь объяснить, что я делаю неправильно?
Ответы
Ответ 1
Я решил эту проблему следующим образом:
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');
- throw "никогда не делайте этого";
- throw undefined;
Ответ 2
Оформить заказ console.Console
, родительский класс нормального console
.
var myLogFileStream = fs.createWriteStream(pathToMyLogFile);
var myConsole = new console.Console(myLogFileStream, myLogFileStream);
Затем вы можете использовать myConsole.log
, myConsole.error
, myConsole.dir
и т.д. и записывать непосредственно в свой файл.
Вы также можете патч обезьяны 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
в файл.
Ответ 3
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(...);
без ошибок. Но я полагаю, что этот призыв просто ничего не делает. За исключением возврата нового потока Writable, связанного с stdout (или, возможно, он возвращает process.stdout
сам. В документации нет спецификации).
Если вы хотите перенаправить stdout в файл, у вас есть много решений:
- Просто используйте свою командную строку для этого. Стиль Windows:
node myfile.js > api.access.log
.
- Заменить объект консоли вашим собственным объектом. И вы можете переписать консольные методы.
- Я не уверен, но может быть возможно заменить
process.stdout
на собственный поток (и вы можете делать все, что хотите, с этим)
Ответ 4
@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
потому что process.stdout
кажется, делает много работы в это время. Является ли это хорошей практикой, сделаете ли вы это или что бы вы сделали в этой ситуации, любой может ответить.