diff --git a/README.md b/README.md index 605953d2..a3c437e1 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,13 @@ export class MyService { private readonly logger: PinoLogger ) {} + constructor( + // If InjectPinoLogger is used without argument, it will attempt to deduce context + // using INQUIRER injection https://github.com/nestjs/docs.nestjs.com/issues/937 + @InjectPinoLogger() + private readonly logger: PinoLogger + ) {} + foo() { // PinoLogger has same methods as pino instance this.logger.trace({ foo: 'bar' }, 'baz %s', 'qux'); diff --git a/__tests__/no-context.spec.ts b/__tests__/no-context.spec.ts index fae02225..991922cd 100644 --- a/__tests__/no-context.spec.ts +++ b/__tests__/no-context.spec.ts @@ -55,7 +55,7 @@ describe('no context', () => { const ctrlLog = logs.find((v) => v.msg === msg); expect(ctrlLog).toBeTruthy(); - expect(ctrlLog).not.toHaveProperty('context'); + expect(ctrlLog?.context).toEqual(TestController.name); }); }); } diff --git a/__tests__/utils/test-case.ts b/__tests__/utils/test-case.ts index f3ebf538..6d8e1938 100644 --- a/__tests__/utils/test-case.ts +++ b/__tests__/utils/test-case.ts @@ -83,6 +83,7 @@ export class TestCase { __resetSingletons(); const app = await NestFactory.create(this.module, this.adapter, { + abortOnError: false, bufferLogs: true, }); app.useLogger(app.get(Logger)); diff --git a/src/InjectPinoLogger.ts b/src/InjectPinoLogger.ts index 94bd7767..6a40e3bf 100644 --- a/src/InjectPinoLogger.ts +++ b/src/InjectPinoLogger.ts @@ -1,9 +1,11 @@ -import { Inject, Provider } from '@nestjs/common'; +import { Inject, Provider, Scope } from '@nestjs/common'; +import { INQUIRER } from '@nestjs/core'; import { PinoLogger } from './PinoLogger'; const decoratedTokenPrefix = 'PinoLogger:'; const decoratedLoggers = new Set(); +const transientToken = getLoggerToken(''); export function InjectPinoLogger(context = '') { decoratedLoggers.add(context); @@ -11,6 +13,24 @@ export function InjectPinoLogger(context = '') { } function createDecoratedLoggerProvider(context: string): Provider { + if (context === '') { + return { + provide: transientToken, + useFactory: (logger: PinoLogger, inquirer: any) => { + if (!inquirer) { + return logger; + } + if (typeof inquirer === 'string') { + logger.setContext(inquirer); + } else if (typeof inquirer === 'object') { + logger.setContext(inquirer.constructor.name); + } + return logger; + }, + inject: [PinoLogger, INQUIRER], + scope: Scope.TRANSIENT, + }; + } return { provide: getLoggerToken(context), useFactory: (logger: PinoLogger) => {