0

I have a web application on Nest.js where I make use of pino to log exceptions .

Service1.ts

import {Logger} from 'nestjs-pino';

export class Service1{
constructor(private readonly logger : Logger) {}

async Do()
{

...
 this.logger.log("Log1");
}
}

Service2.ts

import {Logger} from 'nestjs-pino';

export class Service2{
constructor(private readonly logger : Logger) {}

async DoOtherWork()
{

...
 this.logger.log("Log1");
}
}

Since the Service files will be called from multiple UI operations so my understanding is multiple Logger classes will be created . So , is it a good idea to have Logger as a Singleton class ?

How can I make changes to the Nest.js application to have Logger as a singleton class with thread safety?

1
  • Yes you can use middleware concept of nestjs and create a logger middleware Commented Mar 19 at 4:48

1 Answer 1

0

In NestJS, the Logger from nestjs-pino is already designed to be a singleton when injected properly as a provider. If you directly instantiate it in the service, it won't be a singleton.

If you do:

import { Module } from '@nestjs/common';
import { LoggerModule } from 'nestjs-pino';

@Module({
  imports: [
    LoggerModule.forRoot({
      pinoHttp: {
        level: 'info', 
      },
    }),
  ],
  exports: [LoggerModule], 
})
export class AppModule {}

and service1

import { Injectable } from '@nestjs/common';
import { Logger } from 'nestjs-pino';

@Injectable()
export class Service1 {
  constructor(private readonly logger: Logger) {}

  async Do() {
    this.logger.log('Log1');
  }
}

and service2

import { Injectable } from '@nestjs/common';
import { Logger } from 'nestjs-pino';

@Injectable()
export class Service2 {
  constructor(private readonly logger: Logger) {}

  async DoOtherWork() {
    this.logger.info('Log2');
  }
}

and have a module like this:

import { Module } from '@nestjs/common';
import { Service1 } from './service1';
import { Service2 } from './service2';

@Module({
  providers: [Service1, Service2],
  exports: [Service1, Service2],
})
export class SomeModule {}

The same Logger instance will be injected into Service1 and Service2.

What i think you are interested is set the context for the service, the nestjs-pino documentation mentions that:

export class MyService {
  constructor(
    private readonly logger: PinoLogger
  ) {
    // Optionally you can set context for logger in constructor or ...
    this.logger.setContext(MyService.name);
  }

  constructor(
    // ... set context via special decorator
    @InjectPinoLogger(MyService.name)
    private readonly logger: PinoLogger
  ) {}

  foo() {
    // PinoLogger has same methods as pino instance
    this.logger.trace({ foo: 'bar' }, 'baz %s', 'qux');
    this.logger.debug('foo %s %o', 'bar', { baz: 'qux' });
    this.logger.info('foo');
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.