결과물 보기 ✨

Untitled

1. 기존 Logger를 Custom Logger로 바꾸기 (파일 작성)

src/common/logging/logger.service.ts

@Injectable()
export class LoggerService implements NestLoggerService {
  debug(message: any, ...optionalParams: any[]) {
    console.debug(`[Nest]   - ${new Date().toISOString()} ------> [DEBUG] 🌸 ${message}`, ...optionalParams);
  }

  warn(message: any, ...optionalParams: any[]) {
    console.warn(`[Nest]   - ${new Date().toISOString()} ------> [WARN] 🚨 ${message}`, ...optionalParams);
  }

  log(message: any, ...optionalParams: any[]) {
    console.log(`[Nest]   - ${new Date().toISOString()} ------> [LOG] 🍀 ${message}`, ...optionalParams);
  }

  error(message: any, ...optionalParams: any[]) {
    console.error(`[Nest]   - ${new Date().toISOString()} ------> [ERROR]💥 ${message}`, ...optionalParams);
  }
}

src/common/logginglogger.module.ts

@Module({
  providers: [LoggerService],
})
export class LoggerModule {}

2. custom logger 적용하기

main.ts

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe({ transform: true, forbidUnknownValues: false }));
  app.useGlobalFilters(new BusinessExceptionFilter());
  app.useLogger(app.get(LoggerService));
  await app.listen(3000);
}
bootstrap();

3. logger interceptor 만들기 & exception filter에 logging 추가

src/common/logging/logging.interceptor.ts

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

  intercept(context: ExecutionContext, next: CallHandler): Observable<any> | Promise<Observable<any>> {
    const ctx = context.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();

    const now = Date.now();
    return next
      .handle()
      .pipe(
				tap(() => this.logger.debug(`RequestUrl: [${request.method}] ${request.url} form`)),
        tap(() => this.logger.debug(`Status: ${response.statusCode} After: ${Date.now() - now}ms form`)),
        tap(json => this.logger.debug(`Response: ${JSON.stringify(json)} form`)),
      );

  }
}

src/common/exception/business.exception.filters.ts

@Catch(BusinessException)
export class BusinessExceptionFilter implements ExceptionFilter {
  private readonly logger = new Logger(BusinessExceptionFilter.name);

  catch(exception: BusinessException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    this.logger.error(`ErrorCode: ${exception.errorCode.code} ErrorMessage: ${exception.errorCode.message} form`)

    response
      .status(exception.errorCode.code)
      .json(exception.toResponse(request.url));
  }
}

4. interceptor 적용