Skip to content

Instantly share code, notes, and snippets.

@pguillory
Created December 5, 2010 23:51
Show Gist options
  • Select an option

  • Save pguillory/729616 to your computer and use it in GitHub Desktop.

Select an option

Save pguillory/729616 to your computer and use it in GitHub Desktop.
Hooking into Node.js stdout
var util = require('util')
function hook_stdout(callback) {
var old_write = process.stdout.write
process.stdout.write = (function(write) {
return function(string, encoding, fd) {
write.apply(process.stdout, arguments)
callback(string, encoding, fd)
}
})(process.stdout.write)
return function() {
process.stdout.write = old_write
}
}
console.log('a')
console.log('b')
var unhook = hook_stdout(function(string, encoding, fd) {
util.debug('stdout: ' + util.inspect(string))
})
console.log('c')
console.log('d')
unhook()
console.log('e')
console.log('f')
@stringparser

Copy link
Copy Markdown

@IonicaBizau

Copy link
Copy Markdown

Awesome magic here. 😄 Thanks!

@dmarcelino

Copy link
Copy Markdown

Thanks @pguillory, I've used it on debug-logger

@wthit56

wthit56 commented Oct 12, 2015

Copy link
Copy Markdown

Genius! In my implementation, I created a new object to add my changes to:

var stdout = process.stdout;
var shadow = process.stdout = Object.create(process.stdout);
shadow.original = stdout;
shadow.write = function() {
    // stdout.original.write.apply(stdout, arguments); // not shown
    result.stdout += data;
};

(Which didn't work. Ignore me. ;P)

@jkuri

jkuri commented Jan 28, 2016

Copy link
Copy Markdown

Thanks for this.

@karlpokus

Copy link
Copy Markdown

FYI. Commenting out this line mutes the log too.

@reliasn

reliasn commented Dec 14, 2016

Copy link
Copy Markdown

This implementation redirects both stdout and stderr to a log file:

var log_file = require('fs').createWriteStream(__dirname + '/log.txt', {flags : 'w'})

function hook_stream(stream, callback) {
  var old_write = stream.write

  stream.write = (function(write) {
    return function(string, encoding, fd) {
      write.apply(stream, arguments)  // comments this line if you don't want output in the console
      callback(string, encoding, fd)
    }
  })(stream.write)

  return function() {
    stream.write = old_write
  }
}

console.log('a')
console.error('b')

var unhook_stdout = hook_stream(process.stdout, function(string, encoding, fd) {
  log_file.write(string, encoding)
})

var unhook_stderr = hook_stream(process.stderr, function(string, encoding, fd) {
  log_file.write(string, encoding)
})

console.log('c')
console.error('d')

unhook_stdout()
unhook_stderr()

console.log('e')
console.error('f')

It should print in the console

a
b
c
d
e
f

and in the log file:

c
d

@dherault

dherault commented Jun 10, 2019

Copy link
Copy Markdown

This one works with AWS Lambda:

function hookStdout(callback) {
  const boundProcessStdout = process.stdout.write.bind(process.stdout)
  const boundProcessStderr = process.stderr.write.bind(process.stderr)

  process.stdout.write = (string, encoding, fd) => {
    boundProcessStdout(string, encoding, fd)
    callback(string, encoding, fd, false)
  }

  process.stderr.write = (string, encoding, fd) => {
    boundProcessStderr(string, encoding, fd)
    callback(string, encoding, fd, true)
  }

  return () => {
    process.stdout.write = boundProcessStdout
    process.stderr.write = boundProcessStderr
  }
}

@MaiTrinh

MaiTrinh commented Nov 3, 2020

Copy link
Copy Markdown

thanks for this.

@nexensys

Copy link
Copy Markdown

Thank you so much for this! I'm trying to make an advanced CLI for a nextjs app, but webpack uses stdout and messes up all of the formatting!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment