Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support new nestedKey config to avoid property name collisions with pino standard properties when logging objects #759

Merged
merged 4 commits into from
Jan 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,32 @@ Default: `'msg'`

The string key for the 'message' in the JSON object.

<a id=opt-nestedkey></a>
#### `nestedKey` (String)

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 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.

For example,
```js
const logger = require('pino')({
nestedKey: 'payload'
})

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","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.

<a id=prettyPrint></a>
#### `prettyPrint` (Boolean | Object)

Expand Down
2 changes: 2 additions & 0 deletions lib/symbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 nestedKeySym = Symbol('pino.nestedKey')

const wildcardFirstSym = Symbol('pino.wildcardFirst')

Expand Down Expand Up @@ -54,6 +55,7 @@ module.exports = {
endSym,
formatOptsSym,
messageKeySym,
nestedKeySym,
wildcardFirstSym,
changeLevelNameSym,
wildcardGsym,
Expand Down
4 changes: 3 additions & 1 deletion lib/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ const {
needsMetadataGsym,
wildcardGsym,
redactFmtSym,
streamSym
streamSym,
nestedKeySym
} = require('./symbols')

function noop () {}
Expand All @@ -33,6 +34,7 @@ function genLog (z) {
} else if (typeof o.setHeader === 'function') {
o = mapHttpResponse(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)
}
Expand Down
4 changes: 4 additions & 0 deletions pino.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const {
endSym,
formatOptsSym,
messageKeySym,
nestedKeySym,
useLevelLabelsSym,
changeLevelNameSym,
mixinSym,
Expand All @@ -40,6 +41,7 @@ const defaultOptions = {
level: 'info',
useLevelLabels: false,
messageKey: 'msg',
nestedKey: null,
enabled: true,
prettyPrint: false,
base: { pid, hostname },
Expand All @@ -66,6 +68,7 @@ function pino (...args) {
serializers,
timestamp,
messageKey,
nestedKey,
base,
name,
level,
Expand Down Expand Up @@ -112,6 +115,7 @@ function pino (...args) {
[endSym]: end,
[formatOptsSym]: formatOpts,
[messageKeySym]: messageKey,
[nestedKeySym]: nestedKey,
[serializersSym]: serializers,
[mixinSym]: mixin,
[chindingsSym]: chindings
Expand Down
20 changes: 20 additions & 0 deletions test/basic.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,26 @@ test('set the messageKey', async ({ is, same }) => {
})
})

test('set the nestedKey', async ({ is, same }) => {
const stream = sink()
const object = { hello: 'world' }
const nestedKey = 'stuff'
const instance = pino({
nestedKey
}, 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)
Expand Down