From 2438b0b01ca3f02d837c909e7681ae45a45c0b07 Mon Sep 17 00:00:00 2001 From: Trent Mick Date: Wed, 31 Oct 2012 22:17:44 -0700 Subject: [PATCH] issue #48: fix a couple issues with dtrace support - before this, if there were no non-raw streams on the logger the `str` for the dtrace probe.fire would not be created - ensure that with no non-raw streams we only render a record's JSON string if the dtrace probe is enabled --- lib/bunyan.js | 88 ++++++++++++++++++++++++++------------------------- package.json | 2 +- 2 files changed, 46 insertions(+), 44 deletions(-) diff --git a/lib/bunyan.js b/lib/bunyan.js index 1fdc126..bbb2984 100644 --- a/lib/bunyan.js +++ b/lib/bunyan.js @@ -308,7 +308,7 @@ function Logger(options, _childOptions, _childSimple) { for (var level in levelFromName) { var probe; - probes[levelFromName[level]] = probe = + probes[levelFromName[level]] = probe = dtp.addProbe('log-' + level, 'char *'); // Explicitly add a reference to dtp to prevent it from being GC'd @@ -660,33 +660,12 @@ Logger.prototype._mkRecord = function (fields, level, msgArgs) { * Emit a log record. * * @param rec {log record} - * @param noemit {Boolean} Optional. Set to true to only return the string. + * @param noemit {Boolean} Optional. Set to true to skip emission + * and just return the JSON string. */ Logger.prototype._emit = function (rec, noemit) { var i; - var obj = objCopy(rec[0]); - var level = obj.level = rec[2]; - var recFields = rec[1]; - if (recFields) { - if (this.serializers) { - this._applySerializers(recFields); - } - Object.keys(recFields).forEach(function (k) { - obj[k] = recFields[k]; - }); - } - xxx('Record:', rec) - obj.msg = format.apply(this, rec[3]); - if (!obj.time) { - obj.time = (new Date()); - } - // Get call source info - if (this.src && !obj.src) { - obj.src = getCaller3Info() - } - obj.v = LOG_VERSION; - // Lazily determine if this Logger has non-"raw" streams. If there are // any, then we need to stringify the log record. if (this.haveNonRawStreams === undefined) { @@ -701,19 +680,20 @@ Logger.prototype._emit = function (rec, noemit) { // Stringify the object. Attempt to warn/recover on error. var str; - if (this.haveNonRawStreams) { - str = JSON.stringify(obj, safeCycles()) + '\n'; + if (noemit || this.haveNonRawStreams) { + str = JSON.stringify(rec, safeCycles()) + '\n'; } if (noemit) return str; + var level = rec.level; for (i = 0; i < this.streams.length; i++) { var s = this.streams[i]; if (s.level <= level) { xxx('writing log rec "%s" to "%s" stream (%d <= %d): %j', - obj.msg, s.type, s.level, level, obj); - s.stream.write(s.raw ? obj : str); + rec.msg, s.type, s.level, level, rec); + s.stream.write(s.raw ? rec : str); } }; @@ -729,7 +709,7 @@ function mkLogEmitter(minLevel) { return function () { var log = this; - var mkRecord = function (args) { + function mkRecord(args) { if (args[0] instanceof Error) { // `log.(err, ...)` fields = {err: errSerializer(args[0])}; @@ -750,27 +730,49 @@ function mkLogEmitter(minLevel) { fields = args[0]; msgArgs = Array.prototype.slice.call(args, 1); } - return log._mkRecord(fields, minLevel, msgArgs); + + // Build up the record object. + var rec = objCopy(log.fields); + var level = rec.level = minLevel; + var recFields = (fields ? objCopy(fields) : null); + if (recFields) { + if (log.serializers) { + log._applySerializers(recFields); + } + Object.keys(recFields).forEach(function (k) { + rec[k] = recFields[k]; + }); + } + rec.msg = format.apply(log, msgArgs); + if (!rec.time) { + rec.time = (new Date()); + } + // Get call source info + if (log.src && !rec.src) { + rec.src = getCaller3Info() + } + rec.v = LOG_VERSION; + + return rec; }; - var fields = null, msgArgs = null; + var fields = null; + var msgArgs = arguments; + var str = null; + var rec = null; if (arguments.length === 0) { // `log.()` return (this._level <= minLevel); } else if (this._level > minLevel) { - /* - * Even if our level is such that we will not emit the record, we want - * to fire the DTrace probe associated with the level -- but we only - * assemble the string representation if the probe is in fact enabled. - */ - msgArgs = arguments; - - probes[minLevel].fire(function () { - return [ log._emit(mkRecord(msgArgs), true) ]; - }); + /* pass through */ } else { - var str = this._emit(mkRecord(arguments)); - probes[minLevel].fire(function () { return [ str ]; }); + rec = mkRecord(msgArgs); + str = this._emit(rec); } + probes[minLevel].fire(function () { + return [ str || + (rec && log._emit(rec, true)) || + log._emit(mkRecord(msgArgs), true) ]; + }); } } diff --git a/package.json b/package.json index a99e397..d1d0980 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "keywords": ["log", "logging", "log4j", "json"], "dependencies": { - "dtrace-provider": "0.2.2" + "dtrace-provider": "0.2.3" }, "devDependencies": { "tap": "0.2.0",