Skip to content

Commit

Permalink
feat: pass logger/child logger as param to mixin
Browse files Browse the repository at this point in the history
Passing the logger or child logger as a parameter to `mixin` allows
users to set logger-specific context in the logger object that can be
used by `mixin` to enrich the context to be added to the resulting JSON.

One example use case for this is avoiding the "duplicate keys" caveat
that comes with child loggers. If the user wants to make a known key
"mergeable", they could add a custom function that concatenates values
to the key and then use `mixin` to pass that merged value to the
context. For example:

```js
instance = pino({
  mixin(obj, num, logger) {
    return {
      "tags": logger.tags
    }
  }
})
instance.tags = {}

instance.addTag = function (key, value) {
  child.tags[key] = value
}

function createChild (logger, ...context) {
  const child = logger.child(...context)
  child.tags = { ...logger.tags }
  child.addTag = function (key, value) {
    child.tags[key] = value
  }
  return child
}

instance.addTag('foo', 1)
child.addTag('bar', 2)
instance.info('this will only have `foo: 1`')
child.info('this will have both `foo: 1` and `bar: 2`')
```
  • Loading branch information
mmarchini committed May 4, 2023
1 parent 27d2ab8 commit 59d2aed
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/proto.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ function write (_obj, msg, num) {
}

if (mixin) {
obj = mixinMergeStrategy(obj, mixin(obj, num))
obj = mixinMergeStrategy(obj, mixin(obj, num, this))
}

const s = this[asJsonSym](obj, msg, num, t)
Expand Down
56 changes: 56 additions & 0 deletions test/mixin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,59 @@ test('mixin can use level number', async ({ ok, same }) => {
stack: 'stack'
}, 'test')
})

test('mixin receives logger as third parameter', async ({ ok, same }) => {
const stream = sink()
const instance = pino({
mixin (context, num, logger) {
ok(logger !== null, 'logger should be defined')
ok(logger !== undefined, 'logger should be defined')
same(logger, instance)
return { ...context, num }
}
}, stream)
instance.level = name
instance[name]({
message: '123'
}, 'test')
})

test('mixin receives child logger', async ({ ok, same }) => {
const stream = sink()
let child = null
const instance = pino({
mixin (context, num, logger) {
ok(logger !== null, 'logger should be defined')
ok(logger !== undefined, 'logger should be defined')
same(logger.expected, child.expected)
return { ...context, num }
}
}, stream)
instance.level = name
instance.expected = false
child = instance.child({})
child.expected = true
child[name]({
message: '123'
}, 'test')
})

test('mixin receives logger even if child exists', async ({ ok, same }) => {
const stream = sink()
let child = null
const instance = pino({
mixin (context, num, logger) {
ok(logger !== null, 'logger should be defined')
ok(logger !== undefined, 'logger should be defined')
same(logger.expected, instance.expected)
return { ...context, num }
}
}, stream)
instance.level = name
instance.expected = false
child = instance.child({})
child.expected = true
instance[name]({
message: '123'
}, 'test')
})

0 comments on commit 59d2aed

Please sign in to comment.