Using Winston Logger with context NestJS

Viewed 1943

I am trying to use Winston Logger in my NestJS project combined with "context" from nestjs's Logger.

If I directly assign logger when creating NestFactory:

const app = await NestFactory.create(AppModule, {
httpsOptions: serverOptions,
logger: WinstonModule.createLogger({
  level: 'info',
  handleExceptions: true,
  format: winston.format.combine(
    winston.format.errors({ stack: true }),
    winston.format.timestamp(),
    winston.format.json(),
  ),
  transports: [
    new winston.transports.File({
      level: 'debug',
      filename: 'logging.log',
      handleExceptions: true,
    }),
    new winston.transports.Console({
      level: 'debug',
      handleExceptions: true,
      format: winston.format.combine(
        winston.format.errors({ stack: true }),
        winston.format.timestamp(),
        winston.format.colorize(),
        winston.format.printf(
          ({ level, message, context, timestamp, stack, trace }) => {
            return `${timestamp} [${context}] ${level}: ${message} ${stack ? stack : ''} ${trace ? trace : ''}`;
          }),
      ),
    }),
  ],
}),

I can set context from each of services and the logging correctly shows the context:

export class AppService implements OnModuleInit {

  constructor(private logger: Logger) {
    this.logger.setContext(AppService.name);
  }

  async onModuleInit(): Promise<void> {
      this.logger.log('Testing...');
  }
Output: 2021-07-30T05:40:52.742Z [AppService] info: Testing...

However, if I extract winston logger out to another module:

import { Injectable, Scope, Logger } from '@nestjs/common';
import { Logger as WinstonLogger } from 'winston';
import * as winston from 'winston';

@Injectable()
export class MyLogger extends Logger {
  private logger: WinstonLogger;

  constructor() {
    super();

    this.logger = winston.createLogger({ ... same options

And set it indirectly from the bootstrap:

 // add global logger
  const logger: MyLogger = new MyLogger();

  const app = await NestFactory.create(AppModule, {
    httpsOptions: serverOptions,
    logger: logger

The "context" no longer works and the output is:

2021-07-30T05:50:07.933Z [undefined] info: Testing...

The reason why I am extending Logger is so I can add query function and use query function from winston.

I don't understand why above two methods aren't working in the same way for "context"

0 Answers
Related