issue #54: fix stderr flushing of dtrace child proc (again)
This commit is contained in:
parent
7166772533
commit
69285c7a79
2 changed files with 37 additions and 13 deletions
|
@ -2,7 +2,9 @@
|
||||||
|
|
||||||
## bunyan 0.16.4 (not yet released)
|
## bunyan 0.16.4 (not yet released)
|
||||||
|
|
||||||
(nothing yet)
|
- issue #54: Ensure (again, see 0.16.2) that stderr from the dtrace child
|
||||||
|
process (when using `bunyan -p PID`) gets through. There had been a race
|
||||||
|
between exiting bunyan and the flushing of the dtrace process' stderr.
|
||||||
|
|
||||||
|
|
||||||
## bunyan 0.16.3
|
## bunyan 0.16.3
|
||||||
|
|
46
bin/bunyan
46
bin/bunyan
|
@ -15,6 +15,8 @@ var fs = require('fs');
|
||||||
var warn = console.warn;
|
var warn = console.warn;
|
||||||
var spawn = require('child_process').spawn;
|
var spawn = require('child_process').spawn;
|
||||||
|
|
||||||
|
var nodeSpawnSupportsStdio = (Number(process.version.split('.')[1]) >= 8);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---- globals and constants
|
//---- globals and constants
|
||||||
|
@ -907,13 +909,19 @@ function processPid(opts, stylize, callback) {
|
||||||
var leftover = ""; // Left-over partial line from last chunk.
|
var leftover = ""; // Left-over partial line from last chunk.
|
||||||
var argv = ['dtrace', '-Z', '-x', 'strsize=4k', '-qn',
|
var argv = ['dtrace', '-Z', '-x', 'strsize=4k', '-qn',
|
||||||
format('bunyan%d:::log-*{printf("%s", copyinstr(arg0))}', opts.pid)];
|
format('bunyan%d:::log-*{printf("%s", copyinstr(arg0))}', opts.pid)];
|
||||||
var dtrace = spawn(argv[0], argv.slice(1));
|
var dtrace = spawn(argv[0], argv.slice(1),
|
||||||
child = dtrace; // intentionall global
|
// Share the stderr handle to have error output come
|
||||||
|
// straight through. Only supported in v0.8+.
|
||||||
|
{stdio: ['pipe', 'pipe', process.stderr]});
|
||||||
|
child = dtrace; // intentionally global
|
||||||
|
|
||||||
dtrace.stderr.setEncoding('utf8');
|
function finish(code) {
|
||||||
dtrace.stderr.on('data', function (chunk) {
|
if (leftover) {
|
||||||
process.stderr.write(chunk);
|
handleLogLine(null, leftover, opts, stylize);
|
||||||
});
|
leftover = '';
|
||||||
|
}
|
||||||
|
callback(returnCode);
|
||||||
|
}
|
||||||
|
|
||||||
dtrace.stdout.setEncoding('utf8');
|
dtrace.stdout.setEncoding('utf8');
|
||||||
dtrace.stdout.on('data', function (chunk) {
|
dtrace.stdout.on('data', function (chunk) {
|
||||||
|
@ -932,13 +940,27 @@ function processPid(opts, stylize, callback) {
|
||||||
handleLogLine(null, lines[i], opts, stylize);
|
handleLogLine(null, lines[i], opts, stylize);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dtrace.on('exit', function (code) {
|
|
||||||
if (leftover) {
|
if (nodeSpawnSupportsStdio) {
|
||||||
handleLogLine(null, leftover, opts, stylize);
|
dtrace.on('exit', finish);
|
||||||
leftover = '';
|
} else {
|
||||||
|
// Fallback (for < v0.8) to pipe the dtrace process' stderr to this stderr.
|
||||||
|
// Wait for all of (1) process 'exit', (2) stderr 'end', and (2) stdout
|
||||||
|
// 'end' before returning to ensure all stderr is flushed (issue #54).
|
||||||
|
var returnCode = null;
|
||||||
|
var eventsRemaining = 3;
|
||||||
|
function countdownToFinish(code) {
|
||||||
|
returnCode = code;
|
||||||
|
eventsRemaining--;
|
||||||
|
if (eventsRemaining == 0) {
|
||||||
|
finish(returnCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
callback(code);
|
dtrace.stderr.pipe(process.stderr);
|
||||||
});
|
dtrace.stderr.on('end', countdownToFinish);
|
||||||
|
dtrace.stderr.on('end', countdownToFinish);
|
||||||
|
dtrace.on('exit', countdownToFinish);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue