From fc0150f9fbd692560542111ba555b64251c7fdfd Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 28 May 2014 23:24:57 -0700 Subject: [PATCH] [issue #85] Ensure logging a non-object/non-string doesn't throw --- AUTHORS | 1 + CHANGES.md | 22 ++++-- Makefile | 11 +-- bin/bunyan | 2 +- lib/bunyan.js | 6 +- package.json | 4 +- test/log.test.js | 183 ++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 206 insertions(+), 23 deletions(-) diff --git a/AUTHORS b/AUTHORS index 10f706e..777589b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -5,3 +5,4 @@ Michael Hart (https://github.com/mhart) Isaac Schlueter (https://github.com/isaacs) Rob Gulewich (https://github.com/rgulewich) Bryan Cantrill (https://github.com/bcantrill) +Michael Hart (https://github.com/mhart) diff --git a/CHANGES.md b/CHANGES.md index 8be82d9..d706905 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,9 +6,17 @@ Known issues: bug](https://github.com/TooTallNate/node-gyp/issues/65). -## bunyan 0.22.4 (not yet released) +## bunyan 0.23.0 (not yet released) -(nothing yet) +- Drop node 0.6 support. I can't effectively `npm install` with a node 0.6 + anymore. + +- [issue #85] Ensure logging a non-object/non-string doesn't throw (by + https://github.com/mhart). This changes fixes: + + log.info() # TypeError: Object.keys called on non-object + log.info() # "msg":"" (instead of wanted "msg":"[Function]") + log.info() # "msg":"" (instead of wanted "msg":util.format()) ## bunyan 0.22.3 @@ -20,28 +28,28 @@ Known issues: Note: Bad release. The published package in the npm registry got corrupted. Use 0.22.3 or later. -- #131 Allow `log.info()` and, most importantly, don't crash on that. +- [issue #131] Allow `log.info()` and, most importantly, don't crash on that. - Update 'mv' optional dep to latest. ## bunyan 0.22.1 -- #111 Fix a crash when attempting to use `bunyan -p` on a platform without +- [issue #111] Fix a crash when attempting to use `bunyan -p` on a platform without dtrace. -- #101 Fix a crash in `bunyan` rendering a record with unexpected "res.headers". +- [issue #101] Fix a crash in `bunyan` rendering a record with unexpected "res.headers". ## bunyan 0.22.0 -- #104 `log.reopenFileStreams()` convenience method to be used with external log +- [issue #104] `log.reopenFileStreams()` convenience method to be used with external log rotation. ## bunyan 0.21.4 -- #96 Fix `bunyan` to default to paging (with `less`) by default in node 0.10.0. +- [issue #96] Fix `bunyan` to default to paging (with `less`) by default in node 0.10.0. The intention has always been to default to paging for node >=0.8. diff --git a/Makefile b/Makefile index 0450b03..1dd3a7d 100644 --- a/Makefile +++ b/Makefile @@ -82,10 +82,10 @@ test: $(NODEUNIT) # Test will all node supported versions (presumes install locations I use on # my machine). -# Note: 'test08' is last so (if all is well) I end up with a binary -# dtrace-provider build for node 0.8 (my current version). +# Note: 'test10' is last so (if all is well) I end up with a binary +# dtrace-provider build for node 0.10 (my current version). .PHONY: testall -testall: test06 test10 test08 +testall: test08 test10 .PHONY: test10 test10: @@ -97,11 +97,6 @@ test08: @echo "# Test node 0.8.x (with node `$(NODEOPT)/node-0.8/bin/node --version`)" @$(NODEOPT)/node-0.8/bin/node --version PATH="$(NODEOPT)/node-0.8/bin:$(PATH)" make distclean all test -.PHONY: test06 -test06: - @echo "# Test node 0.6.x (with node `$(NODEOPT)/node-0.6/bin/node --version`)" - @$(NODEOPT)/node-0.6/bin/node --version - PATH="$(NODEOPT)/node-0.6/bin:$(PATH)" make distclean all test #---- check diff --git a/bin/bunyan b/bin/bunyan index 54e4055..8b9b6a7 100755 --- a/bin/bunyan +++ b/bin/bunyan @@ -6,7 +6,7 @@ // See . // -var VERSION = '0.22.4'; +var VERSION = '0.23.0'; var p = console.log; var util = require('util'); diff --git a/lib/bunyan.js b/lib/bunyan.js index 0d5ffd7..3dfe9be 100644 --- a/lib/bunyan.js +++ b/lib/bunyan.js @@ -7,7 +7,7 @@ * vim: expandtab:ts=4:sw=4 */ -var VERSION = '0.22.4'; +var VERSION = '0.23.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, @@ -769,8 +769,8 @@ function mkLogEmitter(minLevel) { } else { msgArgs = Array.prototype.slice.call(args, 1); } - } else if (typeof (args[0]) === 'string' || - typeof (args[0]) === 'number') { + } else if (typeof (args[0]) !== 'object' && args[0] !== null || + Array.isArray(args[0])) { // `log.(msg, ...)` fields = null; msgArgs = Array.prototype.slice.call(args); diff --git a/package.json b/package.json index f3bbba4..7aafafc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bunyan", - "version": "0.22.4", + "version": "0.23.0", "description": "a JSON Logger library for node.js services", "author": "Trent Mick (http://trentm.com)", "main": "./lib/bunyan.js", @@ -12,7 +12,7 @@ "type": "git", "url": "git://github.com/trentm/node-bunyan.git" }, - "engines": ["node >=0.6.0"], + "engines": ["node >=0.8.0"], "keywords": ["log", "logging", "log4j", "json"], "dependencies": { diff --git a/test/log.test.js b/test/log.test.js index 77e013b..5483f68 100644 --- a/test/log.test.js +++ b/test/log.test.js @@ -4,6 +4,11 @@ * Test the `log.trace(...)`, `log.debug(...)`, ..., `log.fatal(...)` API. */ +var util = require('util'), + format = util.format, + inspect = util.inspect; +var p = console.log; + var bunyan = require('../lib/bunyan'); // node-tap API @@ -15,6 +20,8 @@ var before = tap4nodeunit.before; var test = tap4nodeunit.test; +// ---- test boolean `log.()` calls + var log1 = bunyan.createLogger({ name: 'log1', streams: [ @@ -57,5 +64,177 @@ test('log.LEVEL() -> boolean', function (t) { t.end(); }); -//TODO: -// - rest of api + +// ---- test `log.(...)` calls which various input types + +function Catcher() { + this.records = []; +} +Catcher.prototype.write = function (record) { + this.records.push(record); +} +var catcher = new Catcher(); +var log3 = new bunyan.createLogger({ + name: 'log3', + streams: [ + { + type: 'raw', + stream: catcher, + level: 'trace' + } + ] +}); + +var names = ['trace', 'debug', 'info', 'warn', 'error', 'fatal']; +var fields = {one: 'un'}; + +test('log.info(undefined, )', function (t) { + names.forEach(function (lvl) { + log3[lvl].call(log3, undefined, 'some message'); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, 'undefined \'some message\'', + format('log.%s msg is "some message"', lvl)); + }); + t.end(); +}); + +test('log.info(, undefined)', function (t) { + names.forEach(function (lvl) { + log3[lvl].call(log3, fields, undefined); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, 'undefined', + format('log.%s msg: expect "undefined", got %j', lvl, rec.msg)); + t.equal(rec.one, 'un'); + }); + t.end(); +}); + +test('log.info(null, )', function (t) { + names.forEach(function (lvl) { + log3[lvl].call(log3, null, 'some message'); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, 'some message', + format('log.%s msg is "some message"', lvl)); + }); + t.end(); +}); + +test('log.info(, null)', function (t) { + names.forEach(function (lvl) { + log3[lvl].call(log3, fields, null); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, 'null', + format('log.%s msg: expect "null", got %j', lvl, rec.msg)); + t.equal(rec.one, 'un'); + }); + t.end(); +}); + +test('log.info()', function (t) { + names.forEach(function (lvl) { + log3[lvl].call(log3, 'some message'); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, 'some message', + format('log.%s msg is "some message"', lvl)); + }); + t.end(); +}); + +test('log.info(, )', function (t) { + names.forEach(function (lvl) { + log3[lvl].call(log3, fields, 'some message'); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, 'some message', + format('log.%s msg: got %j', lvl, rec.msg)); + t.equal(rec.one, 'un'); + }); + t.end(); +}); + +test('log.info()', function (t) { + names.forEach(function (lvl) { + log3[lvl].call(log3, true); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, 'true', + format('log.%s msg is "true"', lvl)); + }); + t.end(); +}); + +test('log.info(, )', function (t) { + names.forEach(function (lvl) { + log3[lvl].call(log3, fields, true); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, 'true', + format('log.%s msg: got %j', lvl, rec.msg)); + t.equal(rec.one, 'un'); + }); + t.end(); +}); + +test('log.info()', function (t) { + names.forEach(function (lvl) { + log3[lvl].call(log3, 3.14); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, '3.14', + format('log.%s msg: got %j', lvl, rec.msg)); + }); + t.end(); +}); + +test('log.info(, )', function (t) { + names.forEach(function (lvl) { + log3[lvl].call(log3, fields, 3.14); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, '3.14', + format('log.%s msg: got %j', lvl, rec.msg)); + t.equal(rec.one, 'un'); + }); + t.end(); +}); + +test('log.info()', function (t) { + var func = function func1() {}; + names.forEach(function (lvl) { + log3[lvl].call(log3, func); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, '[Function: func1]', + format('log.%s msg: got %j', lvl, rec.msg)); + }); + t.end(); +}); + +test('log.info(, )', function (t) { + var func = function func2() {}; + names.forEach(function (lvl) { + log3[lvl].call(log3, fields, func); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, '[Function: func2]', + format('log.%s msg: got %j', lvl, rec.msg)); + t.equal(rec.one, 'un'); + }); + t.end(); +}); + +test('log.info()', function (t) { + var arr = ['a', 1, {two: 'deux'}]; + names.forEach(function (lvl) { + log3[lvl].call(log3, arr); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, format(arr), + format('log.%s msg: got %j', lvl, rec.msg)); + }); + t.end(); +}); + +test('log.info(, )', function (t) { + var arr = ['a', 1, {two: 'deux'}]; + names.forEach(function (lvl) { + log3[lvl].call(log3, fields, arr); + var rec = catcher.records[catcher.records.length - 1]; + t.equal(rec.msg, format(arr), + format('log.%s msg: got %j', lvl, rec.msg)); + t.equal(rec.one, 'un'); + }); + t.end(); +});