Skip to content

Instantly share code, notes, and snippets.

@shakahl
Forked from pguillory/gist:729616
Last active October 25, 2024 08:12
Show Gist options
  • Save shakahl/038514236e23a80c201e5a7c58275f7c to your computer and use it in GitHub Desktop.
Save shakahl/038514236e23a80c201e5a7c58275f7c 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')
// tommedema commented on May 27, 2012
// Thanks, I've created a use case example for when one uses cluster and wishes to separate per-process output.
module.exports = function(mediator) {
var fs = require('fs'),
path = require('path'),
config = require('../../config'),
env = process.env,
stdout = process.stdout,
stderr = process.stderr,
workerId = env.NODE_WORKER_ID || env.NODE_UNIQUE_ID,
logDir = config.debug.logDir,
stdoutFile = path.resolve(logDir, 'worker#' + workerId + '.log'),
stderrFile = path.resolve(logDir, 'worker#' + workerId + '.err.log');
//run prior to boot ready
mediator.once('boot.init', function() {
//create a new stdout file stream
var stdoutFS = fs.createWriteStream(stdoutFile, {
encoding: 'utf8',
flags : 'a+'
});
//create a new stderr file stream
var stderrFS = fs.createWriteStream(stderrFile, {
encoding: 'utf8',
flags : 'a+'
});
//pipe stdout to a worker file
var unhookStdout = hook_writestream(stdout, function(string, encoding, fd) {
stdoutFS.write(string, encoding || 'utf8');
});
console.log('\n\nPrepared new stdout hook to worker file.');
//pipe stderr to a worker file
var unhookStderr = hook_writestream(stderr, function(string, encoding, fd) {
stderrFS.write(string, encoding || 'utf8');
});
console.log('\n\nPrepared new stderr hook to worker file.');
//unhook when things go wrong
stdoutFS.once('close', function() {
unhookStdout();
console.log('Unhooked stdout.');
});
stdoutFS.once('error', function(err) {
unhookStdout();
console.error('Error: Unhooked stdout due to error %j.', err);
});
stderrFS.once('close', function() {
unhookStderr();
console.log('Unhooked stderr.');
});
stderrFS.once('error', function(err) {
unhookStderr();
console.error('Error: Unhooked stderr due to error %j.', err);
});
});
function hook_writestream(stream, callback) {
var old_write = stream.write;
stream.write = (function(write) {
return function(string, encoding, fd) {
write.apply(stream, arguments);
callback(string, encoding, fd);
};
})(stream.write);
return function() {
stream.write = old_write;
};
}
};
// 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
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment