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

feat: add errorKey option #1507

Merged
merged 2 commits into from
Aug 4, 2022
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
16 changes: 15 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ matching the exact key of a serializer will be serialized using the defined seri
The serializers are applied when a property in the logged object matches a property
in the serializers. The only exception is the `err` serializer as it is also applied in case
the object is an instance of `Error`, e.g. `logger.info(new Error('kaboom'))`.
See `errorKey` option to change `err` namespace.

* See [pino.stdSerializers](#pino-stdserializers)

Expand Down Expand Up @@ -434,6 +435,13 @@ Default: `'msg'`

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

<a id=opt-messagekey></a>
#### `errorKey` (String)

Default: `'err'`

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

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

Expand Down Expand Up @@ -603,6 +611,9 @@ logger.info({MIX: {IN: true}})
If the object is of type Error, it is wrapped in an object containing a property err (`{ err: mergingObject }`).
This allows for a unified error handling flow.

Options `serializers` and `errorKey` could be used at instantiation time to change the namespace
from `err` to another string as preferred.

<a id="message"></a>
#### `message` (String)

Expand All @@ -625,7 +636,7 @@ See [Avoid Message Conflict](/docs/help.md#avoid-message-conflict) for informati
on how to overcome this limitation.

If no `message` parameter is provided, and the `mergingObject` is of type `Error` or it has a property named `err`, the
`message` parameter is set to the `message` value of the error.
`message` parameter is set to the `message` value of the error. See option `errorKey` if you want to change the namespace.

The `messageKey` option can be used at instantiation time to change the namespace
from `msg` to another string as preferred.
Expand Down Expand Up @@ -689,6 +700,9 @@ const logger = pino(pinoOptions)

Errors can be supplied as either the first parameter or if already using `mergingObject` then as the `err` property on the `mergingObject`.

Options `serializers` and `errorKey` could be used at instantiation time to change the namespace
from `err` to another string as preferred.

> ## Note
> This section describes the default configuration. The error serializer can be
> mapped to a different key using the [`serializers`](#opt-serializers) option.
Expand Down
8 changes: 5 additions & 3 deletions lib/proto.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ const {
streamSym,
serializersSym,
formattersSym,
errorKeySym,
useOnlyCustomLevelsSym,
needsMetadataGsym,
redactFmtSym,
Expand Down Expand Up @@ -174,20 +175,21 @@ function defaultMixinMergeStrategy (mergeObject, mixinObject) {
function write (_obj, msg, num) {
const t = this[timeSym]()
const mixin = this[mixinSym]
const errorKey = this[errorKeySym]
const mixinMergeStrategy = this[mixinMergeStrategySym] || defaultMixinMergeStrategy
let obj

if (_obj === undefined || _obj === null) {
obj = {}
} else if (_obj instanceof Error) {
obj = { err: _obj }
obj = { [errorKey]: _obj }
if (msg === undefined) {
msg = _obj.message
}
} else {
obj = _obj
if (msg === undefined && _obj.err) {
msg = _obj.err.message
if (msg === undefined && _obj[errorKey]) {
msg = _obj[errorKey].message
}
}

Expand Down
2 changes: 2 additions & 0 deletions lib/symbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const stringifiersSym = Symbol('pino.stringifiers')
const endSym = Symbol('pino.end')
const formatOptsSym = Symbol('pino.formatOpts')
const messageKeySym = Symbol('pino.messageKey')
const errorKeySym = Symbol('pino.errorKey')
const nestedKeySym = Symbol('pino.nestedKey')
const nestedKeyStrSym = Symbol('pino.nestedKeyStr')
const mixinMergeStrategySym = Symbol('pino.mixinMergeStrategy')
Expand Down Expand Up @@ -57,6 +58,7 @@ module.exports = {
endSym,
formatOptsSym,
messageKeySym,
errorKeySym,
nestedKeySym,
wildcardFirstSym,
needsMetadataGsym,
Expand Down
5 changes: 5 additions & 0 deletions pino.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,10 @@ declare namespace pino {
* The string key for the 'message' in the JSON object. Default: "msg".
*/
messageKey?: string;
/**
* The string key for the 'error' in the JSON object. Default: "err".
*/
errorKey?: string;
/**
* The string key to place any logged object under.
*/
Expand Down Expand Up @@ -682,6 +686,7 @@ declare namespace pino {
readonly endSym: unique symbol;
readonly formatOptsSym: unique symbol;
readonly messageKeySym: unique symbol;
readonly errorKeySym: unique symbol;
readonly nestedKeySym: unique symbol;
readonly wildcardFirstSym: unique symbol;
readonly needsMetadataGsym: unique symbol;
Expand Down
4 changes: 4 additions & 0 deletions pino.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const {
endSym,
formatOptsSym,
messageKeySym,
errorKeySym,
nestedKeySym,
mixinSym,
useOnlyCustomLevelsSym,
Expand All @@ -49,6 +50,7 @@ const defaultOptions = {
level: 'info',
levels,
messageKey: 'msg',
errorKey: 'err',
nestedKey: null,
enabled: true,
base: { pid, hostname },
Expand Down Expand Up @@ -88,6 +90,7 @@ function pino (...args) {
serializers,
timestamp,
messageKey,
errorKey,
nestedKey,
base,
name,
Expand Down Expand Up @@ -162,6 +165,7 @@ function pino (...args) {
[endSym]: end,
[formatOptsSym]: formatOpts,
[messageKeySym]: messageKey,
[errorKeySym]: errorKey,
[nestedKeySym]: nestedKey,
// protect against injection
[nestedKeyStrSym]: nestedKey ? `,${JSON.stringify(nestedKey)}:{` : '',
Expand Down
20 changes: 20 additions & 0 deletions test/errorKey.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict'
const { test } = require('tap')
const { sink, once } = require('./helper')
const stdSerializers = require('pino-std-serializers')
const pino = require('../')

test('set the errorKey with error serializer', async ({ equal, same }) => {
const stream = sink()
const errorKey = 'error'
const instance = pino({
errorKey,
serializers: { [errorKey]: stdSerializers.err }
}, stream)
instance.error(new ReferenceError('test'))
const o = await once(stream, 'data')
equal(typeof o[errorKey], 'object')
equal(o[errorKey].type, 'ReferenceError')
equal(o[errorKey].message, 'test')
equal(typeof o[errorKey].stack, 'string')
})
9 changes: 3 additions & 6 deletions test/transport/core.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -395,12 +395,9 @@ test('stdout in worker', async ({ not }) => {
let actual = ''
const child = execa(process.argv[0], [join(__dirname, '..', 'fixtures', 'transport-main.js')])

child.stdout.pipe(writer((s, enc, cb) => {
actual += s
cb()
}))
await once(child, 'close')
await immediate()
for await (const chunk of child.stdout) {
actual += chunk
}
not(strip(actual).match(/Hello/), null)
})

Expand Down