NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #4692 most downloaded on npm
a JSON logging library for node.js services
Last release 6 years ago
no release in 18 months
Ships unpredictably
gaps range from 2 weeks to 2.9 years
Nearly every release is documented
notes for 54 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
15 years old
112 releases · first in 2012
[pull #67] Remove debugging prints in rotating-file support. (by github.com/chad3814).
Get the bunyan CLI to not automatically page (i.e. pipe to less) if stdin isn't a TTY, or if following dtrace probe output (via -p PID), or if not giv
bunyan CLI to not automatically page (i.e. pipe to less)
if stdin isn't a TTY, or if following dtrace probe output (via -p PID),
or if not given log file arguments.One column per quarter.
Automatic paging support in the bunyan CLI (similar to git log et al). IOW, bunyan will open your pager (by default less) and pipe rendered log output
Automatic paging support in the bunyan CLI (similar to git log et al).
IOW, bunyan will open your pager (by default less) and pipe rendered
log output through it. A main benefit of this is getting colored logs with
a pager without the pain. Before you had to explicit use --color to tell
bunyan to color output when the output was not a TTY:
bunyan foo.log --color | less -R # before
bunyan foo.log # now
Disable with the --no-pager option or the BUNYAN_NO_PAGER=1 environment
variable.
Limitations: Only supported for node >=0.8. Windows is not supported (at least not yet).
Switch test suite to nodeunit (still using a node-tap'ish API via a helper).
[issue #33] Log rotation support:
[issue #33] Log rotation support:
var bunyan = require('bunyan');
var log = bunyan.createLogger({
name: 'myapp',
streams: [{
type: 'rotating-file',
path: '/var/log/myapp.log',
count: 7,
period: 'daily'
}]
});
Tweak to CLI default pretty output: don't special case "latency" field. The special casing was perhaps nice, but less self-explanatory. Before:
[2012-12-27T21:17:38.218Z] INFO: audit/45769 on myserver: handled: 200 (15ms, audit=true, bar=baz)
GET /foo
...
After:
[2012-12-27T21:17:38.218Z] INFO: audit/45769 on myserver: handled: 200 (audit=true, bar=baz, latency=15)
GET /foo
...
Exit CLI on EPIPE, otherwise we sit there useless processing a huge log
file with, e.g. bunyan huge.log | head.
Guards on -c CONDITION usage to attempt to be more user friendly. Bogus JS code will result in this:
Guards on -c CONDITION usage to attempt to be more user friendly.
Bogus JS code will result in this:
$ bunyan portal.log -c 'this.req.username==boo@foo'
bunyan: error: illegal CONDITION code: SyntaxError: Unexpected token ILLEGAL
CONDITION script:
Object.prototype.TRACE = 10;
Object.prototype.DEBUG = 20;
Object.prototype.INFO = 30;
Object.prototype.WARN = 40;
Object.prototype.ERROR = 50;
Object.prototype.FATAL = 60;
this.req.username==boo@foo
Error:
SyntaxError: Unexpected token ILLEGAL
at new Script (vm.js:32:12)
at Function.Script.createScript (vm.js:48:10)
at parseArgv (/Users/trentm/tm/node-bunyan-0.x/bin/bunyan:465:27)
at main (/Users/trentm/tm/node-bunyan-0.x/bin/bunyan:1252:16)
at Object.<anonymous> (/Users/trentm/tm/node-bunyan-0.x/bin/bunyan:1330:3)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.runMain (module.js:492:10)
And all CONDITION scripts will be run against a minimal valid Bunyan log record to ensure they properly guard against undefined values (at least as much as can reasonably be checked). For example:
$ bunyan portal.log -c 'this.req.username=="bob"'
bunyan: error: CONDITION code cannot safely filter a minimal Bunyan log record
CONDITION script:
Object.prototype.TRACE = 10;
Object.prototype.DEBUG = 20;
Object.prototype.INFO = 30;
Object.prototype.WARN = 40;
Object.prototype.ERROR = 50;
Object.prototype.FATAL = 60;
this.req.username=="bob"
Minimal Bunyan log record:
{
"v": 0,
"level": 30,
"name": "name",
"hostname": "hostname",
"pid": 123,
"time": 1355514346206,
"msg": "msg"
}
Filter error:
TypeError: Cannot read property 'username' of undefined
at bunyan-condition-0:7:9
at Script.Object.keys.forEach.(anonymous function) [as runInNewContext] (vm.js:41:22)
at parseArgv (/Users/trentm/tm/node-bunyan-0.x/bin/bunyan:477:18)
at main (/Users/trentm/tm/node-bunyan-0.x/bin/bunyan:1252:16)
at Object.<anonymous> (/Users/trentm/tm/node-bunyan-0.x/bin/bunyan:1330:3)
at Module._compile (module.js:449:26)
at Object.Module._extensions..js (module.js:467:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.runMain (module.js:492:10)
A proper way to do that condition would be:
$ bunyan portal.log -c 'this.req && this.req.username=="bob"'
[issue #59] Clear a possibly interrupted ANSI color code on signal termination.
[issue #56] Support bunyan -p NAME to dtrace all PIDs matching 'NAME' in their command and args (using ps -A -o pid,command | grep NAME or, on SunOS p
[issue #56] Support bunyan -p NAME to dtrace all PIDs matching 'NAME' in
their command and args (using ps -A -o pid,command | grep NAME or, on SunOS
pgrep -lf NAME). E.g.:
bunyan -p myappname
This is useful for usage of node's cluster module where you'll have multiple worker processes.
Allow bunyan -p '*' to capture bunyan dtrace probes from all processes.
bunyan -p '*' to capture bunyan dtrace probes from all processes.BUNYAN_NO_COLOR environment variable to
turn off all output coloring. This is still overridden by the --color
and --no-color options.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
bunyan -p PID) gets through. There had been a race
between exiting bunyan and the flushing of the dtrace process' stderr.Drop 'trentm-dtrace-provider' fork dep now that has been resolved. Back to dtrace-provider.
Ensure that stderr from the dtrace child process (when using bunyan -p PID) gets through. The pipe usage wasn't working on SmartOS. This is important
bunyan -p PID)
gets through. The pipe usage wasn't working on SmartOS. This is important
to show the user if they need to 'sudo'.Ensure that a possible dtrace child process (with using bunyan -p PID) is terminated on signal termination of the bunyan CLI (at least for SIGINT, SIG
bunyan -p PID) is
terminated on signal termination of the bunyan CLI (at least for SIGINT,
SIGQUIT, SIGTERM, SIGHUP).Add bunyan -p PID support. This is a convenience wrapper that effectively calls:
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
issue #48: Dtrace support! The elevator pitch is you can watch all logging from all Bunyan-using process with something like this:
issue #48: Dtrace support! The elevator pitch is you can watch all logging from all Bunyan-using process with something like this:
dtrace -x strsize=4k -qn 'bunyan*:::log-*{printf("%d: %s: %s", pid, probefunc, copyinstr(arg0))}'
And this can include log levels below what the service is actually configured to log. E.g. if the service is only logging at INFO level and you need to see DEBUG log messages, with this you can. Obviously this only works on dtrace-y platforms: Illumos derivatives of SunOS (e.g. SmartOS, OmniOS), Mac, FreeBSD.
Or get the bunyan CLI to render logs nicely:
dtrace -x strsize=4k -qn 'bunyan*:::log-*{printf("%s", copyinstr(arg0))}' | bunyan
See https://github.com/trentm/node-bunyan#dtrace-support for details. By Bryan Cantrill.
Export bunyan.safeCycles(). This may be useful for custom type == "raw" streams that may do JSON stringification of log records themselves. Usage:
Export bunyan.safeCycles(). This may be useful for custom type == "raw"
streams that may do JSON stringification of log records themselves. Usage:
var str = JSON.stringify(rec, bunyan.safeCycles());
[issue #49] Allow a log.child() to specify the level of inherited streams.
For example:
# Before
var childLog = log.child({...});
childLog.level('debug');
# After
var childLog = log.child({..., level: 'debug'});
Improve the Bunyan CLI crash message to make it easier to provide relevant details in a bug report.
Fix a bug in the long-stack-trace error serialization added in 0.14.4. The symptom:
Fix a bug in the long-stack-trace error serialization added in 0.14.4. The symptom:
bunyan@0.14.4: .../node_modules/bunyan/lib/bunyan.js:1002
var ret = ex.stack || ex.toString();
^
TypeError: Cannot read property 'stack' of undefined
at getFullErrorStack (.../node_modules/bunyan/lib/bunyan.js:1002:15)
...
Bad release. Use 0.14.5 instead.
Bad release. Use 0.14.5 instead.
Improve error serialization to walk the chain of .cause() errors
from the likes of WError or VError error classes from
verror and
restify v2.0. Example:
[2012-10-11T00:30:21.871Z] ERROR: imgapi/99612 on 0525989e-2086-4270-b960-41dd661ebd7d: my-message
ValidationFailedError: my-message; caused by TypeError: cause-error-message
at Server.apiPing (/opt/smartdc/imgapi/lib/app.js:45:23)
at next (/opt/smartdc/imgapi/node_modules/restify/lib/server.js:550:50)
at Server.setupReq (/opt/smartdc/imgapi/lib/app.js:178:9)
at next (/opt/smartdc/imgapi/node_modules/restify/lib/server.js:550:50)
at Server.parseBody (/opt/smartdc/imgapi/node_modules/restify/lib/plugins/body_parser.js:15:33)
at next (/opt/smartdc/imgapi/node_modules/restify/lib/server.js:550:50)
at Server.parseQueryString (/opt/smartdc/imgapi/node_modules/restify/lib/plugins/query.js:40:25)
at next (/opt/smartdc/imgapi/node_modules/restify/lib/server.js:550:50)
at Server._run (/opt/smartdc/imgapi/node_modules/restify/lib/server.js:579:17)
at Server._handle.log.trace.req (/opt/smartdc/imgapi/node_modules/restify/lib/server.js:480:38)
Caused by: TypeError: cause-error-message
at Server.apiPing (/opt/smartdc/imgapi/lib/app.js:40:25)
at next (/opt/smartdc/imgapi/node_modules/restify/lib/server.js:550:50)
at Server.setupReq (/opt/smartdc/imgapi/lib/app.js:178:9)
at next (/opt/smartdc/imgapi/node_modules/restify/lib/server.js:550:50)
at Server.parseBody (/opt/smartdc/imgapi/node_modules/restify/lib/plugins/body_parser.js:15:33)
at next (/opt/smartdc/imgapi/node_modules/restify/lib/server.js:550:50)
at Server.parseQueryString (/opt/smartdc/imgapi/node_modules/restify/lib/plugins/query.js:40:25)
at next (/opt/smartdc/imgapi/node_modules/restify/lib/server.js:550:50)
at Server._run (/opt/smartdc/imgapi/node_modules/restify/lib/server.js:579:17)
at Server._handle.log.trace.req (/opt/smartdc/imgapi/node_modules/restify/lib/server.js:480:38)
[issue #45] Fix bunyan CLI (default output mode) to not crash on a 'res' field that isn't a response object, but a string.
[issue #44] Fix the default bunyan CLI output of a res.body that is an object instead of a string. See issue#38 for the same with req.body.
bunyan CLI output of a res.body that is an
object instead of a string. See issue#38 for the same with req.body.[pull #41] Safe JSON.stringifying of emitted log records to avoid blowing up on circular objects (by Isaac Schlueter).
JSON.stringifying of emitted log records to avoid blowing
up on circular objects (by Isaac Schlueter).[issue #39] Fix a bug with client_req handling in the default output of the bunyan CLI.
client_req handling in the default output
of the bunyan CLI.[issue #38] Fix the default bunyan CLI output of a req.body that is an object instead of a string.
bunyan CLI output of a req.body that is an
object instead of a string.Export bunyan.resolveLevel(NAME-OR-NUM) to resolve a level name or number to its log level number value:
Export bunyan.resolveLevel(NAME-OR-NUM) to resolve a level name or number
to its log level number value:
> bunyan.resolveLevel('INFO')
30
> bunyan.resolveLevel('debug')
20
A side-effect of this change is that the uppercase level name is now allowed in the logger constructor.
[issue #35] Ensure that an accidental log.info(BUFFER), where BUFFER is a node.js Buffer object, doesn't blow up.
log.info(BUFFER), where BUFFER is
a node.js Buffer object, doesn't blow up.[issue #34] Ensure req.body, res.body and other request/response fields are emitted by the bunyan CLI (mostly by Rob Gulewich).
req.body, res.body and other request/response fields
are emitted by the bunyan CLI (mostly by Rob Gulewich).[issue #31] Re-instate defines for the (uppercase) log level names (TRACE, DEBUG, etc.) in bunyan -c "..." filtering condition code. E.g.:
[issue #31] Re-instate defines for the (uppercase) log level names (TRACE,
DEBUG, etc.) in bunyan -c "..." filtering condition code. E.g.:
$ ... | bunyan -c 'level >= ERROR'
[pull #32] bunyan -o short for more concise output (by Dave Pacheco). E.g.:
[pull #32] bunyan -o short for more concise output (by Dave Pacheco). E.g.:
22:56:52.856Z INFO myservice: My message
instead of:
[2012-02-08T22:56:52.856Z] INFO: myservice/123 on example.com: My message
Add '--strict' option to bunyan CLI to suppress all but legal Bunyan JSON log lines. By default non-JSON, and non-Bunyan lines are passed through.
bunyan CLI to suppress all but legal Bunyan JSON
log lines. By default non-JSON, and non-Bunyan lines are passed through.[issue #30] Robust handling of 'req' field without a 'headers' subfield in bunyan CLI.
bunyan CLI.bunyan -c "..."
filtering code. This was added in v0.11.1, but has a significant adverse
affect.[pull #29] Add -l/--level for level filtering, and -c/--condition for arbitrary conditional filtering (by github.com/isaacs):
[pull #29] Add -l/--level for level filtering, and -c/--condition for arbitrary conditional filtering (by github.com/isaacs):
$ ... | bunyan -l error # filter out log records below error
$ ... | bunyan -l 50 # numeric value works too
$ ... | bunyan -c 'level===50' # equiv with -c filtering
$ ... | bunyan -c 'pid===123' # filter on any field
$ ... | bunyan -c 'pid===123' -c '_audit' # multiple filters
[pull #24] Support for gzip'ed log files in the bunyan CLI (by github.com/mhart):
[pull #24] Support for gzip'ed log files in the bunyan CLI (by github.com/mhart):
$ bunyan foo.log.gz
...
[pull #16] Bullet proof the bunyan.stdSerializers (by github.com/rlidwka).
[pull #16] Bullet proof the bunyan.stdSerializers (by github.com/rlidwka).
[pull #15] The bunyan CLI will now chronologically merge multiple log
streams when it is given multiple file arguments. (by github.com/davepacheco)
$ bunyan foo.log bar.log
... merged log records ...
[pull #15] A new bunyan.RingBuffer stream class that is useful for
keeping the last N log messages in memory. This can be a fast way to keep
recent, and thus hopefully relevant, log messages. (by @dapsays,
github.com/davepacheco)
Potential uses: Live debugging if a running process could inspect those
messages. One could dump recent log messages at a finer log level than is
typically logged on
uncaughtException.
var ringbuffer = new bunyan.RingBuffer({ limit: 100 });
var log = new bunyan({
name: 'foo',
streams: [{
type: 'raw',
stream: ringbuffer,
level: 'debug'
}]
});
log.info('hello world');
console.log(ringbuffer.records);
Add support for "raw" streams. This is a logging stream that is given raw log record objects instead of a JSON-stringified string.
function Collector() {
this.records = [];
}
Collector.prototype.write = function (rec) {
this.records.push(rec);
}
var log = new Logger({
name: 'mylog',
streams: [{
type: 'raw',
stream: new Collector()
}]
});
See "examples/raw-stream.js". I expect raw streams to be useful for piping Bunyan logging to separate services (e.g. http://www.loggly.com/, https://github.com/etsy/statsd) or to separate in-process handling.
Add test/corpus/*.log files (accidentally excluded) so the test suite actually works(!).
[pull #21] Bunyan loggers now re-emit fs.createWriteStream error events. By github.com/EvanOxfeld. See "examples/handle-fs-error.js" and "test/error-e
[pull #21] Bunyan loggers now re-emit fs.createWriteStream error events.
By github.com/EvanOxfeld. See "examples/handle-fs-error.js" and
"test/error-event.js" for details.
var log = new Logger({name: 'mylog', streams: [{path: FILENAME}]});
log.on('error', function (err, stream) {
// Handle error writing to or creating FILENAME.
});
jsstyle'ing (via make check)
[issue #12] Add bunyan.createLogger(OPTIONS) form, as is more typical in node.js APIs. This'll eventually become the preferred form.
bunyan.createLogger(OPTIONS) form, as is more typical in
node.js APIs. This'll eventually become the preferred form.Change bunyan CLI default output to color "src" info red. Before the "src" information was uncolored. The "src" info is the filename, line number and
Change bunyan CLI default output to color "src" info red. Before the "src"
information was uncolored. The "src" info is the filename, line number and
function name resulting from using src: true in Logger creation. I.e.,
the (/Users/trentm/tm/node-bunyan/examples/hi.js:10) in:
[2012-04-10T22:28:58.237Z] INFO: myapp/39339 on banana.local (/Users/trentm/tm/node-bunyan/examples/hi.js:10): hi
Tweak bunyan CLI default output to still show an "err" field if it doesn't
have a "stack" attribute.
Fix bad bug in log.child({...}, true); where the added child fields would be added to the parent's fields. This bug only existed for the "fast child"
log.child({...}, true); where the added child fields would
be added to the parent's fields. This bug only existed for the "fast child"
path (that second true argument). A side-effect of fixing this is that
the "fast child" path is only 5 times as fast as the regular log.child,
instead of 10 times faster.[issue #6] Fix bleeding 'type' var to global namespace. (Thanks Mike!)
Add support to the bunyan CLI taking log file path args, bunyan foo.log, in addition to the usual cat foo.log | bunyan.
bunyan CLI taking log file path args, bunyan foo.log,
in addition to the usual cat foo.log | bunyan.bunyan CLI.
Before it could blow up processing log records missing some expected
fields.ANSI coloring output from bunyan CLI tool (for the default output mode/style). Also add the '--color' option to force coloring if the output stream is
bunyan CLI tool (for the default output mode/style).
Also add the '--color' option to force coloring if the output stream is not
a TTY, e.g. cat my.log | bunyan --color | less -R. Use --no-color to
disable coloring, e.g. if your terminal doesn't support ANSI codes.[issue #5] Fix log.info() -> boolean to work properly. Previous all were returning false. Ditto all trace/debug/.../fatal methods.
log.info() -> boolean to work properly. Previous all were
returning false. Ditto all trace/debug/.../fatal methods.Allow an optional msg and arguments to the log.info( err) logging form. For example, before:
Allow an optional msg and arguments to the log.info(<Error> err) logging
form. For example, before:
log.debug(my_error_instance) // good
log.debug(my_error_instance, "boom!") // wasn't allowed
Now the latter is allowed if you want to expliciting set the log msg. Of course
this applies to all the log.{trace|debug|info...}() methods.
bunyan cli output: clarify extra fields with quoting if empty or have
spaces. E.g. 'cmd' and 'stderr' in the following:
[2012-02-12T00:30:43.736Z] INFO: mo-docs/43194 on banana.local: buildDocs results (req_id=185edca2-2886-43dc-911c-fe41c09ec0f5, route=PutDocset, error=null, stderr="", cmd="make docs")
Fix/guard against unintended inclusion of some files in npm published package due to
Internal: starting jsstyle usage.
Add 'pid' automatic log record field.
Add 'client_req' (HTTP client request) standard formatting in bunyan CLI default output.
bunyan CLI
default output.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).[issue #3] More type checking of new Logger(...) and log.child(...) options.
new Logger(...) and log.child(...)
options.[issue #2] Add guard on JSON.stringifying of log records before emission. This will prevent log.info et al throwing on record fields that cannot be re
[issue #2] Add guard on JSON.stringifying of log records before emission.
This will prevent log.info et al throwing on record fields that cannot be
represented as JSON. An error will be printed on stderr and a clipped log
record emitted with a 'bunyanMsg' key including error details. E.g.:
bunyan: ERROR: could not stringify log record from /Users/trentm/tm/node-bunyan/examples/unstringifyable.js:12: TypeError: Converting circular structure to JSON
{
"name": "foo",
"hostname": "banana.local",
"bunyanMsg": "bunyan: ERROR: could not stringify log record from /Users/trentm/tm/node-bunyan/examples/unstringifyable.js:12: TypeError: Converting circular structure to JSON",
...
Some timing shows this does effect log speed:
$ node tools/timeguard.js # before
Time try/catch-guard on JSON.stringify:
- log.info: 0.07365ms per iteration
$ node tools/timeguard.js # after
Time try/catch-guard on JSON.stringify:
- log.info: 0.07368ms per iteration
Use 10/20/... instead of 1/2/... for level constant values. Ostensibly this allows for intermediary levels from the defined "trace/debug/..." set. How
Use 10/20/... instead of 1/2/... for level constant values. Ostensibly this allows for intermediary levels from the defined "trace/debug/..." set. However, that is discouraged. I'd need a strong user argument to add support for easily using alternative levels. Consider using a separate JSON field instead.
s/service/name/ for Logger name field. "service" is unnecessarily tied to usage for a service. No need to differ from log4j Logger "name".
Add log.level(...) and log.levels(...) API for changing logger stream
levels.
Add TRACE|DEBUG|INFO|WARN|ERROR|FATAL level constants to exports.
Add log.info(err) special case for logging an Error instance. For
example log.info(new TypeError("boom") will produce:
...
"err": {
"message": "boom",
"name": "TypeError",
"stack": "TypeError: boom\n at Object.<anonymous> ..."
},
"msg": "boom",
...
Add new Logger({src: true}) config option to have a 'src' attribute be automatically added to log records with the log call source info. Example:
Add new Logger({src: true}) config option to have a 'src' attribute be
automatically added to log records with the log call source info. Example:
"src": {
"file": "/Users/trentm/tm/node-bunyan/examples/src.js",
"line": 20,
"func": "Wuzzle.woos"
},
log.child(options[, simple]) Added simple boolean arg. Set true to assert that options only add fields (no config changes). Results in a 10x speed inc
log.child(options[, simple]) Added simple boolean arg. Set true to
assert that options only add fields (no config changes). Results in a 10x
speed increase in child creation. See "tools/timechild.js". On my Mac,
"fast child" creation takes about 0.001ms. IOW, if your app is dishing
10,000 req/s, then creating a log child for each request will take
about 1% of the request time.log.clone -> log.child to better reflect the relationship: streams and
serializers are inherited. Streams can't be removed as part of the child
creation. The child doesn't own the parent's streams (so can't close them).log.child usage
is fast. TODO: measure that.Logger.stdSerializers.err serializer which is necessary to get good
Error object logging with node 0.6 (where core Error object properties
are non-enumerable).Spec'ing core/recommended log record fields.
LOG_VERSION to exports.First release.
First release.
Your coding agent can read these notes before it upgrades. Set up the MCP server →