NestJS 활용하기(6) - logger

이태훈·2023년 11월 6일
0

NestJS

목록 보기
6/6

만든 애플리케이션이 실행되는 동안 발생하는 이벤트를 기록하기 위해 로거를 사용해보겠다. 이렇게 기록된 로그를 통해 문제를 진단하고, 시스템의 성능을 모니터링 할 수 있기 때문에 반드시 로그를 남기는 것이 좋다.

내장 logger

NestJS는 내장된 logger 클래스가 있으며, 이를 사용하면 콘솔에 로그를 출력할 수 있다. 내장 logger에는 다음과 같은 메서드가 있다.

  • log(message: string): 일반적인 정보를 출력할 때 사용
  • error(message: string, trace?: string): 오류 메시지와 스택 트레이스를 출력할 때 사용
  • warn(message: string): 경고 메시지를 출력할 때 사용
  • debug(message: string): 디버그 메시지를 출력할 때 사용
  • verbose(message: string): 자세한 정보를 출력할 때 사용

사용 예시

import { Injectable, Logger } from '@nestjs/common';

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

  doSomething() {
    try {
      // ... 여기에 비즈니스 로직 ...
      this.logger.log('Doing something...');
    } catch (error) {
      this.logger.error('An error occurred!', error.stack);
    }
  }
}

이렇게 간단하게 어떤 부분에 해당하는 로거인지를 지정하여 로거를 생성한 후 각 메서드를 통해 로그 메세지를 출력할 수 있다.

하지만 이렇게 콘솔에만 로그를 출력하는 것은 개발 중이거나 디버깅할 때는 용이할 수 있지만 운영환경에서는 시스템이 재부팅되거나 콘솔 세션이 닫힌 경우 로그가 사라지고, 검색과 분석도 어려우며, 로그 모니터링을 하는데 제한이 있는 등의 문제점이 있을 수 있기 때문에 파일이나 데이터베이스 등에 저장하는 것이 좋다.

로깅 라이브러리 사용

winston 이라는 로깅 라이브러리를 사용하면 파일로 로그를 기록할 수 있다.

설치 방법

npm install winston
npm install @types/winston --save-dev

커스텀 로거 생성

import { Injectable, LoggerService } from '@nestjs/common';
import * as winston from 'winston';

@Injectable()
export class WinstonLoggerService implements LoggerService {
  private readonly logger: winston.Logger;

  constructor() {
    this.logger = winston.createLogger({
      level: 'info',
      format: winston.format.json(),
      transports: [
        new winston.transports.File({ filename: 'error.log', level: 'error' }),
        new winston.transports.File({ filename: 'combined.log' }),
      ],
    });

    // 콘솔 출력 설정 (개발 중에 유용함)
    if (process.env.NODE_ENV !== 'production') {
      this.logger.add(new winston.transports.Console({
        format: winston.format.simple(),
      }));
    }
  }

  log(message: string) {
    this.logger.log({ level: 'info', message });
  }

  error(message: string, trace: string) {
    this.logger.log({ level: 'error', message, trace });
  }

  warn(message: string) {
    this.logger.log({ level: 'warn', message });
  }

  // 기타 필요한 메서드(debug, verbose 등) 구현...
}

커스텀 로거 등록

import { Module } from '@nestjs/common';
import { WinstonLoggerService } from './winston-logger.service';

@Module({
  // ...
  providers: [WinstonLoggerService],
})
export class AppModule {}

app.module.ts에 providers 리스트에 이전에 생성한 커스텀 로거를 추가하여 NestJS 모듈에 로거로 제공하도록 설정을 한다.

사용

import { Injectable, Logger } from '@nestjs/common';
import { WinstonLoggerService } from './winston-logger.service';

@Injectable()
export class MyService {
  constructor(private logger: WinstonLoggerService) {} // 이 부분 수정

  doSomething() {
    try {
      // ... 여기에 비즈니스 로직 ...
      this.logger.log('Doing something...');
    } catch (error) {
      this.logger.error('An error occurred!', error.stack);
    }
  }
}

이전에 내장 logger를 사용하던 부분에서 logger를 생성하던 부분을 커스텀 로거를 주입하는 형태로 바꿔서 사용한다.

profile
지속가능한 개발자를 꿈꿉니다

0개의 댓글