From 386f46f6fca2faa3a891ac3f2f4e2a4d7eae0d0f Mon Sep 17 00:00:00 2001 From: Tal Efronny Date: Wed, 31 Aug 2022 13:05:11 +0300 Subject: [PATCH 1/5] Added `onChild` callback with tests and documentation --- docs/api.md | 12 ++++++++++++ lib/proto.js | 2 +- lib/tools.js | 3 ++- pino.d.ts | 6 ++++++ pino.js | 6 ++++-- test/basic.test.js | 10 ++++++++++ 6 files changed, 35 insertions(+), 4 deletions(-) diff --git a/docs/api.md b/docs/api.md index 2cf0c6c77..a8b0d5038 100644 --- a/docs/api.md +++ b/docs/api.md @@ -508,6 +508,18 @@ 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 callback that will be called on each creation of a new child and use the child instance as it's first argument. +```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 29bf28107..387eeb117 100644 --- a/lib/tools.js +++ b/lib/tools.js @@ -301,8 +301,9 @@ function createArgsNormalizer (defaultOptions) { if ('onTerminated' in opts) { throw Error('The onTerminated option has been removed, use pino.final instead') } - 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 a977a1c8e..799c6f52d 100644 --- a/pino.d.ts +++ b/pino.d.ts @@ -79,6 +79,12 @@ interface LoggerExtras extends EventEmitter { */ child(bindings: pino.Bindings, options?: ChildOptions): pino.Logger; + /** + * A callback that will run on each creation of a new child. + * @param child: The newly created child logger instance. + */ + onChild(child: pino.Logger): void; + /** * 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 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) +}) From 3a85fcd8c80b2cda61bde84c7d76b92c8df9d88a Mon Sep 17 00:00:00 2001 From: Tal Efronny Date: Wed, 31 Aug 2022 14:30:32 +0300 Subject: [PATCH 2/5] Update `onChild` type to also be in options and added types tests --- pino.d.ts | 16 +++++++++++++--- test/types/pino.test-d.ts | 5 +++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/pino.d.ts b/pino.d.ts index 799c6f52d..89d8fed6a 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 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); @@ -80,10 +86,9 @@ interface LoggerExtras extends EventEmitter { child(bindings: pino.Bindings, options?: ChildOptions): pino.Logger; /** - * A callback that will run on each creation of a new child. - * @param child: The newly created child logger instance. + * This can be used to modify the callback function on creation of a new child. */ - onChild(child: pino.Logger): void; + onChild: OnChildCallback; /** * Registers a listener function that is triggered when the level is changed. @@ -607,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/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 From 5958758e75213033ca9c908728c3514b2534cb4c Mon Sep 17 00:00:00 2001 From: Diabl0269 Date: Wed, 31 Aug 2022 23:49:54 +0300 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: James Sumners --- docs/api.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api.md b/docs/api.md index a8b0d5038..ad21e6a10 100644 --- a/docs/api.md +++ b/docs/api.md @@ -510,7 +510,7 @@ when using the `transport` option. In this case an `Error` will be thrown. #### `onChild` (Function) -The `onChild` function is a callback that will be called on each creation of a new child and use the child instance as it's first argument. +The `onChild` function is a callback that will be called on each creation of a new child, passing the child instance as its first argument. ```js const parent = require('pino')({ onChild: (instance) => { // Exceute call back code for each newly created child. From df31031862bf3a35c7c6b47078084579ad9a662e Mon Sep 17 00:00:00 2001 From: Tal Efronny Date: Thu, 1 Sep 2022 19:29:38 +0300 Subject: [PATCH 4/5] updated documentation --- docs/api.md | 2 +- pino.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api.md b/docs/api.md index 338592996..82e9ce4d7 100644 --- a/docs/api.md +++ b/docs/api.md @@ -509,7 +509,7 @@ when using the `transport` option. In this case an `Error` will be thrown. #### `onChild` (Function) -The `onChild` function is a callback that will be called on each creation of a new child, passing the child instance as its first argument. +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. ```js const parent = require('pino')({ onChild: (instance) => { // Exceute call back code for each newly created child. diff --git a/pino.d.ts b/pino.d.ts index bcc1a3031..8e7fe6ea9 100644 --- a/pino.d.ts +++ b/pino.d.ts @@ -37,7 +37,7 @@ type MixinMergeStrategyFn = (mergeObject: object, mixinObject: object) => object type CustomLevelLogger = Options extends { customLevels: Record } ? Record : Record /** -* A callback that will run on each creation of a new child. +* 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 From 17900b73d47baf476c86b13218f4e42c0b9fc873 Mon Sep 17 00:00:00 2001 From: Diabl0269 Date: Thu, 1 Sep 2022 22:46:08 +0300 Subject: [PATCH 5/5] Updated documentation. Expanded `onChild` documentation to mention the function doesn't handle errors --- docs/api.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/api.md b/docs/api.md index 82e9ce4d7..8e0004c39 100644 --- a/docs/api.md +++ b/docs/api.md @@ -509,7 +509,8 @@ when using the `transport` option. In this case an `Error` will be thrown. #### `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. +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.