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 1 commit
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-objectkey></a>
#### `objectKey` (String)
matthewadams marked this conversation as resolved.
Show resolved Hide resolved

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)
matthewadams marked this conversation as resolved.
Show resolved Hide resolved
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.

<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 objectKeySym = Symbol('pino.objectKey')

const wildcardFirstSym = Symbol('pino.wildcardFirst')

Expand Down Expand Up @@ -54,6 +55,7 @@ module.exports = {
endSym,
formatOptsSym,
messageKeySym,
objectKeySym,
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,
objectKeySym
} = require('./symbols')

function noop () {}
Expand All @@ -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)
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "pino",
"version": "5.15.0",
"version": "5.16.0",
matthewadams marked this conversation as resolved.
Show resolved Hide resolved
"description": "super fast, all natural json logger",
"main": "pino.js",
"browser": "./browser.js",
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,
objectKeySym,
useLevelLabelsSym,
changeLevelNameSym,
mixinSym,
Expand All @@ -40,6 +41,7 @@ const defaultOptions = {
level: 'info',
useLevelLabels: false,
messageKey: 'msg',
objectKey: null,
enabled: true,
prettyPrint: false,
base: { pid, hostname },
Expand All @@ -66,6 +68,7 @@ function pino (...args) {
serializers,
timestamp,
messageKey,
objectKey,
base,
name,
level,
Expand Down Expand Up @@ -112,6 +115,7 @@ function pino (...args) {
[endSym]: end,
[formatOptsSym]: formatOpts,
[messageKeySym]: messageKey,
[objectKeySym]: objectKey,
[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 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)
Expand Down