TIL - 20260304

juni·2026년 3월 4일

TIL

목록 보기
284/317

0304 NestJS 심화 (4/N): 로깅, 예외 처리, 스케줄링


✅ 1. 로깅 (Logging)

  • 로깅은 애플리케이션이 실행되는 동안 발생하는 이벤트나 상태를 기록하는 것입니다. 단순한 console.log를 넘어, 체계적인 로깅은 디버깅, 성능 모니터링, 오류 추적에 필수적인 요소입니다.

  • NestJS의 내장 로거 (Logger):

    • NestJS는 @nestjs/common에 포함된 Logger 서비스를 기본 로깅 솔루션으로 제공합니다.
    • log(), error(), warn(), debug(), verbose()와 같이 로그 레벨(Log Level)에 따라 다른 메서드를 제공하여, 로그의 중요도를 구분할 수 있습니다.

➕ 프로덕션 환경을 위한 로깅: Winston

  • 기본 로거는 콘솔 출력에 최적화되어 있습니다. 실제 운영 환경에서는 로그를 파일로 저장하고, 포맷을 변경하며, 여러 곳으로 동시에 전송하는 등 더 고급 기능이 필요합니다.

  • Winston: Node.js 생태계에서 가장 널리 사용되는 로깅 라이브러리입니다.

  • nest-winston: Winston을 NestJS에서 쉽게 사용할 수 있도록 통합해주는 모듈입니다.

  • 주요 기능:

    • 다중 트랜스포트 (Transports): 로그를 콘솔, 파일, 데이터베이스 등 여러 목적지로 동시에 보낼 수 있습니다.
    • 로그 포맷팅: 로그 출력 형식을 JSON, 텍스트 등 원하는 대로 커스터마이징할 수 있습니다.
    • 로그 레벨 기반 필터링: 운영 환경에서는 info 레벨 이상의 로그만 파일에 기록하고, 개발 환경에서는 debug 레벨까지 모두 콘솔에 출력하는 등 환경별로 다른 로깅 정책을 적용할 수 있습니다.

✅ 2. 전역 예외 처리 (Global Exception Handling)

  • 애플리케이션 전역에서 처리되지 않은 예외(Unhandled Exception)가 발생했을 때, 이를 가로채서 클라이언트에게 일관된 형태의 에러 응답을 보내는 중앙 집중식 처리 메커니즘입니다.

➕ 예외 필터 (Exception Filter)

  • 개념: @Catch() 데코레이터가 붙은 클래스로, 특정 타입의 예외가 발생했을 때 실행됩니다. Spring의 @RestControllerAdvice와 동일한 역할입니다.

  • HttpExceptionFilter: 가장 일반적으로 사용되는 필터로, NestJS의 내장 HttpException 또는 이를 상속받은 커스텀 예외들을 처리합니다.

  • 구현 흐름:

    1. ExceptionFilter 인터페이스를 구현하는 클래스를 만듭니다.
    2. @Catch() 데코레이터에 처리할 예외 타입을 지정합니다. (비워두면 모든 예외를 처리)
    3. catch() 메서드 내에서, 예외 정보와 요청 정보를 바탕으로 클라이언트에게 보낼 커스텀 에러 응답 객체를 만듭니다.
    4. main.ts에서 app.useGlobalFilters()를 사용하여 생성한 예외 필터를 전역 필터로 등록합니다.
    // http-exception.filter.ts
    import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';
    import { Request, Response } from 'express';
    
    @Catch(HttpException)
    export class HttpExceptionFilter implements ExceptionFilter {
      catch(exception: HttpException, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse<Response>();
        const status = exception.getStatus();
    
        response.status(status).json({
          statusCode: status,
          message: exception.message,
          timestamp: new Date().toISOString(),
        });
      }
    }

✅ 3. 스케줄링 (Scheduling)

  • 스케줄링이란 애플리케이션 내에서 특정 작업을 미리 정해진 시간에 또는 주기적으로 자동으로 실행하도록 만드는 기능입니다.

  • 주요 사용 사례:

    • 매일 자정에 통계 데이터 배치(Batch) 작업 실행
    • 1시간마다 만료된 인증 토큰 정리
    • 매주 월요일 아침에 리포트 이메일 발송

@nestjs/schedule 모듈

  • NestJS는 Cron 스타일의 스케줄링을 쉽게 구현할 수 있도록 공식 @nestjs/schedule 패키지를 제공합니다.

  • 사용법:

    1. 패키지 설치: npm install @nestjs/schedule

    2. 루트 모듈(app.module.ts)에 ScheduleModule 등록:

      import { ScheduleModule } from '@nestjs/schedule';
      
      @Module({
        imports: [ScheduleModule.forRoot()],
      })
      export class AppModule {}
    3. @Cron() 데코레이터 사용:

      • 주기적으로 실행하고 싶은 메서드에 @Cron() 데코레이터를 붙이고, 실행 주기를 Cron 표현식으로 지정합니다.
    // my-scheduler.service.ts
    import { Injectable, Logger } from '@nestjs/common';
    import { Cron, CronExpression } from '@nestjs/schedule';
    
    @Injectable()
    export class MySchedulerService {
      private readonly logger = new Logger(MySchedulerService.name);
    
      // 매 30초마다 실행
      @Cron(CronExpression.EVERY_30_SECONDS)
      handleEvery30Seconds() {
        this.logger.debug('30초마다 실행되는 작업');
      }
    
      // 매일 오전 4시 30분에 실행
      @Cron('30 4 * * *')
      handleDailyTask() {
        this.logger.log('일일 통계 작업 실행');
        // ... 실제 배치 로직 ...
      }
    }
  • 기타 데코레이터:

    • @Interval(ms): 지정된 밀리초 간격으로 작업을 반복 실행.
    • @Timeout(ms): 애플리케이션 시작 후 지정된 밀리초가 지나면 한 번만 실행.

📌 요약

  • 운영 환경에서는 console.log 대신, Winston과 같은 전문 로깅 라이브러리를 사용하여 로그 레벨출력 형식/위치를 체계적으로 관리해야 합니다.
  • 전역 예외 필터 (Exception Filter)를 사용하면, 애플리케이션 전체에서 발생하는 예외를 중앙에서 일관되게 처리하여 안정적인 API 응답을 보장할 수 있습니다.
  • @nestjs/schedule 모듈과 @Cron() 데코레이터를 사용하면, 주기적인 배치 작업이나 예약된 작업을 매우 간단하게 구현할 수 있습니다.

0개의 댓글