Home » Nodejs » Redirecting stdout to file nodejs

Redirecting stdout to file nodejs

Posted by: admin December 21, 2017 Leave a comment

Questions:

I had created:

var access = fs.createWriteStream('/var/log/node/api.access.log', { flags: 'w' });

Then piped:

process.stdout.pipe(access);

Then tried:

console.log("test");

And nothing appeared in /var/log/node/api.access.log. However this way is working:

process.stdout.pipe(access).write('test');

Could someone explain what am I doing wrong ?

Answers:

I solved this problem the following way:

var access = fs.createWriteStream('/var/log/node/api.access.log');
process.stdout.write = process.stderr.write = access.write.bind(access);

Of course you can also separate stdout and stderr if you want.

I also would strongly recommend to handle uncaught exceptions:

process.on('uncaughtException', function(err) {
  console.error((err && err.stack) ? err.stack : err);
});

This will cover the following situations:

  • process.stdout.write
  • process.stderr.write
  • console.log
  • console.dir
  • console.error
  • someStream.pipe(process.stdout);
  • throw new Error(‘Crash’);
  • throw ‘never do this’;
  • throw undefined;
Questions:
Answers:

process.stdout is a Writable. pipe is a method of Readable(Cf StreamAPI documentation : https://nodejs.org/api/stream.html

You can see the documentation of process.stdout here : https://nodejs.org/api/process.html#process_process_stdout

It’s surprising that you can do process.stdout.pipe(...); without any error. But i suppose this call just do nothing. Except returning a new Writable stream binded to stdout (or maybe it returns process.stdout itself. There’s no specification for that in the documentation).

If you want to redirect stdout to a file, you have many solutions :

  • Just use your command line to do that. Windows style : node myfile.js > api.access.log.
  • Replace the console object by your own object. And you can rewrite console methods.
  • I’m not sure, but it may be possible to replace process.stdout with your own stream (and you can do whatever you want with this)
Questions:
Answers:

Checkout console.Console, the parent class of the normal console.

var myLogFileStream = fs.createWriteStream(pathToMyLogFile);

var myConsole = new console.Console(myLogFileStream, myLogFileStream);

You can then you use myConsole.log, myConsole.error, myConsole.dir, etc. and write directly to your file.

You can also monkey patch process.stdout.write as follows:

var fn = process.stdout.write;

function write() {
  fn.apply(process.stdout, arguments);
  myLogFileStream.write.apply(myLogFileStream, arguments);
}

process.stdout.write = write;

there are also other options for overwriting console._stdout depending on the motivation for logging the stdout to a file.