nestjs-winston-logger icon indicating copy to clipboard operation
nestjs-winston-logger copied to clipboard

Question: Is it possible to have different loggers with different transports?

Open rat-matheson opened this issue 3 years ago • 8 comments

Before I start, I just wanted to say great library. I learned a bit more about using nest from looking at your code.

Anyway, from what I can tell, we can create several different loggers using @InjectLogger("someContext") but they all share the same configuration from single global logger. What I need to be able to do is create different loggers that write different things to different files.

Specifically, I would like a separate request log for the API requests, authentication log, error log, and debug log. The error log and debug log can share the same config since the only difference is log level but the authentication log and request log are entirely different things and I don't want information from there going into a debug log.

I assumed that I could do something like @InjectLogger(AUTH_LOG) and @InjectLogger(REQ_LOG) to create the logs, but don't quite see how to configure them.

rat-matheson avatar Dec 20 '21 16:12 rat-matheson

Just to add to my previous comment, I'm looking at how what I'm requesting might be achieved (I'm completely new to winston so forgive me if I'm missing something obvious).

// nestjs-winston-logger.module.ts
export class NestjsWinstonLoggerModule {
  static forRoot(options: LoggerOptions): DynamicModule {

So perhaps what I need is some other kind of parameter in forRoot.

type LoggersConfig = {
  defaultOptions:LoggerOptions,

  // so if I have a separate logger that I need different settings for, the provider can look up the settings based on the context
  loggerSpecificOptions?:{
    [context:string]:LoggerOptions
  }
 
}

And use factory becomes something like

static forRoot(params:LoggersConfig): DynamicModule {

   // ...

    const loggerProviders: FactoryProvider<NestjsWinstonLoggerService>[] = contexts.map(
      (context) => {
        return {
          provide: getLoggerToken(context),
          useFactory: () => {
            let options = params.loggerSpecificOptions && params.loggerSpecificOptions[context] ? params.loggerSpecificOptions[context] : params.defaultOptions;
            const logger = new NestjsWinstonLoggerService(options);
            logger.setContext(context);
            return logger;
          },
        };
      },

rat-matheson avatar Dec 20 '21 17:12 rat-matheson

I see you added the good first issue label. I'm fine with picking this one up if you think the approach is ok.

rat-matheson avatar Dec 20 '21 17:12 rat-matheson

I see you added the good first issue label. I'm fine with picking this one up if you think the approach is ok.

Feel free to go for it! I was accidentally added the good first issue label, would be great if you are willing to work on the enhancement!

I was wondering if we can do it like mongoose: https://docs.nestjs.com/recipes/mongodb#mongodb-mongoose

let me study more after I wake up.

owen1002 avatar Dec 20 '21 18:12 owen1002

I created a pull request which you can check out and give me some CR feedback.

https://github.com/owen1002/nestjs-winston-logger/pull/8/commits/dd0a1d19c6d1f202e2dc99bfdc6b9fbc9e668f12#

With regards to your mongoose comment, I didn't fully understand it at first but after looking at it a bit more, I found this.

// from https://docs.nestjs.com/techniques/mongodb
@Module({
  imports: [
    MongooseModule.forRoot('mongodb://localhost/test', {
      connectionName: 'cats',
    }),
    MongooseModule.forRoot('mongodb://localhost/users', {
      connectionName: 'users',
    }),
  ],
})

I think you may be suggesting something where we allow multiple NestjsWinstonLoggerModule.forRoot(...) function but specify the injection token.

imports:[
  NestjsWinstonLoggerModule.forRoot(config, AUTH_TOKEN),
  NestjsWinstonLoggerModule.forRoot(config, SOME_OTHER_TOKEN),
]

rat-matheson avatar Dec 20 '21 22:12 rat-matheson

Any updates on this? I'd like to be able to have different loggers as well

justinpenguin45 avatar Oct 06 '22 16:10 justinpenguin45

@owen1002 - can you add your thoughts? I don't mind continuing with the review. It seems to be blocked at the moment though

rat-matheson avatar Oct 08 '22 18:10 rat-matheson

Sorry for the late response, I'm trying to understand where we are in.

Just to confirm, this use case is to have multiple logger configs to be used in one module right?

What is blocking us from using the below setup?

@Module({
  imports: [
    NestjsWinstonLoggerModule.forRoot('LoggerA', loggerAConfig),
    NestjsWinstonLoggerModule.forRoot('LoggerB', loggerBConfig),
  ],
})

It would be helpful if you could share an example, so that we'll be on the same page.

owen1002 avatar Oct 09 '22 01:10 owen1002

Yes, I have to admit, I'm a bit foggy too. It has been a while since I looked at it and I've worked on other things in the meantime while I was waiting.

Yes, you are right. The feature I needed was ability to have different log files (and therefore logger instances) with different config. Skimming through the pull request, it looks like I didn't initially understand that I could have multiple forRoot imports for the module, but then once I did that, I ran into a bug relating to the context.

I think an an appropriate next step might be to just re-create the use case I was trying to do and see if I run into the context issue with the newest version of the library. Not sure when exactly I'll get around to it but if you are available and interested in reviewing, I will try to do it in the next week or two. If you can give me feedback as I go, I can stick with it until we can close it out. In the end, it might just be an update to documentation to spell out the specific use case.

rat-matheson avatar Oct 09 '22 16:10 rat-matheson