bunyan CLI output includes all keys

master
Trent Mick 2012-02-08 15:18:07 -08:00
parent 96db4f27c5
commit d53107246a
2 changed files with 77 additions and 18 deletions

View File

@ -2,7 +2,10 @@
## bunyan 0.5.3 (not yet released) ## bunyan 0.5.3 (not yet released)
(nothing yet) - Improve `bunyan` CLI default output to include *all* log record keys. Unknown keys
are either included in the first line parenthetical (if short) or in the indented
subsequent block (if long or multiline).
## bunyan 0.5.2 ## bunyan 0.5.2

View File

@ -107,10 +107,18 @@ function indent(s) {
return ' ' + s.split(/\r?\n/).join('\n ') return ' ' + s.split(/\r?\n/).join('\n ')
} }
function isArray(ar) { function objCopy(obj) {
return ar instanceof Array || if (obj === null) {
Array.isArray(ar) || return null;
(ar && ar !== Object.prototype && isArray(ar.__proto__)); } else if (Array.isArray(obj)) {
return obj.slice();
} else {
var copy = {};
Object.keys(obj).forEach(function (k) {
copy[k] = obj[k];
});
return copy;
}
} }
function printHelp() { function printHelp() {
@ -256,20 +264,31 @@ function handleLogLine(line, opts) {
switch (opts.outputMode) { switch (opts.outputMode) {
case OM_PAUL: case OM_PAUL:
// Single-line msg: // [time] LEVEL: name[/component] on hostname (src): msg* (extras...)
// [time] LEVEL: name[/component] on hostname (src): msg (extras...) // msg*
// Multi-line msg: // --
// [time] LEVEL: name[/component] on hostname (src): (extras...) // long and multi-line extras
// msg // ...
// If 'msg' is single-line, then it goes in the top line.
// If 'req', show the request. // If 'req', show the request.
// If 'res', show the response. // If 'res', show the response.
// If 'err' and 'err.stack' then show that. // If 'err' and 'err.stack' then show that.
delete rec.v;
var time = rec.time;
delete rec.time;
var nameStr = rec.name; var nameStr = rec.name;
delete rec.name;
if (rec.component) { if (rec.component) {
nameStr += '/' + rec.component; nameStr += '/' + rec.component;
} }
var levelStr = (upperNameFromLevel[rec.level] delete rec.component;
|| "<unknown-level " + rec.level + ">");
var level = (upperNameFromLevel[rec.level] || "<level " + rec.level + ">");
delete rec.level;
var src = ""; var src = "";
if (rec.src && rec.src.file) { if (rec.src && rec.src.file) {
var s = rec.src; var s = rec.src;
@ -279,16 +298,31 @@ function handleLogLine(line, opts) {
src = format(" (%s:%d)", s.file, s.line); src = format(" (%s:%d)", s.file, s.line);
} }
} }
delete rec.src;
var hostname = rec.hostname;
delete rec.hostname;
var extras = []; var extras = [];
if (rec.req_id) extras.push("req_id=" + rec.req_id);
if (rec.latency) extras.push(rec.latency + "ms");
extras = (extras.length ? ' (' + extras.join(', ') + ')' : '');
var details = []; var details = [];
if (rec.req_id) {
extras.push("req_id=" + rec.req_id);
}
delete rec.req_id;
if (rec.latency) {
extras.push(rec.latency + "ms");
}
delete rec.latency;
onelineMsg = ' ' + rec.msg; onelineMsg = ' ' + rec.msg;
if (rec.msg.indexOf('\n') !== -1) { if (rec.msg.indexOf('\n') !== -1) {
onelineMsg = ''; onelineMsg = '';
details.push(indent(rec.msg)); details.push(indent(rec.msg));
} }
delete rec.msg;
if (rec.req) { if (rec.req) {
var headers = rec.req.headers; var headers = rec.req.headers;
details.push(indent(format("%s %s HTTP/1.1\n%s", rec.req.method, details.push(indent(format("%s %s HTTP/1.1\n%s", rec.req.method,
@ -296,6 +330,8 @@ function handleLogLine(line, opts) {
Object.keys(headers).map( Object.keys(headers).map(
function (h) { return h + ': ' + headers[h]}).join('\n')))); function (h) { return h + ': ' + headers[h]}).join('\n'))));
} }
delete rec.req;
if (rec.res) { if (rec.res) {
var s = ''; var s = '';
if (rec.res.header) { if (rec.res.header) {
@ -313,15 +349,35 @@ function handleLogLine(line, opts) {
details.push(indent(s)); details.push(indent(s));
} }
} }
delete rec.res;
if (rec.err && rec.err.stack) { if (rec.err && rec.err.stack) {
details.push(indent(rec.err.stack)) details.push(indent(rec.err.stack))
} }
delete rec.err;
var leftover = Object.keys(rec);
for (var i = 0; i < leftover.length; i++) {
var key = leftover[i];
var value = rec[key];
var type = typeof(value);
if (typeof(value) !== 'string') {
value = JSON.stringify(value, null, 2);
}
if (value.indexOf('\n') !== -1 || value.length > 50) {
details.push(indent(key + ': ' + value))
} else {
extras.push(key + '=' + value)
}
}
extras = (extras.length ? ' (' + extras.join(', ') + ')' : '');
details = (details.length ? details.join('\n --\n') + '\n' : ''); details = (details.length ? details.join('\n --\n') + '\n' : '');
emit(format("[%s] %s: %s on %s%s:%s%s\n%s", emit(format("[%s] %s: %s on %s%s:%s%s\n%s",
rec.time, time,
upperNameFromLevel[rec.level] || "<unknown-level " + rec.level + ">", level,
nameStr, nameStr,
rec.hostname || "<no-hostname>", hostname || "<no-hostname>",
src, src,
onelineMsg, onelineMsg,
extras, extras,