Repository: pinojs/pino
Pull request #324 (2017-11-01 19:39:17)

Optional baseLog
This is essentially #282 with requested changes. Please review and provide feedback


Patch:
diff --git a/docs/API.md b/docs/API.md
index 97cf011..e021f85 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -77,6 +77,10 @@
     See [Extreme mode explained](extreme.md) for more detail.
   * `enabled` (boolean): enables logging. Default: `true`
   * `browser` (Object): browser only, may have `asObject` and `write` keys, see [Pino in the Browser](../readme.md#browser)
+  * `base` (Object): key-value object added as child logger to each log line. If set to `null` the `base` child logger is not added . Default: 
+    * `pid` (process.pid)
+    * `hostname` (os.hostname) 
+    * `name` of logger if supplied as option
   * `crlf` (boolean): logs newline delimited JSON with `\r\n` instead of `\n`. Default: `false`.
 + `stream` (Writable): a writable stream where the logs will be written.
   It can also receive some log-line [metadata](#metadata), if the
diff --git a/lib/levels.js b/lib/levels.js
index e5c3e0f..b6c3392 100644
--- a/lib/levels.js
+++ b/lib/levels.js
@@ -18,7 +18,7 @@ var nums = Object.keys(levels).reduce(function (o, k) {
 
 // level string cache
 var lscache = Object.keys(nums).reduce(function (o, k) {
-  o[k] = flatstr('"level":' + Number(k))
+  o[k] = flatstr('{"level":' + Number(k))
   return o
 }, {})
 
diff --git a/lib/tools.js b/lib/tools.js
index ea305be..a593ced 100644
--- a/lib/tools.js
+++ b/lib/tools.js
@@ -1,12 +1,7 @@
 'use strict'
 
-var flatstr = require('flatstr')
 var format = require('quick-format-unescaped')
 var util = require('util')
-var pid = process.pid
-var os = require('os')
-var hostname = os.hostname()
-var baseLog = flatstr('{"pid":' + pid + ',"hostname":"' + hostname + '",')
 var levels = require('./levels')
 var serializers = require('./serializers')
 var isStandardLevelVal = levels.isStandardLevelVal
@@ -30,10 +25,6 @@ function applyOptions (self, opts) {
     if (levelIsStandard === false && valIsStandard === false) self.addLevel(opts.level, opts.levelVal)
   }
   self._setLevel(opts.level)
-  var str = baseLog +
-    (self.name === undefined ? '' : '"name":' + self.stringify(self.name) + ',')
-  Number(str)
-  self._baseLog = str
 }
 
 function defineLevelsProperty (onObject) {
diff --git a/pino.js b/pino.js
index 0243ad7..04ab1af 100644
--- a/pino.js
+++ b/pino.js
@@ -1,5 +1,6 @@
 'use strict'
 
+var os = require('os')
 var EventEmitter = require('events').EventEmitter
 var stringifySafe = require('fast-safe-stringify')
 var fs = require('fs')
@@ -32,6 +33,10 @@ var defaultOptions = {
     if (err) return process.exit(1)
     process.exit(0)
   },
+  base: {
+    pid: process.pid,
+    hostname: os.hostname()
+  },
   enabled: true,
   messageKey: 'msg'
 }
@@ -128,7 +133,7 @@ function asJson (obj, msg, num) {
   var hasObj = obj !== undefined && obj !== null
   var objError = hasObj && obj instanceof Error
   msg = !msg && objError ? obj.message : msg || undefined
-  var data = this._baseLog + this._lscache[num] + this.time()
+  var data = this._lscache[num] + this.time()
   if (msg !== undefined) {
     // JSON.stringify is safe here
     data += this.messageKeyString + JSON.stringify('' + msg)
@@ -236,7 +241,7 @@ function addLevel (name, lvl) {
   if (this.levels.labels.hasOwnProperty(lvl)) return false
   this.levels.values[name] = lvl
   this.levels.labels[lvl] = name
-  this._lscache[lvl] = flatstr('"level":' + Number(lvl))
+  this._lscache[lvl] = flatstr('{"level":' + Number(lvl))
   Object.defineProperty(this, name, {
     value: lvl < this._levelVal ? tools.noop : tools.genLog(lvl),
     enumerable: true,
@@ -338,6 +343,18 @@ function pino (opts, stream) {
     }
   }
 
+  var base = (typeof iopts.base === 'object') ? iopts.base : defaultOptions.base
+
+  if (iopts.name !== undefined) {
+    base = Object.assign({}, base, {
+      name: iopts.name
+    })
+  }
+
+  if (base !== null) {
+    instance = instance.child(base)
+  }
+
   return instance
 }
 


Test patch:
diff --git a/test/basic.test.js b/test/basic.test.js
index f8821dc..fed25f7 100644
--- a/test/basic.test.js
+++ b/test/basic.test.js
@@ -272,6 +272,47 @@ test('set properties defined in the prototype chain', function (t) {
   instance.info(new MyObject())
 })
 
+test('set the base', function (t) {
+  t.plan(2)
+
+  var instance = pino({
+    base: {
+      a: 'b'
+    }
+  }, sink(function (chunk, enc, cb) {
+    t.ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
+    delete chunk.time
+    t.deepEqual(chunk, {
+      a: 'b',
+      level: 60,
+      msg: 'this is fatal',
+      v: 1
+    })
+    cb()
+  }))
+
+  instance.fatal('this is fatal')
+})
+
+test('set the base to null', function (t) {
+  t.plan(2)
+
+  var instance = pino({
+    base: null
+  }, sink(function (chunk, enc, cb) {
+    t.ok(new Date(chunk.time) <= new Date(), 'time is greater than Date.now()')
+    delete chunk.time
+    t.deepEqual(chunk, {
+      level: 60,
+      msg: 'this is fatal',
+      v: 1
+    })
+    cb()
+  }))
+
+  instance.fatal('this is fatal')
+})
+
 test('throw if creating child without bindings', function (t) {
   t.plan(1)