'bunyan -p PID' support

This commit is contained in:
Trent Mick 2012-11-01 23:49:09 -07:00
parent 899a3420cf
commit 79e5ded839
8 changed files with 172 additions and 12 deletions

View file

@ -1,8 +1,11 @@
# bunyan Changelog # bunyan Changelog
## bunyan 0.15.1 (not yet released) ## bunyan 0.16.0 (not yet released)
(nothing yet) - Add `bunyan -p PID` support. This is a convenience wrapper that effectively
calls:
dtrace -x strsize=4k -qn 'bunyan$PID:::log-*{printf("%s", copyinstr(arg0))}' | bunyan
## bunyan 0.15.0 ## bunyan 0.15.0

View file

@ -1,3 +1,4 @@
- -p PID: proper handling of '-l level'
- "all" or "off" levels? log4j? logging.py? - "all" or "off" levels? log4j? logging.py?
logging.py has NOTSET === 0. I think that is only needed/used for logging.py has NOTSET === 0. I think that is only needed/used for
multi-level hierarchical effective level. multi-level hierarchical effective level.

View file

@ -5,7 +5,7 @@
// See <https://github.com/trentm/node-bunyan>. // See <https://github.com/trentm/node-bunyan>.
// //
var VERSION = "0.15.1"; var VERSION = "0.16.0";
var util = require('util'); var util = require('util');
var pathlib = require('path'); var pathlib = require('path');
@ -13,6 +13,7 @@ var vm = require('vm');
var http = require('http'); var http = require('http');
var fs = require('fs'); var fs = require('fs');
var warn = console.warn; var warn = console.warn;
var spawn = require('child_process').spawn;
@ -134,6 +135,8 @@ function objCopy(obj) {
function printHelp() { function printHelp() {
console.log("Usage:"); console.log("Usage:");
console.log(" bunyan [OPTIONS] [FILE ...]"); console.log(" bunyan [OPTIONS] [FILE ...]");
console.log(" ... | bunyan [OPTIONS]");
console.log(" bunyan [OPTIONS] -p PID");
console.log(""); console.log("");
console.log("Filter and pretty-print Bunyan log file content."); console.log("Filter and pretty-print Bunyan log file content.");
console.log(""); console.log("");
@ -141,6 +144,10 @@ function printHelp() {
console.log(" -h, --help print this help info and exit"); console.log(" -h, --help print this help info and exit");
console.log(" --version print version of this command and exit"); console.log(" --version print version of this command and exit");
console.log(""); console.log("");
console.log("Dtrace options (only on dtrace-supporting platforms):");
console.log(" -p PID Process bunyan:log-* probes from the process");
console.log(" with the given PID.");
console.log("");
console.log("Filtering options:"); console.log("Filtering options:");
console.log(" -l, --level LEVEL"); console.log(" -l, --level LEVEL");
console.log(" Only show messages at or above the specified level."); console.log(" Only show messages at or above the specified level.");
@ -307,13 +314,14 @@ function parseArgv(argv) {
jsonIndent: 2, jsonIndent: 2,
level: null, level: null,
conditions: null, conditions: null,
strict: false strict: false,
pid: null
}; };
// Turn '-iH' into '-i -H', except for argument-accepting options. // Turn '-iH' into '-i -H', except for argument-accepting options.
var args = argv.slice(2); // drop ['node', 'scriptname'] var args = argv.slice(2); // drop ['node', 'scriptname']
var newArgs = []; var newArgs = [];
var optTakesArg = {'d': true, 'o': true, 'c': true, 'l': true}; var optTakesArg = {'d': true, 'o': true, 'c': true, 'l': true, 'p': true};
for (var i = 0; i < args.length; i++) { for (var i = 0; i < args.length; i++) {
if (args[i].charAt(0) === "-" && args[i].charAt(1) !== '-' && args[i].length > 2) { if (args[i].charAt(0) === "-" && args[i].charAt(1) !== '-' && args[i].length > 2) {
var splitOpts = args[i].slice(1).split(""); var splitOpts = args[i].slice(1).split("");
@ -382,6 +390,14 @@ function parseArgv(argv) {
case "-j": // output with JSON.stringify case "-j": // output with JSON.stringify
parsed.outputMode = OM_JSON; parsed.outputMode = OM_JSON;
break; break;
case "-p":
var pidArg = args.shift();
var pid = +(pidArg);
if (isNaN(pid)) {
throw new Error(format('invalid pid: "%s"', pidArg));
}
parsed.pid = pid;
break;
case "-l": case "-l":
case "--level": case "--level":
var levelArg = args.shift(); var levelArg = args.shift();
@ -877,6 +893,48 @@ function processStdin(opts, stylize, callback) {
} }
/**
* Process bunyan:log-* probes from the given pid.
*
* @params opts {Object} Bunyan options object.
* @param stylize {Function} Output stylize function to use.
* @param callback {Function} `function (code)`
*/
function processPid(opts, stylize, callback) {
var leftover = ""; // Left-over partial line from last chunk.
var argv = ['dtrace', '-Z', '-x', 'strsize=4k', '-qn',
format('bunyan%d:::log-*{printf("%s", copyinstr(arg0))}', opts.pid)];
var dtrace = spawn(argv[0], argv.slice(1));
dtrace.stderr.pipe(process.stderr);
dtrace.stdout.setEncoding('utf8');
dtrace.stdout.on('data', function (chunk) {
var lines = chunk.split(/\r\n|\n/);
var length = lines.length;
if (length === 1) {
leftover += lines[0];
return;
}
if (length > 1) {
handleLogLine(null, leftover + lines[0], opts, stylize);
}
leftover = lines.pop();
length -= 1;
for (var i=1; i < length; i++) {
handleLogLine(null, lines[i], opts, stylize);
}
});
dtrace.on('exit', function (code) {
if (leftover) {
handleLogLine(null, leftover, opts, stylize);
leftover = '';
}
callback(code);
});
}
/** /**
* Process all input from the given log file. * Process all input from the given log file.
* *
@ -1009,10 +1067,18 @@ function main(argv) {
console.log("bunyan " + getVersion()); console.log("bunyan " + getVersion());
return; return;
} }
if (opts.pid && opts.args.length > 0) {
warn("bunyan: error: can't use both '-p PID' and file args");
return drainStdoutAndExit(1);
}
var stylize = (opts.color ? stylizeWithColor : stylizeWithoutColor); var stylize = (opts.color ? stylizeWithColor : stylizeWithoutColor);
var retval = 0; var retval = 0;
if (opts.args.length > 0) { if (opts.pid) {
processPid(opts, stylize, function (code) {
process.exit(code);
});
} else if (opts.args.length > 0) {
var files = opts.args; var files = opts.args;
files.forEach(function (file) { files.forEach(function (file) {
streams[file] = { stream: null, records: [], done: false } streams[file] = { stream: null, records: [], done: false }

View file

@ -1,13 +1,13 @@
.\" generated with Ronn/v0.7.3 .\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3 .\" http://github.com/rtomayko/ronn/tree/0.7.3
. .
.TH "BUNYAN" "1" "October 2012" "" "bunyan manual" .TH "BUNYAN" "1" "November 2012" "" "bunyan manual"
. .
.SH "NAME" .SH "NAME"
\fBbunyan\fR \- filter and pretty\-print Bunyan log file content \fBbunyan\fR \- filter and pretty\-print Bunyan log file content
. .
.SH "SYNOPSIS" .SH "SYNOPSIS"
\fBbunyan\fR [OPTIONS] [LOOKUPS\.\.\.] \fBbunyan\fR [OPTIONS] [LOOKUPS\.\.\.] \.\.\. | \fBbunyan\fR [OPTIONS] \fBbunyan\fR [OPTIONS] \-p PID
. .
.SH "DESCRIPTION" .SH "DESCRIPTION"
"Bunyan" is \fBa simple and fast a JSON logging library\fR for node\.js services, a one\-JSON\-object\-per\-line log format, and \fBa \fBbunyan\fR CLI tool\fR for nicely viewing those logs\. This man page describes the latter\. "Bunyan" is \fBa simple and fast a JSON logging library\fR for node\.js services, a one\-JSON\-object\-per\-line log format, and \fBa \fBbunyan\fR CLI tool\fR for nicely viewing those logs\. This man page describes the latter\.
@ -96,6 +96,13 @@ Print version of this command and exit\.
Don\'t warn if input isn\'t valid JSON\. Don\'t warn if input isn\'t valid JSON\.
. .
.P .P
Dtrace options (only on dtrace\-supporting platforms):
.
.TP
\fB\-p PID\fR
Process bunyan:log\-* probes from the process with the given PID\.
.
.P
Filtering options: Filtering options:
. .
.TP .TP
@ -166,6 +173,30 @@ inspect Node\.js `util\.inspect` output\.
. .
.fi .fi
. .
.SH "DTRACE SUPPORT"
On systems that support DTrace (e\.g\., MacOS, FreeBSD, illumos derivatives like SmartOS and OmniOS), Bunyan will create a DTrace provider (\fBbunyan\fR) that makes available the following probes:
.
.IP "" 4
.
.nf
log\-trace
log\-debug
log\-info
log\-warn
log\-error
log\-fatal
.
.fi
.
.IP "" 0
.
.P
Each of these probes has a single argument: the string that would be written to the log\. Note that when a probe is enabled, it will fire whenever the corresponding function is called, even if the level of the log message is less than that of any stream\.
.
.P
See \fIhttps://github\.com/trentm/node\-bunyan#dtrace\-support\fR for more details\.
.
.SH "PROJECT & BUGS" .SH "PROJECT & BUGS"
\fBbunyan\fR is written in JavaScript and requires node\.js (\fBnode\fR)\. The project lives at \fIhttps://github\.com/trentm/node\-bunyan\fR and is published to npm as "bunyan"\. \fBbunyan\fR is written in JavaScript and requires node\.js (\fBnode\fR)\. The project lives at \fIhttps://github\.com/trentm/node\-bunyan\fR and is published to npm as "bunyan"\.
. .

View file

@ -65,6 +65,7 @@
<a href="#OPTIONS">OPTIONS</a> <a href="#OPTIONS">OPTIONS</a>
<a href="#LOG-LEVELS">LOG LEVELS</a> <a href="#LOG-LEVELS">LOG LEVELS</a>
<a href="#OUTPUT-FORMATS">OUTPUT FORMATS</a> <a href="#OUTPUT-FORMATS">OUTPUT FORMATS</a>
<a href="#DTRACE-SUPPORT">DTRACE SUPPORT</a>
<a href="#PROJECT-BUGS">PROJECT &amp; BUGS</a> <a href="#PROJECT-BUGS">PROJECT &amp; BUGS</a>
<a href="#LICENSE">LICENSE</a> <a href="#LICENSE">LICENSE</a>
<a href="#COPYRIGHT">COPYRIGHT</a> <a href="#COPYRIGHT">COPYRIGHT</a>
@ -83,7 +84,9 @@
<h2 id="SYNOPSIS">SYNOPSIS</h2> <h2 id="SYNOPSIS">SYNOPSIS</h2>
<p><code>bunyan</code> [OPTIONS] [LOOKUPS...]</p> <p><code>bunyan</code> [OPTIONS] [LOOKUPS...]
... | <code>bunyan</code> [OPTIONS]
<code>bunyan</code> [OPTIONS] -p PID</p>
<h2 id="DESCRIPTION">DESCRIPTION</h2> <h2 id="DESCRIPTION">DESCRIPTION</h2>
@ -146,6 +149,13 @@ record data. In the COND code, <code>this</code> refers to the record object:</p
</dl> </dl>
<p>Dtrace options (only on dtrace-supporting platforms):</p>
<dl>
<dt class="flush"><code>-p PID</code></dt><dd>Process bunyan:log-* probes from the process with the given PID.</dd>
</dl>
<p>Filtering options:</p> <p>Filtering options:</p>
<dl> <dl>
@ -199,6 +209,27 @@ json-N JSON output, N-space indentation, e.g. "json-0"
inspect Node.js `util.inspect` output. inspect Node.js `util.inspect` output.
</code></pre> </code></pre>
<h2 id="DTRACE-SUPPORT">DTRACE SUPPORT</h2>
<p>On systems that support DTrace (e.g., MacOS, FreeBSD, illumos derivatives
like SmartOS and OmniOS), Bunyan will create a DTrace provider (<code>bunyan</code>)
that makes available the following probes:</p>
<pre><code>log-trace
log-debug
log-info
log-warn
log-error
log-fatal
</code></pre>
<p>Each of these probes has a single argument: the string that would be
written to the log. Note that when a probe is enabled, it will
fire whenever the corresponding function is called, even if the level of
the log message is less than that of any stream.</p>
<p>See <a href="https://github.com/trentm/node-bunyan#dtrace-support" data-bare-link="true">https://github.com/trentm/node-bunyan#dtrace-support</a> for more details.</p>
<h2 id="PROJECT-BUGS">PROJECT &amp; BUGS</h2> <h2 id="PROJECT-BUGS">PROJECT &amp; BUGS</h2>
<p><code>bunyan</code> is written in JavaScript and requires node.js (<code>node</code>). The project <p><code>bunyan</code> is written in JavaScript and requires node.js (<code>node</code>). The project
@ -224,7 +255,7 @@ All rights reserved.</p>
<ol class='man-decor man-foot man foot'> <ol class='man-decor man-foot man foot'>
<li class='tl'></li> <li class='tl'></li>
<li class='tc'>October 2012</li> <li class='tc'>November 2012</li>
<li class='tr'>bunyan(1)</li> <li class='tr'>bunyan(1)</li>
</ol> </ol>

View file

@ -4,6 +4,8 @@
## SYNOPSIS ## SYNOPSIS
`bunyan` \[OPTIONS\] \[LOOKUPS...\] `bunyan` \[OPTIONS\] \[LOOKUPS...\]
... | `bunyan` \[OPTIONS\]
`bunyan` \[OPTIONS\] -p PID
## DESCRIPTION ## DESCRIPTION
@ -68,6 +70,11 @@ record data. In the COND code, `this` refers to the record object:
* `-q`, `--quiet`: * `-q`, `--quiet`:
Don't warn if input isn't valid JSON. Don't warn if input isn't valid JSON.
Dtrace options (only on dtrace-supporting platforms):
* `-p PID`:
Process bunyan:log-* probes from the process with the given PID.
Filtering options: Filtering options:
* `-l`, `--level LEVEL`: * `-l`, `--level LEVEL`:
@ -128,6 +135,27 @@ scripts, uppercase symbols like "DEBUG" are defined for convenience.
inspect Node.js `util.inspect` output. inspect Node.js `util.inspect` output.
## DTRACE SUPPORT
On systems that support DTrace (e.g., MacOS, FreeBSD, illumos derivatives
like SmartOS and OmniOS), Bunyan will create a DTrace provider (`bunyan`)
that makes available the following probes:
log-trace
log-debug
log-info
log-warn
log-error
log-fatal
Each of these probes has a single argument: the string that would be
written to the log. Note that when a probe is enabled, it will
fire whenever the corresponding function is called, even if the level of
the log message is less than that of any stream.
See <https://github.com/trentm/node-bunyan#dtrace-support> for more details.
## PROJECT & BUGS ## PROJECT & BUGS
`bunyan` is written in JavaScript and requires node.js (`node`). The project `bunyan` is written in JavaScript and requires node.js (`node`). The project

View file

@ -4,7 +4,7 @@
* The bunyan logging library for node.js. * The bunyan logging library for node.js.
*/ */
var VERSION = '0.15.1'; var VERSION = '0.16.0';
// Bunyan log format version. This becomes the 'v' field on all log records. // Bunyan log format version. This becomes the 'v' field on all log records.
// `0` is until I release a version '1.0.0' of node-bunyan. Thereafter, // `0` is until I release a version '1.0.0' of node-bunyan. Thereafter,

View file

@ -1,6 +1,6 @@
{ {
"name": "bunyan", "name": "bunyan",
"version": "0.15.1", "version": "0.16.0",
"description": "a JSON Logger library for node.js services", "description": "a JSON Logger library for node.js services",
"author": "Trent Mick <trentm@gmail.com> (http://trentm.com)", "author": "Trent Mick <trentm@gmail.com> (http://trentm.com)",
"main": "./lib/bunyan.js", "main": "./lib/bunyan.js",