AnDeriensのブログ

個人的なブログです

NestJSのLoggerの挙動を調べてみた

NestJSのLoggerをいい感じにしていきたいが、ドキュメント見ただけでは最終的にどう動作するのかよくわからない。

いくつか試してみた。

参考ドキュメント

Logger | NestJS - A progressive Node.js framework

準備

とりあえず色付きのログが出るようにロガーを実装。

import { LoggerService } from '@nestjs/common';

export class MyLogger implements LoggerService {
  log(message: string) {
    console.log(this.color(message));
  }
  error(message: string, trace: string) {
    console.log(this.color(message, 'red'));
  }
  warn(message: string) {
    console.log(this.color(message, 'yellow'));
  }
  debug(message: string) {
    console.log(this.color(message, 'green'));
  }
  verbose(message: string) {
    console.log(this.color(message, 'purple'));
  }

  protected color<T extends string>(message: T, color = '') {
    const COLORS = {
      BLACK: '\u001b[30m',
      RED: '\u001b[31m',
      GREEN: '\u001b[32m',
      YELLOW: '\u001b[33m',
      BLUE: '\u001b[34m',
      MAGENTA: '\u001b[35m',
      CYAN: '\u001b[36m',
      WHITE: '\u001b[37m',
    };

    const printer = (message: T, color: typeof COLORS[keyof typeof COLORS]) => {
      const END = '\u001b[0m';
      return color + message + END;
    };

    switch (color) {
      case 'black':
        return printer(message, COLORS.BLACK);
      case 'red':
        return printer(message, COLORS.RED);
      case 'green':
        return printer(message, COLORS.GREEN);
      case 'blue':
        return printer(message, COLORS.BLUE);
      case 'yellow':
        return printer(message, COLORS.YELLOW);
      case 'cyan':
        return printer(message, COLORS.CYAN);
      case 'cyan':
        return printer(message, COLORS.CYAN);
      case 'white':
        return printer(message, COLORS.WHITE);
      default:
        return message;
    }
  }
}

ドキュメントにあるように、main.tsでロガーを設定

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    logger: new MyLogger(),
  });
  await app.listen(3000);
}

これでいったん、ロガーのインストールは完了。 次の章で使いかたを見ていく。

ロガーを使う

app.controller.tsでloggerを使ってみる。

1. console.logで出力

  getHello(): string {
    console.log('this is info log');
    console.warn('this is warn log');
    console.error('this is error log');
    return this.appService.getHello();
  }
}

ただの出力されるのみ。

f:id:anderiens:20210329161315p:plain
出力(console.log)

2. new でインスタンス

  getHello(): string {
    const logger = new Logger();
    logger.log('this is info log');
    logger.warn('this is warn log');
    logger.error('this is error log');
    return this.appService.getHello();
  }

出力は以下。カスタムロガークラスが使われている。

f:id:anderiens:20210329160657p:plain
出力(new でインスタンス化)

3. DIでインスタンス

  constructor(private readonly appService: AppService, private readonly logger: Logger) {}

  @Get()
  getHello(): string {
    this.logger.log('this is info log');
    this.logger.warn('this is warn log');
    this.logger.error('this is error log');
    return this.appService.getHello();
  }

出力は以下。カスタムロガーが使われている。

f:id:anderiens:20210329161734p:plain
出力(DI)

4. staticメソッドで呼び出す

NestJS coreのLoggerクラスは静的メソッドも持っている。

  getHello(): string {
    Logger.log('this is info log');
    Logger.warn('this is warn log');
    Logger.error('this is error log');
    return this.appService.getHello();
  }

出力は以下。自前で実装したロガークラスが使われなくなった。

f:id:anderiens:20210329161116p:plain
出力(staticメソッド)

まとめ

main.ts でLoggerを登録しても、静的には呼び出せない。

個人的には、ロガークラスのためにDIしたりインスタンス化に1行割いたりするのが嫌なので、静的に呼び出してかつちゃんとカスタムされたロガーを使いたいところ。