Repository: pinojs/pino
Pull request #1364 (2022-03-09 15:20:42)

feat: add level number to mixin callback

techmunk: @mcollina Those failed checks don't seem related. Can they be ignored? It doesn't seem like this patch could cause the reported problem.
techmunk: Force push to change commit author details

Patch:
diff --git a/docs/api.md b/docs/api.md
index 0c27d08..e10d253 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -119,8 +119,8 @@ Option to limit stringification of properties/elements when logging a specific o
 Default: `undefined`
 
 If provided, the `mixin` function is called each time one of the active
-logging methods is called. The first and only parameter is the value `mergeObject` or an empty object. The function must synchronously return an
-object. The properties of the returned object will be added to the
+logging methods is called. The first parameter is the value `mergeObject` or an empty object. The second parameter is the leg level number.
+The function must synchronously return an object. The properties of the returned object will be added to the
 logged JSON.
 
 ```js
@@ -153,12 +153,28 @@ const logger = pino({
 logger.info({
     description: 'Ok'
 }, 'Message 1')
-// {"level":30,"time":1591195061437,"pid":16012,"hostname":"x","appName":"My app","description":"Ok" "msg":"Message 1"}
+// {"level":30,"time":1591195061437,"pid":16012,"hostname":"x","appName":"My app","description":"Ok","msg":"Message 1"}
 logger.info('Message 2')
 // {"level":30,"time":1591195061437,"pid":16012,"hostname":"x","appName":"My app","description":"Ok","msg":"Message 2"}
 // Note: the second log contains "description":"Ok" text, even if it was not provided.
 ```
 
+The `mixin` method can be used to add the level label to each log message such as in the following example:
+```js
+const logger = pino({
+  mixin(_context, level) {
+    return { 'level-label': logger.levels.labels[level] }
+  }
+})
+
+logger.info({
+    description: 'Ok'
+}, 'Message 1')
+// {"level":30,"time":1591195061437,"pid":16012,"hostname":"x","appName":"My app","description":"Ok","level-label":"info","msg":"Message 1"}
+logger.error('Message 2')
+// {"level":30,"time":1591195061437,"pid":16012,"hostname":"x","appName":"My app","description":"Ok","level-label":"error","msg":"Message 2"}
+```
+
 If the `mixin` feature is being used merely to add static metadata to each log message,
 then a [child logger ⇗](/docs/child-loggers.md) should be used instead.
 
diff --git a/lib/proto.js b/lib/proto.js
index f51e5d7..abbeef8 100644
--- a/lib/proto.js
+++ b/lib/proto.js
@@ -192,7 +192,7 @@ function write (_obj, msg, num) {
   }
 
   if (mixin) {
-    obj = mixinMergeStrategy(obj, mixin(obj))
+    obj = mixinMergeStrategy(obj, mixin(obj, num))
   }
 
   const s = this[asJsonSym](obj, msg, num, t)
diff --git a/pino.d.ts b/pino.d.ts
index b1be386..2f2431b 100644
--- a/pino.d.ts
+++ b/pino.d.ts
@@ -31,7 +31,7 @@ import type { WorkerOptions } from "worker_threads";
 type ThreadStream = any
 
 type TimeFn = () => string;
-type MixinFn = (mergeObject: object) => object;
+type MixinFn = (mergeObject: object, level: number) => object;
 type MixinMergeStrategyFn = (mergeObject: object, mixinObject: object) => object;
 
 type CustomLevelLogger<Options> = Options extends { customLevels: Record<string, number> } ? Record<keyof Options["customLevels"], LogFn> : Record<never, LogFn>


Test patch:
diff --git a/test/mixin.test.js b/test/mixin.test.js
index cac37e9..86b1622 100644
--- a/test/mixin.test.js
+++ b/test/mixin.test.js
@@ -140,3 +140,23 @@ test('mixin works without context', async ({ ok, same }) => {
   instance.level = name
   instance[name]('test')
 })
+
+test('mixin can use level number', async ({ ok, same }) => {
+  const stream = sink()
+  const instance = pino({
+    mixin (context, num) {
+      ok(num !== null, 'level should be defined')
+      ok(num !== undefined, 'level should be defined')
+      same(num, level)
+      return Object.assign({
+        error: context.message,
+        stack: context.stack
+      })
+    }
+  }, stream)
+  instance.level = name
+  instance[name]({
+    message: '123',
+    stack: 'stack'
+  }, 'test')
+})
diff --git a/test/types/pino.test-d.ts b/test/types/pino.test-d.ts
index a808903..87e319b 100644
--- a/test/types/pino.test-d.ts
+++ b/test/types/pino.test-d.ts
@@ -47,6 +47,14 @@ pino({
     mixin: () => ({ customName: "unknown", customId: 111 }),
 });
 
+pino({
+    mixin: (context: object) => ({ customName: "unknown", customId: 111 }),
+});
+
+pino({
+    mixin: (context: object, level: number) => ({ customName: "unknown", customId: 111 }),
+});
+
 pino({
     redact: { paths: [], censor: "SECRET" },
 });