Skip to content

Commit

Permalink
feat: keep parent formatters bindings function option
Browse files Browse the repository at this point in the history
  • Loading branch information
dgarrido-orange committed Apr 25, 2024
1 parent 4f8ea32 commit cc20940
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 6 deletions.
21 changes: 20 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,12 +378,31 @@ const hooks = {
<a id=opt-formatters></a>
#### `formatters` (Object)

An object containing functions for formatting the shape of the log lines.
An object containing an `options` object and functions for formatting
the shape of the log lines.
These functions should return a JSONifiable object and
should never throw. These functions allow for full customization of
the resulting log lines. For example, they can be used to change
the level key name or to enrich the default metadata.

##### `options`

The formatters `options` object is passed to the child loggers, except if a new formatters `options` object is passed to the `child()` method.

###### `keepParentBindings`

If `true`, child loggers will keep their parent `bindings` formatters function.

If `false` or `undefined`, child loggers will have their `bindings` formatters function reset to a "no-op" formatter function.

```js
const formatters = {
options: {
keepParentBindings: true
}
}
```

##### `level`

Changes the shape of the log level. The default shape is `{ level: number }`.
Expand Down
11 changes: 7 additions & 4 deletions lib/proto.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ module.exports = function () {
return Object.create(prototype)
}

const resetChildingsFormatter = bindings => bindings
const noOpFormatter = bindings => bindings
function child (bindings, options) {
if (!bindings) {
throw Error('missing bindings for child Pino')
Expand Down Expand Up @@ -110,17 +110,20 @@ function child (bindings, options) {
instance[serializersSym][bks] = options.serializers[bks]
}
} else instance[serializersSym] = serializers
const keepParentBindings = typeof formatters.options === 'object' && formatters.options.keepParentBindings
if (options.hasOwnProperty('formatters')) {
const { level, bindings: chindings, log } = options.formatters
const { options: formattersOptions, level, bindings: chindings, log } = options.formatters
instance[formattersSym] = buildFormatters(
formattersOptions || formatters.options,
level || formatters.level,
chindings || resetChildingsFormatter,
chindings || (keepParentBindings ? formatters.bindings || noOpFormatter : noOpFormatter),
log || formatters.log
)
} else {
instance[formattersSym] = buildFormatters(
formatters.options,
formatters.level,
resetChildingsFormatter,
keepParentBindings ? formatters.bindings || noOpFormatter : noOpFormatter,
formatters.log
)
}
Expand Down
3 changes: 2 additions & 1 deletion lib/tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,9 @@ function stringify (obj, stringifySafeFn) {
}
}

function buildFormatters (level, bindings, log) {
function buildFormatters (options, level, bindings, log) {
return {
options,
level,
bindings,
log
Expand Down
1 change: 1 addition & 0 deletions pino.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ function pino (...args) {
})

const allFormatters = buildFormatters(
formatters.options,
formatters.level,
formatters.bindings,
formatters.log
Expand Down
39 changes: 39 additions & 0 deletions test/formatters.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,45 @@ test('Formatters in child logger', async ({ match }) => {
})
})

test('Formatters with keepParentBindings option', async ({ match }) => {
const stream = sink()

const logger = pino({
formatters: {
options: {
keepParentBindings: true
},
bindings (bindings) {
if (bindings.foobar) bindings.foobar = bindings.foobar.toUpperCase()
if (bindings.faz) bindings.faz = bindings.faz.toUpperCase()
if (bindings.foobat) bindings.foobat = bindings.foobat.toUpperCase()
if (bindings.foobaz) bindings.foobaz = bindings.foobaz.toUpperCase()
return bindings
}
}
}, stream)
logger.setBindings({ foobar: 'foobar' })

const child = logger.child({
faz: 'baz',
nested: { object: true }
})
child.setBindings({ foobat: 'foobat' })

const childChild = child.child({ foobaz: 'foobaz' })

const o = once(stream, 'data')
childChild.info({ foo: 'bar', nested: { object: true } }, 'hello world')
match(await o, {
foobar: 'FOOBAR',
faz: 'BAZ',
foobat: 'FOOBAT',
foobaz: 'FOOBAZ',
foo: 'bar',
nested: { object: true }
})
})

test('Formatters without bindings in child logger', async ({ match }) => {
const stream = sink()
const logger = pino({
Expand Down

0 comments on commit cc20940

Please sign in to comment.