Repository: pinojs/pino
Pull request #317 (2017-10-25 20:46:46)

feat: add additional opts to pretty formatter
#316 - pretty dev formatter

I can improve the quality of tests if required, but its all very simple.


Patch:
diff --git a/docs/API.md b/docs/API.md
index 97cf011..89a768a 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -106,8 +106,10 @@ Returns a new [logger](#logger) instance.
 + `options` (object):
   * `timeTransOnly` (boolean): if set to `true`, it will only covert the unix
   timestamp to ISO 8601 date format, and reserialize the JSON (equivalent to `pino -t`).
-  * `formatter` (function): a custom function to format the line, is passed the
-  JSON object as an argument and should return a string value.
+  * `formatter` (function): a custom function to format the line. It's passed 2 arguments,
+  JSON object log data and an options object
+  that [exposes utility functions](https://github.com/pinojs/pino/blob/master/pretty.js#L110).
+  It should return a string value.
   * `levelFirst` (boolean): if set to `true`, it will print the name of the log
   level as the first field in the log line. Default: `false`.
   * `messageKey` (string): the key in the JSON object to use as the highlighted
diff --git a/pretty.js b/pretty.js
index 049f519..d52bbb1 100755
--- a/pretty.js
+++ b/pretty.js
@@ -97,11 +97,7 @@ function pretty (opts) {
 
     if (parsed.err || !isPinoLine(value)) {
       // pass through
-      return line + '\n'
-    }
-
-    if (formatter) {
-      return opts.formatter(parsed.value) + eol
+      return line + eol
     }
 
     if (timeTransOnly) {
@@ -113,6 +109,18 @@ function pretty (opts) {
         ? asColoredLevel(value) + ' ' + formatTime(value)
         : formatTime(value, ' ') + asColoredLevel(value)
 
+    if (formatter) {
+      return opts.formatter(value, {
+        prefix: line,
+        chalk: ctx,
+        withSpaces: withSpaces,
+        filter: filter,
+        formatTime: formatTime,
+        asColoredText: asColoredText,
+        asColoredLevel: asColoredLevel
+      }) + eol
+    }
+
     line += ' ('
     if (value.name) {
       line += value.name + '/'
@@ -122,7 +130,7 @@ function pretty (opts) {
     if (value[messageKey]) {
       line += ctx.cyan(value[messageKey])
     }
-    line += '\n'
+    line += eol
     if (value.type === 'Error') {
       line += '    ' + withSpaces(value.stack, eol) + eol
     } else {
@@ -149,10 +157,14 @@ function pretty (opts) {
   }
 
   function asColoredLevel (value) {
+    return asColoredText(value, levelColors.hasOwnProperty(value.level) ? levels[value.level] : levels.default)
+  }
+
+  function asColoredText (value, text) {
     if (levelColors.hasOwnProperty(value.level)) {
-      return levelColors[value.level](levels[value.level])
+      return levelColors[value.level](text)
     } else {
-      return levelColors.default(levels.default)
+      return levelColors.default(text)
     }
   }
 }


Test patch:
diff --git a/test/pretty.test.js b/test/pretty.test.js
index fbb40d5..7c54e53 100644
--- a/test/pretty.test.js
+++ b/test/pretty.test.js
@@ -65,8 +65,15 @@ test('pino transform can just parse the dates', function (t) {
 })
 
 test('pino transform can format with a custom function', function (t) {
-  t.plan(1)
-  var prettier = pretty({ formatter: function (line) {
+  t.plan(8)
+  var prettier = pretty({ formatter: function (line, opts) {
+    t.ok(opts.prefix.indexOf('INFO') > -1, 'prefix contains level')
+    t.ok(typeof opts.chalk.white === 'function', 'chalk instance')
+    t.ok(typeof opts.withSpaces === 'function', 'withSpaces function')
+    t.ok(typeof opts.filter === 'function', 'filter function')
+    t.ok(typeof opts.formatTime === 'function', 'formatTime function')
+    t.ok(typeof opts.asColoredText === 'function', 'asColoredText function')
+    t.ok(typeof opts.asColoredLevel === 'function', 'asColoredLevel function')
     return 'msg: ' + line.msg + ', foo: ' + line.foo
   } })
   prettier.pipe(split(function (line) {
@@ -188,7 +195,7 @@ test('handles `true` input', function (t) {
   prettier.end()
 })
 
-test('accept customLogLevvel', function (t) {
+test('accept customLogLevel', function (t) {
   t.plan(1)
   var prettier = pretty()