[NestJS] Logger

문지은·2024년 6월 16일

NestJS

목록 보기
4/5
post-thumbnail

Logger 사용하기

  • NestJS는 기본적으로 로거가 내장되어 있어 서비스 클래스나 컨트롤러 클래스에서 로거를 쉽게 사용할 수 있다.
  • @nestjs/common 패키지에서 Logger 클래스를 불러온 후 인스턴스를 생성한 다음에 log()나 warn()debug()와 같은 메서드를 호출하면 된다.
  • 이 때 Logger() 생성자의 인자로 <클래스명>.name을 넘기주면 로거의 컨텍스트(context)가 클래스 이름으로 설정된다.
    • 이렇게 해주면 로그를 확인할 때 어느 클래스에 찍히는 로그인지 파악할 수 있다.
import { Injectable, Logger } from "@nestjs/common";

@Injectable()
export class AppService {
  private readonly logger = new Logger(AppService.name);

  getHello(): string {
    this.logger.debug("Logging...");
    return "Hello World!";
  }
}

Logger 확장하기

  • 로그를 남기는 방식에 변화를 주고 싶다면 NestJS에 내장된 기본 로거를 어렵지 않게 확장할 수 있다.
  • @nestjs/common 패키지의 ConsoleLogger 클래스를 확장(extend)하여 원하는 메서드만 오버라이드(override)해주면 된다.
  • debug 수준과 warn 수준에서 로그가 찍힐 때 메시지 앞에 특정 이모지(emoji)를 함께 출력되도록 로거를 확장해보자.
import { ConsoleLogger, Injectable } from "@nestjs/common";

@Injectable()
export class MyLogger extends ConsoleLogger {
  debug(message: any, ...optionalParams: any[]) {
    super.debug(`🐛 ${message}`, ...optionalParams);
  }

  warn(message: any, ...optionalParams: any[]) {
    super.warn(`🚨 ${message}`, ...optionalParams);
  }
}
  • 확장한 로거는 NestJS 앱에 설정을 해줘야 기본 로거 대신에 사용할 수 있다.
  • NestFactory.create()를 호출할 때 logger 옵션으로 확장한 로거 클래스의 인스턴스를 넘겨주면 된다.

main.ts

import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { MyLogger } from "./my-logger";

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

사용자 정의 로거

  • @nestjs/common 패키지의 LoggerService 인터페이스를 구현(implement)하는 경우가 있다.
  • 이 인테페이스는 총 6개의 메서드가 있다.
    • logwarnerror는 반드시 구현해줘야 하고, debugverbose는 선택적으로 구현이 가능하다.
import { LoggerService, Injectable } from '@nestjs/common';

@Injectable()
export class MyLogger implements LoggerService {
  /**
   * 'log' 레벨 로그 작성.
   */
  log(message: any, ...optionalParams: any[]) {}

  /**
   * 'fatal' 레벨 로그 작성.
   */
  fatal(message: any, ...optionalParams: any[]) {}

  /**
   * 'error' 레벨 로그 작성.
   */
  error(message: any, ...optionalParams: any[]) {}

  /**
   * 'warn' 레벨 로그 작성.
   */
  warn(message: any, ...optionalParams: any[]) {}

  /**
   * 'debug' 레벨 로그 작성.
   */
  debug?(message: any, ...optionalParams: any[]) {}

  /**
   * 'verbose' 레벨 로그 작성.
   */
  verbose?(message: any, ...optionalParams: any[]) {}
}
  • 자바스크립트의 console 전역 객체를 사용하여 로거를 구현해보자.

src/logger/logger.service.ts

import { Injectable, LoggerService as NestLoggerService } from "@nestjs/common";

@Injectable()
export class LoggerService implements NestLoggerService {
  debug(message: any, ...optionalParams: any[]) {
    console.debug(`🐛 ${message}`, ...optionalParams);
  }

  warn(message: any, ...optionalParams: any[]) {
    console.warn(`🚨 ${message}`, ...optionalParams);
  }

  log(message: any, ...optionalParams: any[]) {
    console.log(`🪵 ${message}`, ...optionalParams);
  }

  error(message: any, ...optionalParams: any[]) {
    console.error(`💥 ${message}`, ...optionalParams);
  }
}
  • 고급 로깅 기능을 위해서는 의존성 주입을 활용하는 것이 좋다.
    • Logger 클래스를 정의하고, 이를 LoggerModule에서 제공

src/logger/logger.module.ts

import { Module } from "@nestjs/common";
import { LoggerService } from "./logger.service";

@Module({
  providers: [LoggerService],
  exports: [LoggerService],
})
export class LoggerModule {}
  • 로거를 별도의 모듈로 제공하는 경우에는 로거의 인스턴스를 직접 생성하는 대신에 다른 일반 서비스처럼 NestJS의 DI(의존성 주입)을 사용해야한다.

src/app.module.ts


import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { LoggerModule } from './logger/logger.module';

@Module({
  controllers: [AppController],
  providers: [AppService],
  imports: [LoggerModule],
})
export class AppModule {}
  • NestFactory.create() 함수를 호출할 때 bufferLogs 옵션을 반드시 true로 설정해주어야 한다.
    • 이렇게 해주지 않으면 NestJS 앱이 구동되는 초반에 잠시동안 내장 로거가 사용될 수 있다.

main.ts


import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { LoggerService } from "./logger/logger.service";

async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    bufferLogs: true,
  });
  app.useLogger(app.get(LoggerService));
  await app.listen(3000);
}
bootstrap();

References
Documentation | NestJS - A progressive Node.js framework
NestJS에서 로깅(logging)하기

profile
코드로 꿈을 펼치는 개발자의 이야기, 노력과 열정이 가득한 곳 🌈

0개의 댓글