From be9464a4a5b9b20ad30b0672a2ef3c1497b16903 Mon Sep 17 00:00:00 2001 From: Matthew Adams Date: Mon, 6 Jan 2020 18:46:42 -0600 Subject: [PATCH 1/4] support objectKey config --- docs/api.md | 26 ++++++++++++++++++++++++++ lib/symbols.js | 2 ++ lib/tools.js | 4 +++- package.json | 2 +- pino.js | 4 ++++ test/basic.test.js | 20 ++++++++++++++++++++ 6 files changed, 56 insertions(+), 2 deletions(-) diff --git a/docs/api.md b/docs/api.md index 6e15ba350..2c6f45da9 100644 --- a/docs/api.md +++ b/docs/api.md @@ -201,6 +201,32 @@ Default: `'msg'` The string key for the 'message' in the JSON object. + +#### `objectKey` (String) + +Default: `null` + +If there's a chance that objects that you're logging have properties that conflict with those from pino itself (`level`, `timestamp`, `v`, `pid`, etc) +and you don't want duplicate keys in your log records, you can set an `objectKey` option that causes any `object`s that are logged +to be placed under a key whose name is the value of `objectKey`. + +This way, when you're doing something like searching Kibana for values, you can consistently search under the configured `objectKey` value instead of the root log record keys. + +For example, +```js +const logger = require('pino')({ + objectKey: 'payload' +}) + +const thing = { level: 'hi', timestamp: 'never', foo: 'bar'} // has pino-conflicting properties! +logger.info(thing) + +// logs the following: +// {"level":30,"time":1578357790020,"pid":91736,"hostname":"x","payload":{"level":"hi","timestamp":"never","foo":"bar"},"v":1} +``` +In this way, you never have to worry that one of your logged objects' properties conflicts with pino's standard logging properties, +and you always know which key to start searching from when you're looking for logged objects. + #### `prettyPrint` (Boolean | Object) diff --git a/lib/symbols.js b/lib/symbols.js index 22446a80b..24cbe786e 100644 --- a/lib/symbols.js +++ b/lib/symbols.js @@ -24,6 +24,7 @@ const stringifiersSym = Symbol('pino.stringifiers') const endSym = Symbol('pino.end') const formatOptsSym = Symbol('pino.formatOpts') const messageKeySym = Symbol('pino.messageKey') +const objectKeySym = Symbol('pino.objectKey') const wildcardFirstSym = Symbol('pino.wildcardFirst') @@ -54,6 +55,7 @@ module.exports = { endSym, formatOptsSym, messageKeySym, + objectKeySym, wildcardFirstSym, changeLevelNameSym, wildcardGsym, diff --git a/lib/tools.js b/lib/tools.js index 586c84d14..bc68c3045 100644 --- a/lib/tools.js +++ b/lib/tools.js @@ -20,7 +20,8 @@ const { needsMetadataGsym, wildcardGsym, redactFmtSym, - streamSym + streamSym, + objectKeySym } = require('./symbols') function noop () {} @@ -33,6 +34,7 @@ function genLog (z) { } else if (typeof o.setHeader === 'function') { o = mapHttpResponse(o) } + if (this[objectKeySym]) o = { [this[objectKeySym]]: o } this[writeSym](o, format(null, n, this[formatOptsSym]), z) } else this[writeSym](null, format(o, n, this[formatOptsSym]), z) } diff --git a/package.json b/package.json index bf030ecb3..af8166663 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pino", - "version": "5.15.0", + "version": "5.16.0", "description": "super fast, all natural json logger", "main": "pino.js", "browser": "./browser.js", diff --git a/pino.js b/pino.js index 9a6aeb32f..91a78aa44 100644 --- a/pino.js +++ b/pino.js @@ -27,6 +27,7 @@ const { endSym, formatOptsSym, messageKeySym, + objectKeySym, useLevelLabelsSym, changeLevelNameSym, mixinSym, @@ -40,6 +41,7 @@ const defaultOptions = { level: 'info', useLevelLabels: false, messageKey: 'msg', + objectKey: null, enabled: true, prettyPrint: false, base: { pid, hostname }, @@ -66,6 +68,7 @@ function pino (...args) { serializers, timestamp, messageKey, + objectKey, base, name, level, @@ -112,6 +115,7 @@ function pino (...args) { [endSym]: end, [formatOptsSym]: formatOpts, [messageKeySym]: messageKey, + [objectKeySym]: objectKey, [serializersSym]: serializers, [mixinSym]: mixin, [chindingsSym]: chindings diff --git a/test/basic.test.js b/test/basic.test.js index fbb1c96cb..5610c78e0 100644 --- a/test/basic.test.js +++ b/test/basic.test.js @@ -286,6 +286,26 @@ test('set the messageKey', async ({ is, same }) => { }) }) +test('set the objectKey', async ({ is, same }) => { + const stream = sink() + const object = { hello: 'world' } + const objectKey = 'stuff' + const instance = pino({ + objectKey + }, stream) + instance.info(object) + const result = await once(stream, 'data') + is(new Date(result.time) <= new Date(), true, 'time is greater than Date.now()') + delete result.time + same(result, { + pid: pid, + hostname: hostname, + level: 30, + stuff: object, + v: 1 + }) +}) + test('set undefined properties', async ({ is, same }) => { const stream = sink() const instance = pino(stream) From 607662552ef8eb03c8871711b77113250aea9149 Mon Sep 17 00:00:00 2001 From: Matthew Adams Date: Tue, 7 Jan 2020 09:14:58 -0600 Subject: [PATCH 2/4] revert minor version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index af8166663..bf030ecb3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pino", - "version": "5.16.0", + "version": "5.15.0", "description": "super fast, all natural json logger", "main": "pino.js", "browser": "./browser.js", From 5d35a08d8665d77468d3f4233bffbcf008ce0f78 Mon Sep 17 00:00:00 2001 From: Matthew Adams Date: Tue, 7 Jan 2020 11:06:14 -0600 Subject: [PATCH 3/4] objectKey -> nestedKey, no "you" in docs --- docs/api.md | 18 +++++++++--------- lib/symbols.js | 4 ++-- lib/tools.js | 4 ++-- pino.js | 8 ++++---- test/basic.test.js | 6 +++--- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/docs/api.md b/docs/api.md index 2c6f45da9..df7ee6c20 100644 --- a/docs/api.md +++ b/docs/api.md @@ -201,21 +201,21 @@ Default: `'msg'` The string key for the 'message' in the JSON object. - -#### `objectKey` (String) + +#### `nestedKey` (String) Default: `null` -If there's a chance that objects that you're logging have properties that conflict with those from pino itself (`level`, `timestamp`, `v`, `pid`, etc) -and you don't want duplicate keys in your log records, you can set an `objectKey` option that causes any `object`s that are logged -to be placed under a key whose name is the value of `objectKey`. +If there's a chance that objects being logged have properties that conflict with those from pino itself (`level`, `timestamp`, `v`, `pid`, etc) +and duplicate keys in your log records are undesirable, pino can be configured with an `nestedKey` option that causes any `object`s that are logged +to be placed under a key whose name is the value of `nestedKey`. -This way, when you're doing something like searching Kibana for values, you can consistently search under the configured `objectKey` value instead of the root log record keys. +This way, when searching something like Kibana for values, one can consistently search under the configured `nestedKey` value instead of the root log record keys. For example, ```js const logger = require('pino')({ - objectKey: 'payload' + nestedKey: 'payload' }) const thing = { level: 'hi', timestamp: 'never', foo: 'bar'} // has pino-conflicting properties! @@ -224,8 +224,8 @@ logger.info(thing) // logs the following: // {"level":30,"time":1578357790020,"pid":91736,"hostname":"x","payload":{"level":"hi","timestamp":"never","foo":"bar"},"v":1} ``` -In this way, you never have to worry that one of your logged objects' properties conflicts with pino's standard logging properties, -and you always know which key to start searching from when you're looking for logged objects. +In this way, logged objects' properties don't conflict with pino's standard logging properties, +and searching for logged objects can start from a consistent path. #### `prettyPrint` (Boolean | Object) diff --git a/lib/symbols.js b/lib/symbols.js index 24cbe786e..9e27d7c35 100644 --- a/lib/symbols.js +++ b/lib/symbols.js @@ -24,7 +24,7 @@ const stringifiersSym = Symbol('pino.stringifiers') const endSym = Symbol('pino.end') const formatOptsSym = Symbol('pino.formatOpts') const messageKeySym = Symbol('pino.messageKey') -const objectKeySym = Symbol('pino.objectKey') +const nestedKeySym = Symbol('pino.nestedKey') const wildcardFirstSym = Symbol('pino.wildcardFirst') @@ -55,7 +55,7 @@ module.exports = { endSym, formatOptsSym, messageKeySym, - objectKeySym, + nestedKeySym, wildcardFirstSym, changeLevelNameSym, wildcardGsym, diff --git a/lib/tools.js b/lib/tools.js index bc68c3045..c5dd17f15 100644 --- a/lib/tools.js +++ b/lib/tools.js @@ -21,7 +21,7 @@ const { wildcardGsym, redactFmtSym, streamSym, - objectKeySym + nestedKeySym } = require('./symbols') function noop () {} @@ -34,7 +34,7 @@ function genLog (z) { } else if (typeof o.setHeader === 'function') { o = mapHttpResponse(o) } - if (this[objectKeySym]) o = { [this[objectKeySym]]: o } + if (this[nestedKeySym]) o = { [this[nestedKeySym]]: o } this[writeSym](o, format(null, n, this[formatOptsSym]), z) } else this[writeSym](null, format(o, n, this[formatOptsSym]), z) } diff --git a/pino.js b/pino.js index 91a78aa44..70c94bd71 100644 --- a/pino.js +++ b/pino.js @@ -27,7 +27,7 @@ const { endSym, formatOptsSym, messageKeySym, - objectKeySym, + nestedKeySym, useLevelLabelsSym, changeLevelNameSym, mixinSym, @@ -41,7 +41,7 @@ const defaultOptions = { level: 'info', useLevelLabels: false, messageKey: 'msg', - objectKey: null, + nestedKey: null, enabled: true, prettyPrint: false, base: { pid, hostname }, @@ -68,7 +68,7 @@ function pino (...args) { serializers, timestamp, messageKey, - objectKey, + nestedKey, base, name, level, @@ -115,7 +115,7 @@ function pino (...args) { [endSym]: end, [formatOptsSym]: formatOpts, [messageKeySym]: messageKey, - [objectKeySym]: objectKey, + [nestedKeySym]: nestedKey, [serializersSym]: serializers, [mixinSym]: mixin, [chindingsSym]: chindings diff --git a/test/basic.test.js b/test/basic.test.js index 5610c78e0..eeb91b6ae 100644 --- a/test/basic.test.js +++ b/test/basic.test.js @@ -286,12 +286,12 @@ test('set the messageKey', async ({ is, same }) => { }) }) -test('set the objectKey', async ({ is, same }) => { +test('set the nestedKey', async ({ is, same }) => { const stream = sink() const object = { hello: 'world' } - const objectKey = 'stuff' + const nestedKey = 'stuff' const instance = pino({ - objectKey + nestedKey }, stream) instance.info(object) const result = await once(stream, 'data') From 6d80dbf8cd9bb8632de783a1d3565f4fe307e184 Mon Sep 17 00:00:00 2001 From: Matthew Adams Date: Tue, 7 Jan 2020 13:42:09 -0600 Subject: [PATCH 4/4] fix typos --- docs/api.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api.md b/docs/api.md index df7ee6c20..f4cfd0baa 100644 --- a/docs/api.md +++ b/docs/api.md @@ -207,7 +207,7 @@ The string key for the 'message' in the JSON object. Default: `null` If there's a chance that objects being logged have properties that conflict with those from pino itself (`level`, `timestamp`, `v`, `pid`, etc) -and duplicate keys in your log records are undesirable, pino can be configured with an `nestedKey` option that causes any `object`s that are logged +and duplicate keys in your log records are undesirable, pino can be configured with a `nestedKey` option that causes any `object`s that are logged to be placed under a key whose name is the value of `nestedKey`. This way, when searching something like Kibana for values, one can consistently search under the configured `nestedKey` value instead of the root log record keys. @@ -218,11 +218,11 @@ const logger = require('pino')({ nestedKey: 'payload' }) -const thing = { level: 'hi', timestamp: 'never', foo: 'bar'} // has pino-conflicting properties! +const thing = { level: 'hi', time: 'never', foo: 'bar'} // has pino-conflicting properties! logger.info(thing) // logs the following: -// {"level":30,"time":1578357790020,"pid":91736,"hostname":"x","payload":{"level":"hi","timestamp":"never","foo":"bar"},"v":1} +// {"level":30,"time":1578357790020,"pid":91736,"hostname":"x","payload":{"level":"hi","time":"never","foo":"bar"},"v":1} ``` In this way, logged objects' properties don't conflict with pino's standard logging properties, and searching for logged objects can start from a consistent path.