diff --git a/docs/api.md b/docs/api.md
index 7c2a78405..8e0004c39 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -507,6 +507,19 @@ when using the `transport` option. In this case an `Error` will be thrown.
* See [pino.transport()](#pino-transport)
+#### `onChild` (Function)
+
+The `onChild` function is a synchronous callback that will be called on each creation of a new child, passing the child instance as its first argument.
+Any error thrown inside the callback will be uncaught and should be handled inside the callback.
+```js
+const parent = require('pino')({ onChild: (instance) => {
+ // Exceute call back code for each newly created child.
+}})
+// `onChild` will now be executed with the new child.
+parent.child(bindings)
+```
+
+
### `destination` (SonicBoom | WritableStream | String | Object)
diff --git a/lib/proto.js b/lib/proto.js
index 25c0c5b99..400945282 100644
--- a/lib/proto.js
+++ b/lib/proto.js
@@ -141,7 +141,7 @@ function child (bindings, options) {
instance[chindingsSym] = asChindings(instance, bindings)
const childLevel = options.level || this.level
instance[setLevelSym](childLevel)
-
+ this.onChild(instance)
return instance
}
diff --git a/lib/tools.js b/lib/tools.js
index 3ac99c739..674198b43 100644
--- a/lib/tools.js
+++ b/lib/tools.js
@@ -298,8 +298,9 @@ function createArgsNormalizer (defaultOptions) {
throw new Error('prettyPrint option is no longer supported, see the pino-pretty package (https://github.com/pinojs/pino-pretty)')
}
- const { enabled } = opts
+ const { enabled, onChild } = opts
if (enabled === false) opts.level = 'silent'
+ if (!onChild) opts.onChild = noop
if (!stream) {
if (!hasBeenTampered(process.stdout)) {
// If process.stdout.fd is undefined, it means that we are running
diff --git a/pino.d.ts b/pino.d.ts
index 6ad74ba38..8e7fe6ea9 100644
--- a/pino.d.ts
+++ b/pino.d.ts
@@ -36,6 +36,12 @@ type MixinMergeStrategyFn = (mergeObject: object, mixinObject: object) => object
type CustomLevelLogger = Options extends { customLevels: Record } ? Record : Record
+/**
+* A synchronous callback that will run on each creation of a new child.
+* @param child: The newly created child logger instance.
+*/
+type OnChildCallback = (child: pino.Logger) => void
+
interface redactOptions {
paths: string[];
censor?: string | ((value: any, path: string[]) => any);
@@ -79,6 +85,11 @@ interface LoggerExtras extends EventEmitter {
*/
child(bindings: pino.Bindings, options?: ChildOptions): pino.Logger;
+ /**
+ * This can be used to modify the callback function on creation of a new child.
+ */
+ onChild: OnChildCallback;
+
/**
* Registers a listener function that is triggered when the level is changed.
* Note: When browserified, this functionality will only be available if the `events` module has been required elsewhere
@@ -601,6 +612,11 @@ declare namespace pino {
* Stringification limit of properties/elements when logging a specific object/array with circular references. Default: `100`.
*/
edgeLimit?: number
+
+ /**
+ * Optional child creation callback.
+ */
+ onChild?: OnChildCallback;
}
interface ChildLoggerOptions {
diff --git a/pino.js b/pino.js
index 9ace3a71d..934eb7476 100644
--- a/pino.js
+++ b/pino.js
@@ -102,7 +102,8 @@ function pino (...args) {
formatters,
hooks,
depthLimit,
- edgeLimit
+ edgeLimit,
+ onChild
} = opts
const stringifySafe = configure({
@@ -175,7 +176,8 @@ function pino (...args) {
[chindingsSym]: chindings,
[formattersSym]: allFormatters,
[hooksSym]: hooks,
- silent: noop
+ silent: noop,
+ onChild
})
Object.setPrototypeOf(instance, proto())
diff --git a/test/basic.test.js b/test/basic.test.js
index 2f9700f0d..ca4ca1e97 100644
--- a/test/basic.test.js
+++ b/test/basic.test.js
@@ -725,3 +725,13 @@ test('throws if prettyPrint is passed in as an option', async (t) => {
})
}, new Error('prettyPrint option is no longer supported, see the pino-pretty package (https://github.com/pinojs/pino-pretty)'))
})
+
+test('Should invoke `onChild` with the newly created child', async ({ equal }) => {
+ let innerChild
+ const child = pino({
+ onChild: (instance) => {
+ innerChild = instance
+ }
+ }).child({ foo: 'bar' })
+ equal(child, innerChild)
+})
diff --git a/test/types/pino.test-d.ts b/test/types/pino.test-d.ts
index b2a6515ba..57b8ca43c 100644
--- a/test/types/pino.test-d.ts
+++ b/test/types/pino.test-d.ts
@@ -340,3 +340,8 @@ cclog3.myLevel('')
cclog3.childLevel('')
// child itself
cclog3.childLevel2('')
+
+const withChildCallback = pino({
+ onChild: (child: Logger) => {}
+})
+withChildCallback.onChild = (child: Logger) => {}
\ No newline at end of file