From 632379030ead3606280612299c617225bef5bea0 Mon Sep 17 00:00:00 2001 From: Evan Oxfeld Date: Mon, 4 Jun 2012 23:23:12 -0400 Subject: [PATCH 01/12] Re-emit fs.createWriteStream errors --- README.md | 1 + lib/bunyan.js | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 24a32d2..5bc0011 100644 --- a/README.md +++ b/README.md @@ -443,6 +443,7 @@ Supported stream types are: "level": "warn" } +- Bunyan re-emits error events if the file cannot be opened successfully. # License diff --git a/lib/bunyan.js b/lib/bunyan.js index 5d0abf7..6b02041 100644 --- a/lib/bunyan.js +++ b/lib/bunyan.js @@ -25,6 +25,7 @@ var os = require('os'); var fs = require('fs'); var util = require('util'); var assert = require('assert'); +var EventEmitter = require('events').EventEmitter; @@ -169,6 +170,8 @@ function resolveLevel(nameOrNum) { //---- Logger class +Logger.prototype = new EventEmitter; + /** * Create a Logger instance. * @@ -316,7 +319,9 @@ function Logger(options, _childOptions, _childSimple) { case 'file': if (!s.stream) { s.stream = fs.createWriteStream(s.path, - {flags: 'a', encoding: 'utf8'}); + {flags: 'a', encoding: 'utf8'}).on('error', function(err) { + self.emit('error', err); + }); if (!s.closeOnExit) { s.closeOnExit = true; } From 858150bbd21a0a43e965a51c2182bd80fa00b5a6 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 4 Jun 2012 23:13:50 -0700 Subject: [PATCH 02/12] pull #21: some style tweaks, add stream to error event args, test case, example, changelog --- CHANGES.md | 11 ++++++++++- examples/handle-fs-error.js | 37 +++++++++++++++++++++++++++++++++++++ lib/bunyan.js | 15 +++++++++------ test/error-event.test.js | 24 ++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 examples/handle-fs-error.js create mode 100644 test/error-event.test.js diff --git a/CHANGES.md b/CHANGES.md index bfe9d34..96e028f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,15 @@ # bunyan Changelog -## bunyan 0.7.1 (not yet released) +## bunyan 0.8.0 (not yet released) + +- [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`) diff --git a/examples/handle-fs-error.js b/examples/handle-fs-error.js new file mode 100644 index 0000000..517999f --- /dev/null +++ b/examples/handle-fs-error.js @@ -0,0 +1,37 @@ +// Example handling as fs error for a Bunyan-created +// stream. + +var fs = require('fs'); +var path = require('path'); +var Logger = require('../lib/bunyan'); + +var FILENAME = 'handle-fs-error.log'; +var S_IWUSR = 00200; // mask for owner write permission in stat mode + +console.warn('- Log file is "%s".', FILENAME); +if (!path.existsSync(FILENAME)) { + console.warn('- Touch log file.'); + fs.writeFileSync(FILENAME, 'touch\n'); +} +if (fs.statSync(FILENAME).mode & S_IWUSR) { + console.warn('- Make log file read-only.'); + fs.chmodSync(FILENAME, 0444); +} + +console.warn('- Create logger.') +var log = new Logger({name: 'handle-fs-error', streams: [{path: FILENAME}]}); + +log.on('error', function (err) { + console.warn('- The logger emitted an error:', err); +}); + +console.warn('- Call log.info(...).') +log.info('info log message'); +console.warn('- Called log.info(...).') + +setTimeout(function () { + console.warn('- Call log.warn(...).') + log.warn('warn log message'); + console.warn('- Called log.warn(...).') +}, 1000); + diff --git a/lib/bunyan.js b/lib/bunyan.js index 6b02041..ffcf567 100644 --- a/lib/bunyan.js +++ b/lib/bunyan.js @@ -4,7 +4,7 @@ * The bunyan logging library for node.js. */ -var VERSION = '0.7.1'; +var VERSION = '0.8.0'; // 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, @@ -170,8 +170,6 @@ function resolveLevel(nameOrNum) { //---- Logger class -Logger.prototype = new EventEmitter; - /** * Create a Logger instance. * @@ -242,6 +240,8 @@ function Logger(options, _childOptions, _childSimple) { throw new TypeError('invalid options.serializers: must be an object') } + EventEmitter.call(this); + // Fast path for simple child creation. if (parent && _childSimple) { // `_isSimpleChild` is a signal to stream close handling that this child @@ -319,9 +319,10 @@ function Logger(options, _childOptions, _childSimple) { case 'file': if (!s.stream) { s.stream = fs.createWriteStream(s.path, - {flags: 'a', encoding: 'utf8'}).on('error', function(err) { - self.emit('error', err); - }); + {flags: 'a', encoding: 'utf8'}); + s.stream.on('error', function (err) { + self.emit('error', err, s); + }); if (!s.closeOnExit) { s.closeOnExit = true; } @@ -404,6 +405,8 @@ function Logger(options, _childOptions, _childSimple) { }); } +util.inherits(Logger, EventEmitter); + /** * Create a child logger, typically to add a few log record fields. diff --git a/test/error-event.test.js b/test/error-event.test.js new file mode 100644 index 0000000..6c8f0cf --- /dev/null +++ b/test/error-event.test.js @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2012 Trent Mick. All rights reserved. + * + * Test emission and handling of 'error' event in a logger with a 'path' + * stream. + */ + +var test = require('tap').test; +var Logger = require('../lib/bunyan'); + +test('error event on log write', function (t) { + LOG_PATH = '/this/path/is/bogus.log' + var log = new Logger({name: 'error-event', streams: [{path: LOG_PATH}]}); + t.plan(5); + log.on('error', function (err, stream) { + t.ok(err, 'got err in error event: ' + err); + t.equal(err.code, 'ENOENT', 'error code is ENOENT'); + t.ok(stream, 'got a stream argument'); + t.equal(stream.path, LOG_PATH); + t.equal(stream.type, 'file'); + t.end(); + }); + log.info('info log message'); +}); From bb8664a5597f4d4024d82647e75417ba2028ddbc Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 4 Jun 2012 23:19:39 -0700 Subject: [PATCH 03/12] jsstyling of example files --- Makefile | 2 +- examples/err.js | 68 +++++++++++++++++++------------------ examples/handle-fs-error.js | 1 - examples/hi.js | 22 ++++++------ examples/level.js | 9 +++-- examples/multi.js | 16 ++++----- examples/server.js | 56 +++++++++++++++--------------- examples/src.js | 17 +++++----- examples/unstringifyable.js | 7 ++-- 9 files changed, 99 insertions(+), 99 deletions(-) diff --git a/Makefile b/Makefile index d1f8c1d..b474205 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ TAP := ./node_modules/.bin/tap #---- Files -JSSTYLE_FILES := $(shell find lib test tools -name "*.js") +JSSTYLE_FILES := $(shell find lib test tools examples -name "*.js") diff --git a/examples/err.js b/examples/err.js index 0efe01b..2eacc7f 100644 --- a/examples/err.js +++ b/examples/err.js @@ -5,52 +5,54 @@ var Logger = require('../lib/bunyan'); var util = require('util'); var log = new Logger({ - name: "myserver", + name: 'myserver', serializers: { err: Logger.stdSerializers.err, // <--- use this } }); try { - throw new TypeError("boom"); + throw new TypeError('boom'); } catch (err) { - log.warn({err: err}, "operation went boom: %s", err) // <--- here + log.warn({err: err}, 'operation went boom: %s', err) // <--- here } -log.info(new TypeError("how about this?")) // <--- alternatively this +log.info(new TypeError('how about this?')) // <--- alternatively this try { - throw "boom string"; + throw 'boom string'; } catch (err) { log.error(err) } -/* - -$ node err.js | ../bin/bunyan -j -{ - "name": "myserver", - "hostname": "banana.local", - "err": { - "stack": "TypeError: boom\n at Object. (/Users/trentm/tm/node-bunyan/examples/err.js:15:9)\n at Module._compile (module.js:411:26)\n at Object..js (module.js:417:10)\n at Module.load (module.js:343:31)\n at Function._load (module.js:302:12)\n at Array.0 (module.js:430:10)\n at EventEmitter._tickCallback (node.js:126:26)", - "name": "TypeError", - "message": "boom" - }, - "level": 4, - "msg": "operation went boom: TypeError: boom", - "time": "2012-02-02T04:42:53.206Z", - "v": 0 -} -$ node err.js | ../bin/bunyan -[2012-02-02T05:02:39.412Z] WARN: myserver on banana.local: operation went boom: TypeError: boom - TypeError: boom - at Object. (/Users/trentm/tm/node-bunyan/examples/err.js:15:9) - at Module._compile (module.js:411:26) - at Object..js (module.js:417:10) - at Module.load (module.js:343:31) - at Function._load (module.js:302:12) - at Array.0 (module.js:430:10) - at EventEmitter._tickCallback (node.js:126:26) - -*/ +/* BEGIN JSSTYLED */ +/** + * + * $ node err.js | ../bin/bunyan -j + * { + * "name": "myserver", + * "hostname": "banana.local", + * "err": { + * "stack": "TypeError: boom\n at Object. (/Users/trentm/tm/node-bunyan/examples/err.js:15:9)\n at Module._compile (module.js:411:26)\n at Object..js (module.js:417:10)\n at Module.load (module.js:343:31)\n at Function._load (module.js:302:12)\n at Array.0 (module.js:430:10)\n at EventEmitter._tickCallback (node.js:126:26)", + * "name": "TypeError", + * "message": "boom" + * }, + * "level": 4, + * "msg": "operation went boom: TypeError: boom", + * "time": "2012-02-02T04:42:53.206Z", + * "v": 0 + * } + * $ node err.js | ../bin/bunyan + * [2012-02-02T05:02:39.412Z] WARN: myserver on banana.local: operation went boom: TypeError: boom + * TypeError: boom + * at Object. (/Users/trentm/tm/node-bunyan/examples/err.js:15:9) + * at Module._compile (module.js:411:26) + * at Object..js (module.js:417:10) + * at Module.load (module.js:343:31) + * at Function._load (module.js:302:12) + * at Array.0 (module.js:430:10) + * at EventEmitter._tickCallback (node.js:126:26) + * + */ +/* END JSSTYLED */ diff --git a/examples/handle-fs-error.js b/examples/handle-fs-error.js index 517999f..b0aa95b 100644 --- a/examples/handle-fs-error.js +++ b/examples/handle-fs-error.js @@ -34,4 +34,3 @@ setTimeout(function () { log.warn('warn log message'); console.warn('- Called log.warn(...).') }, 1000); - diff --git a/examples/hi.js b/examples/hi.js index 0afac83..0f5f21b 100644 --- a/examples/hi.js +++ b/examples/hi.js @@ -1,32 +1,32 @@ var Logger = require('../lib/bunyan'); // Basic usage. -var log = new Logger({name: "myapp", level: "info", src: true}); +var log = new Logger({name: 'myapp', level: 'info', src: true}); // isInfoEnabled replacement -console.log("log.info() is:", log.info()) +console.log('log.info() is:', log.info()) // `util.format`-based printf handling -log.info("hi"); -log.info("hi", "trent"); -log.info("hi %s there", true); +log.info('hi'); +log.info('hi', 'trent'); +log.info('hi %s there', true); // First arg as an object adds fields to the log record. -log.info({foo:"bar", multiline:"one\ntwo\nthree"}, "hi %d", 1, "two", 3); +log.info({foo:'bar', multiline:'one\ntwo\nthree'}, 'hi %d', 1, 'two', 3); // Shows `log.child(...)` to specialize a logger for a sub-component. -console.log("\n") +console.log('\n') function Wuzzle(options) { this.log = options.log; - this.log.info("creating a wuzzle") + this.log.info('creating a wuzzle') } Wuzzle.prototype.woos = function () { - this.log.warn("This wuzzle is woosey.") + this.log.warn('This wuzzle is woosey.') } -var wuzzle = new Wuzzle({log: log.child({component: "wuzzle"})}); +var wuzzle = new Wuzzle({log: log.child({component: 'wuzzle'})}); wuzzle.woos(); -log.info("done with the wuzzle") +log.info('done with the wuzzle') diff --git a/examples/level.js b/examples/level.js index 275d392..80bb563 100644 --- a/examples/level.js +++ b/examples/level.js @@ -37,11 +37,10 @@ try { assert.ok(e.message.indexOf('name') !== -1) } -log.trace("no one should see this") -log.debug("should see this once (on stdout)") -log.info("should see this twice") +log.trace('no one should see this') +log.debug('should see this once (on stdout)') +log.info('should see this twice') log.levels('stdout', INFO) -log.debug("no one should see this either") +log.debug('no one should see this either') log.level('trace') log.trace('should see this twice as 4th and 5th emitted log messages') - diff --git a/examples/multi.js b/examples/multi.js index 00a119e..81400ee 100644 --- a/examples/multi.js +++ b/examples/multi.js @@ -1,20 +1,20 @@ var Logger = require('../lib/bunyan'); log = new Logger({ - name: "amon", + name: 'amon', streams: [ { - level: "info", + level: 'info', stream: process.stdout, }, { - level: "error", - path: "multi.log" + level: 'error', + path: 'multi.log' } ] }); -log.debug("hi nobody on debug"); -log.info("hi stdout on info"); -log.error("hi both on error"); -log.fatal("hi both on fatal"); +log.debug('hi nobody on debug'); +log.info('hi stdout on info'); +log.error('hi both on error'); +log.fatal('hi both on fatal'); diff --git a/examples/server.js b/examples/server.js index 1acff65..c8bdac1 100644 --- a/examples/server.js +++ b/examples/server.js @@ -4,7 +4,7 @@ var http = require('http'); var Logger = require('../lib/bunyan'); var log = new Logger({ - name: "myserver", + name: 'myserver', serializers: { req: Logger.stdSerializers.req, res: Logger.stdSerializers.res @@ -12,13 +12,13 @@ var log = new Logger({ }); var server = http.createServer(function (req, res) { - log.info({req: req}, "start request"); // <-- this is the guy we're testing + log.info({req: req}, 'start request'); // <-- this is the guy we're testing res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); - log.info({res: res}, "done response"); // <-- this is the guy we're testing + log.info({res: res}, 'done response'); // <-- this is the guy we're testing }); -server.listen(1337, "127.0.0.1", function () { - log.info("server listening"); +server.listen(1337, '127.0.0.1', function () { + log.info('server listening'); var options = { port: 1337, hostname: '127.0.0.1', @@ -33,29 +33,31 @@ server.listen(1337, "127.0.0.1", function () { process.exit(); }) }); - req.write("hi from the client"); + req.write('hi from the client'); req.end(); }); -/* - -$ node server.js -{"service":"myserver","hostname":"banana.local","level":3,"msg":"server listening","time":"2012-02-02T05:32:13.257Z","v":0} -{"service":"myserver","hostname":"banana.local","req":{"method":"GET","url":"/path?q=1#anchor","headers":{"x-hi":"Mom","connection":"close"}},"level":3,"msg":"start request","time":"2012-02-02T05:32:13.260Z","v":0} -{"service":"myserver","hostname":"banana.local","res":{"statusCode":200,"_hasBody":true,"_header":"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n","_trailer":""},"level":3,"msg":"done response","time":"2012-02-02T05:32:13.261Z","v":0} - -$ node server.js | ../bin/bunyan -[2012-02-02T05:32:16.006Z] INFO: myserver on banana.local: server listening -[2012-02-02T05:32:16.010Z] INFO: myserver on banana.local: start request - GET /path?q=1#anchor - x-hi: Mom - connection: close -[2012-02-02T05:32:16.011Z] INFO: myserver on banana.local: done response - HTTP/1.1 200 OK - Content-Type: text/plain - Connection: close - Transfer-Encoding: chunked - (body) - -*/ +/* BEGIN JSSTYLED */ +/** + * + * $ node server.js + * {"service":"myserver","hostname":"banana.local","level":3,"msg":"server listening","time":"2012-02-02T05:32:13.257Z","v":0} + * {"service":"myserver","hostname":"banana.local","req":{"method":"GET","url":"/path?q=1#anchor","headers":{"x-hi":"Mom","connection":"close"}},"level":3,"msg":"start request","time":"2012-02-02T05:32:13.260Z","v":0} + * {"service":"myserver","hostname":"banana.local","res":{"statusCode":200,"_hasBody":true,"_header":"HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nConnection: close\r\nTransfer-Encoding: chunked\r\n\r\n","_trailer":""},"level":3,"msg":"done response","time":"2012-02-02T05:32:13.261Z","v":0} + * + * $ node server.js | ../bin/bunyan + * [2012-02-02T05:32:16.006Z] INFO: myserver on banana.local: server listening + * [2012-02-02T05:32:16.010Z] INFO: myserver on banana.local: start request + * GET /path?q=1#anchor + * x-hi: Mom + * connection: close + * [2012-02-02T05:32:16.011Z] INFO: myserver on banana.local: done response + * HTTP/1.1 200 OK + * Content-Type: text/plain + * Connection: close + * Transfer-Encoding: chunked + * (body) + * + */ +/* END JSSTYLED */ diff --git a/examples/src.js b/examples/src.js index bb09e5a..fe4ab50 100644 --- a/examples/src.js +++ b/examples/src.js @@ -3,24 +3,23 @@ var Logger = require('../lib/bunyan'); -var log = new Logger({name: "src-example", src: true}); +var log = new Logger({name: 'src-example', src: true}); -log.info("one"); -log.info("two"); +log.info('one'); +log.info('two'); function doSomeFoo() { - log.info({foo:"bar"}, "three"); + log.info({foo:'bar'}, 'three'); } doSomeFoo(); function Wuzzle(options) { this.log = options.log; - this.log.info("creating a wuzzle") + this.log.info('creating a wuzzle') } Wuzzle.prototype.woos = function () { - this.log.warn("This wuzzle is woosey.") + this.log.warn('This wuzzle is woosey.') } -var wuzzle = new Wuzzle({log: log.child({component: "wuzzle"})}); +var wuzzle = new Wuzzle({log: log.child({component: 'wuzzle'})}); wuzzle.woos(); -log.info("done with the wuzzle") - +log.info('done with the wuzzle') diff --git a/examples/unstringifyable.js b/examples/unstringifyable.js index 4851e59..ddad545 100644 --- a/examples/unstringifyable.js +++ b/examples/unstringifyable.js @@ -1,7 +1,7 @@ // See how bunyan behaves with an un-stringify-able object. -var Logger = require("../lib/bunyan"); +var Logger = require('../lib/bunyan'); -var log = new Logger({src: true, name: "foo"}); +var log = new Logger({src: true, name: 'foo'}); // Make a circular object (cannot be JSON-ified). var myobj = { @@ -9,5 +9,4 @@ var myobj = { }; myobj.myobj = myobj; -log.info({obj: myobj}, "hi there"); // <--- here - +log.info({obj: myobj}, 'hi there'); // <--- here From 4dee56bc1d8f0f40c001398dce38e12d503010fc Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 4 Jun 2012 23:20:33 -0700 Subject: [PATCH 04/12] 0.8.0 release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5fc2e03..460d2ce 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bunyan", - "version": "0.7.1", + "version": "0.8.0", "description": "a JSON Logger library for node.js servers", "author": "Trent Mick (http://trentm.com)", "main": "./lib/bunyan.js", From e9d768b70e9f33e054b3c53df5f43ca85df73921 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 4 Jun 2012 23:21:02 -0700 Subject: [PATCH 05/12] forgot to update version here --- bin/bunyan | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/bunyan b/bin/bunyan index 2ce958c..19bf2e0 100755 --- a/bin/bunyan +++ b/bin/bunyan @@ -5,7 +5,7 @@ // See . // -var VERSION = "0.7.1"; +var VERSION = "0.8.0"; var util = require('util'); var pathlib = require('path'); From cd009b392c710756b4d154d16435931e2d97b8af Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 4 Jun 2012 23:22:39 -0700 Subject: [PATCH 06/12] update version check for jsstyling (using single-quotes for stirngs now) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index b474205..d9455ea 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ all: .PHONY: versioncheck versioncheck: [[ `cat package.json | json version` == `grep '^var VERSION' bin/bunyan | awk -F'"' '{print $$2}'` ]] - [[ `cat package.json | json version` == `grep '^var VERSION' lib/bunyan.js | awk -F'"' '{print $$2}'` ]] + [[ `cat package.json | json version` == `grep '^var VERSION' lib/bunyan.js | awk -F"'" '{print $$2}'` ]] @echo Version check ok. .PHONY: cutarelease From 9e251a5470b7ea3d24031e79b57fa4cad23812a0 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 4 Jun 2012 23:30:58 -0700 Subject: [PATCH 07/12] prepare for 0.8.0 release --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 96e028f..ce0a60c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,6 +1,6 @@ # bunyan Changelog -## bunyan 0.8.0 (not yet released) +## bunyan 0.8.0 - [pull #21] Bunyan loggers now re-emit `fs.createWriteStream` error events. By github.com/EvanOxfeld. See "examples/handle-fs-error.js" and From 80c009a0d756b42ad52a5d3e768ef586e7339bcd Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 4 Jun 2012 23:31:10 -0700 Subject: [PATCH 08/12] prep for future dev --- CHANGES.md | 5 +++++ bin/bunyan | 2 +- lib/bunyan.js | 2 +- package.json | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index ce0a60c..0c1b247 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,10 @@ # bunyan Changelog +## bunyan 0.8.1 (not yet released) + +(nothing yet) + + ## bunyan 0.8.0 - [pull #21] Bunyan loggers now re-emit `fs.createWriteStream` error events. diff --git a/bin/bunyan b/bin/bunyan index 19bf2e0..00fe851 100755 --- a/bin/bunyan +++ b/bin/bunyan @@ -5,7 +5,7 @@ // See . // -var VERSION = "0.8.0"; +var VERSION = "0.8.1"; var util = require('util'); var pathlib = require('path'); diff --git a/lib/bunyan.js b/lib/bunyan.js index ffcf567..aa294f3 100644 --- a/lib/bunyan.js +++ b/lib/bunyan.js @@ -4,7 +4,7 @@ * The bunyan logging library for node.js. */ -var VERSION = '0.8.0'; +var VERSION = '0.8.1'; // 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, diff --git a/package.json b/package.json index 460d2ce..0b9b8ca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bunyan", - "version": "0.8.0", + "version": "0.8.1", "description": "a JSON Logger library for node.js servers", "author": "Trent Mick (http://trentm.com)", "main": "./lib/bunyan.js", From ff3786f7d6d6a98bab46f535f2c5e01c7fc4bd86 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 4 Jun 2012 23:33:03 -0700 Subject: [PATCH 09/12] update to cutarelease 1.0.7 for JS version marker fix --- tools/cutarelease.py | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/tools/cutarelease.py b/tools/cutarelease.py index 5d2fb15..2cfeb98 100755 --- a/tools/cutarelease.py +++ b/tools/cutarelease.py @@ -13,7 +13,7 @@ Conventions: - XXX """ -__version_info__ = (1, 0, 6) +__version_info__ = (1, 0, 7) __version__ = '.'.join(map(str, __version_info__)) import sys @@ -213,12 +213,23 @@ def cutarelease(project_name, version_files, dry_run=False): ver_content = ver_content.replace(marker, '"version": "%s"' % next_version) elif ver_file_type == "javascript": - marker = 'var VERSION = "%s";' % version - if marker not in ver_content: - raise Error("couldn't find `%s' version marker in `%s' " - "content: can't prep for subsequent dev" % (marker, ver_file)) - ver_content = ver_content.replace(marker, - 'var VERSION = "%s";' % next_version) + candidates = [ + ("single", "var VERSION = '%s';" % version), + ("double", 'var VERSION = "%s";' % version), + ] + for quote_type, marker in candidates: + if marker in ver_content: + break + else: + raise Error("couldn't find any candidate version marker in " + "`%s' content: can't prep for subsequent dev: %r" + % (ver_file, candidates)) + if quote_type == "single": + ver_content = ver_content.replace(marker, + "var VERSION = '%s';" % next_version) + else: + ver_content = ver_content.replace(marker, + 'var VERSION = "%s";' % next_version) elif ver_file_type == "python": marker = "__version_info__ = %r" % (version_info,) if marker not in ver_content: @@ -299,7 +310,8 @@ def _parse_version_file(version_file): Supported version file types (i.e. types of files from which we know how to parse the version string/number -- often by some convention): - json: use the "version" key - - javascript: look for a `var VERSION = "1.2.3";` + - javascript: look for a `var VERSION = "1.2.3";` or + `var VERSION = '1.2.3';` - python: Python script/module with `__version_info__ = (1, 2, 3)` - version: a VERSION.txt or VERSION file where the whole contents are the version string @@ -353,8 +365,8 @@ def _parse_version_file(version_file): m = re.search(r'^__version_info__ = (.*?)$', content, re.M) version_info = eval(m.group(1)) elif version_file_type == "javascript": - m = re.search(r'^var VERSION = "(.*?)";$', content, re.M) - version_info = _version_info_from_version(m.group(1)) + m = re.search(r'^var VERSION = (\'|")(.*?)\1;$', content, re.M) + version_info = _version_info_from_version(m.group(2)) elif version_file_type == "version": version_info = _version_info_from_version(content.strip()) else: From 79313595897c3928d29b811e6a1a252330de019f Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 4 Jun 2012 23:37:07 -0700 Subject: [PATCH 10/12] pull #21: tweak readme --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5bc0011..c818477 100644 --- a/README.md +++ b/README.md @@ -443,7 +443,13 @@ Supported stream types are: "level": "warn" } -- Bunyan re-emits error events if the file cannot be opened successfully. + Bunyan re-emits error events from the created `WriteStream`. So you can + do this: + + var log = new Logger({name: 'mylog', streams: [{path: LOG_PATH}]}); + log.on('error', function (err, stream) { + // Handle stream write or create error here. + }); # License From 7e90e07865124ef67ba52e6c83dfa67cb4d6d816 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Tue, 5 Jun 2012 17:22:25 -0700 Subject: [PATCH 11/12] Add test/corpus/*.log files (accidentally excluded) so that test suite works --- .gitignore | 2 +- CHANGES.md | 3 ++- test/corpus/all.log | 20 ++++++++++++++++++++ test/corpus/bogus.log | 2 ++ test/corpus/extrafield.log | 1 + test/corpus/simple.log | 1 + 6 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 test/corpus/all.log create mode 100644 test/corpus/bogus.log create mode 100644 test/corpus/extrafield.log create mode 100644 test/corpus/simple.log diff --git a/.gitignore b/.gitignore index f371022..3de30f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /tmp -/npm-debug.log /node_modules *.log +!/test/corpus/*.log diff --git a/CHANGES.md b/CHANGES.md index 0c1b247..1572251 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,7 +2,8 @@ ## bunyan 0.8.1 (not yet released) -(nothing yet) +- Add test/corpus/*.log files (accidentally excluded) so that test suite + works(!). ## bunyan 0.8.0 diff --git a/test/corpus/all.log b/test/corpus/all.log new file mode 100644 index 0000000..5d59151 --- /dev/null +++ b/test/corpus/all.log @@ -0,0 +1,20 @@ +# levels +{"name":"myservice","pid":123,"hostname":"example.com","level":10,"msg":"My message","time":"2012-02-08T22:56:50.856Z","v":0} +{"name":"myservice","pid":123,"hostname":"example.com","level":20,"msg":"My message","time":"2012-02-08T22:56:51.856Z","v":0} +{"name":"myservice","pid":123,"hostname":"example.com","level":30,"msg":"My message","time":"2012-02-08T22:56:52.856Z","v":0} +{"name":"myservice","pid":123,"hostname":"example.com","level":40,"msg":"My message","time":"2012-02-08T22:56:53.856Z","v":0} +{"name":"myservice","pid":123,"hostname":"example.com","level":50,"msg":"My message","time":"2012-02-08T22:56:54.856Z","v":0} +{"name":"myservice","pid":123,"hostname":"example.com","level":55,"msg":"My message","time":"2012-02-08T22:56:55.856Z","v":0} +{"name":"myservice","pid":123,"hostname":"example.com","level":60,"msg":"My message","time":"2012-02-08T22:56:56.856Z","v":0} + +# extra fields +{"name":"myservice","pid":123,"hostname":"example.com","level":30,"one":"short","msg":"My message","time":"2012-02-08T22:56:52.856Z","v":0} +{"name":"myservice","pid":123,"hostname":"example.com","level":30,"two":"short with space","msg":"My message","time":"2012-02-08T22:56:52.856Z","v":0} +{"name":"myservice","pid":123,"hostname":"example.com","level":30,"three":"multi\nline","msg":"My message","time":"2012-02-08T22:56:52.856Z","v":0} +{"name":"myservice","pid":123,"hostname":"example.com","level":30,"four":"over 50 chars long long long long long long long long long","msg":"My message","time":"2012-02-08T22:56:52.856Z","v":0} +{"name":"myservice","pid":123,"hostname":"example.com","level":30,"five":{"a": "json object"},"msg":"My message","time":"2012-02-08T22:56:52.856Z","v":0} +{"name":"myservice","pid":123,"hostname":"example.com","level":30,"six":["a", "json", "array"],"msg":"My message","time":"2012-02-08T22:56:52.856Z","v":0} + +# bogus +not a JSON line +{"hi": "there"} diff --git a/test/corpus/bogus.log b/test/corpus/bogus.log new file mode 100644 index 0000000..1c9e5fd --- /dev/null +++ b/test/corpus/bogus.log @@ -0,0 +1,2 @@ +not a JSON line +{"hi": "there"} diff --git a/test/corpus/extrafield.log b/test/corpus/extrafield.log new file mode 100644 index 0000000..aac64b9 --- /dev/null +++ b/test/corpus/extrafield.log @@ -0,0 +1 @@ +{"name":"myservice","pid":123,"hostname":"example.com","level":30,"extra":"field","msg":"My message","time":"2012-02-08T22:56:52.856Z","v":0} diff --git a/test/corpus/simple.log b/test/corpus/simple.log new file mode 100644 index 0000000..ebccc0d --- /dev/null +++ b/test/corpus/simple.log @@ -0,0 +1 @@ +{"name":"myservice","pid":123,"hostname":"example.com","level":30,"msg":"My message","time":"2012-02-08T22:56:52.856Z","v":0} From cb6e84921e76d745337bd0885ec3a5eb74889515 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Mon, 18 Jun 2012 12:08:48 -0700 Subject: [PATCH 12/12] add warning about `log.info(myobj)` as both Yunong and Orlando have hit this (at least) --- README.md | 8 ++++++++ TODO.md | 7 ++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c818477..b8083b7 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,14 @@ The full `log.{trace|debug|...|fatal}(...)` API is: log.info(err, 'more on this: %s', more); // ... or you can specify the "msg". +Note that this implies **you cannot pass any object as the first argument +to log it**. IOW, `log.info(myobject)` isn't going to work the way you +expect. Adding support for this API would necessitate (a) JSON-ifying safely +that given object (sometimes hard, and probably slow) and (b) putting all its +attribs under a top-level 'x' field name or something to avoid field name +collisions. + + ## bunyan tool A `bunyan` tool is provided **for pretty-printing bunyan logs** and, eventually, diff --git a/TODO.md b/TODO.md index 1eadffb..58d598f 100644 --- a/TODO.md +++ b/TODO.md @@ -1,4 +1,4 @@ -- [Yuonong] buffered writes to increase speed: +- [Yunong] buffered writes to increase speed: - I'd start with a tools/timeoutput.js for some numbers to compare before/after. Sustained high output to a file. - perhaps this would be a "buffered: true" option on the stream object @@ -20,9 +20,14 @@ as the basis for tools to consume bunyan logs. It can grow indep of node-bunyan for generating the logs. It would take a Bunyan log record object and be expected to emit it. + + node-bunyan-reader + .createReadStream(path, [options]) ? + - document "well-known" keys from bunyan CLI p.o.v.. Add "client_req". - bunyan tool: built in less usage (a la git?) so that I don't have to go through this: `bunyan --color master.log | less -R` +- want `bunyan -f foo.log` a la `tail -f`