Nest: Unable to use the same instance of custom logger for the entire application

Created on 31 Jul 2018  路  4Comments  路  Source: nestjs/nest

The first time I learned about Nest I was really excited. Coming from Symfony/PHP world, it seemed a good way of starting switching to JavaScript. But now, after a few weeks, all the shining things about the DI, services, injections seems to "glue" not very well in Nest.

First it was https://github.com/nestjs/nest/issues/897 and now I'm facing another issue. Take the logger, everyone needs it. So you may end up creating a service, even a module providing MyLogger:

// logger.module.ts
import { Global , Module } from '@nestjs/common';

@Global()
@Module({ })
export class LoggerModule {
  static forRoot(options: LoggerModuleOptions): DynamicModule {
    // This is a dynamic module which accept options and provide a configured
    // instance of MyLogger. Options maybe further manipulated.
  }
}
// mylogger.service.ts
export class MyLogger {
  // Complex options...
  constructor (options: LoggerOptions) { }
}

So far so good you inject MyLogger pretty everywhere and you are happy.

But then you realize that when the application starts, messages from Nest are not logged using MyLogger, of course, but you may change this behavior:

const app = await NestFactory.create(ApplicationModule, {
  logger: new MyLogger(),
});
await app.listen(3000);

... the only problem here is I can't use DI! I can't use the already configure instance of MyLogger, I should pass a fresh new object, duplicating all the options used to build it.

done 馃憦 type question 馃檶

Most helpful comment

The problem is that the first console output (like [NestFactory] Starting Nest application...) appears before even one module is initialized. Thus, we cannot use an instance of a provided logger, because, in fact, it doesn't exist yet.

However, I fully understand your concerns, and therefore in v5.2.0 you'll be able to use the following construction:

const app = await NestFactory.create(ApplicationModule, {
  logger: false,
});
app.useLogger(app.get(LoggerService));
await app.listen(3000);

That will hide initial logs (like x dependencies initialized) but for the rest of them (route mappings, caught exceptions, and so on), Nest will use your custom logger implementation.

All 4 comments

The problem is that the first console output (like [NestFactory] Starting Nest application...) appears before even one module is initialized. Thus, we cannot use an instance of a provided logger, because, in fact, it doesn't exist yet.

However, I fully understand your concerns, and therefore in v5.2.0 you'll be able to use the following construction:

const app = await NestFactory.create(ApplicationModule, {
  logger: false,
});
app.useLogger(app.get(LoggerService));
await app.listen(3000);

That will hide initial logs (like x dependencies initialized) but for the rest of them (route mappings, caught exceptions, and so on), Nest will use your custom logger implementation.

@kamilmysliwiec thanks, waiting for 5.2 then!

5.2.0 is published!

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

FranciZ picture FranciZ  路  3Comments

mishelashala picture mishelashala  路  3Comments

yanshuf0 picture yanshuf0  路  3Comments

artaommahe picture artaommahe  路  3Comments

rlesniak picture rlesniak  路  3Comments