본문 바로가기
Research/Nest.js

nestjs_logger 미들웨어 생성하여 주입해보기

by RIEM 2023. 4. 4.
728x90

미들웨어란?

미들웨어는 라우더 핸들러 이전에 호출되는 함수다. 덕분에 요청-응답 주기에서 req, res 객체을 다룰 수 있다.

미들웨어를 사용하기 위해 1) 미들웨어를 CLI로 생성해준 뒤, 2)app.module에 config 메소드로 주입했다.

 

미들웨어 프로바이더 생성

nest g middleware logger

CLI로 미들웨어 생성.

// logger/logger.middleware.ts
import { Injectable, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  // express의 app.use와 유사한 문법
  use(req: Request, res: Response, next: NextFunction) {
    console.log(req.ip); //127.0.0.1
    console.log(req.originalUrl); //cats
    next();
  }
}

미들웨어도 기본적으로 Provider와 같이 종속성 주입으로 사용하기 때문에 @Injectable() 데코레이터가 붙어있다.

생성된 미들웨어미들웨어의 파라미터들의 타입을 express type으로 지정해주고.. 간단히 단순 콘솔 로그를 찍어보자.

 

미들웨어 주입

// app.module.ts
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsModule } from './cats/cats.module';
import { CatsService } from './cats/cats.service';
import { LoggerMiddleware } from './logger/logger.middleware';

@Module({
  imports: [CatsModule],
  controllers: [AppController],
  providers: [AppService, CatsService],
})
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    // *(모든) 엔드포인트에 로그 적용
    consumer.apply(LoggerMiddleware).forRoutes('*');
  }
}
// NestModule은 인터페이스이기에 implements로 적용

미들웨어는 @Module이 아니라 configure 메소드

 

Console.log -> Logger로 변경

// logger/logger.middleware.ts
import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  // HTTP 관련 로거 인스턴스 생성
  private logger = new Logger('HTTP');

  // express의 app.use와 유사한 문법
  use(req: Request, res: Response, next: NextFunction) {
    // 로거 호출
    this.logger.log(req.ip, req.method, req.originalUrl);
    // console.log(req.ip);
    // console.log(req.originalUrl);

    // res의 finish 이벤트 발생시(res가 완료될 때), 로그 또 찍어주기
    res.on('finish', () => {
      this.logger.log(res.statusCode);
    });

    next();
  }
}

 

nest.js에서 제공하는 로거를 사용하면 console.log보다 더 가독성이 좋다.

로그 부분을 리팩토링해서 깔끔하게 한줄로 표현하자.

// logger/logger.middleware.ts
import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  // HTTP 관련 로거 인스턴스 생성
  private logger = new Logger('HTTP');

  // express의 app.use와 유사한 문법
  use(req: Request, res: Response, next: NextFunction) {
    // 로거 호출
    // res의 finish 이벤트 발생시(res가 완료될 때), 로그 또 찍어주기
    res.on('finish', () => {
      this.logger.log(
        `${req.ip}, ${req.method}, ${res.statusCode}, ${req.originalUrl}`,
      );
    });

    next();
  }
}
[Nest] 17348  - 2023. 04. 04. 오전 5:17:21     LOG [HTTP] ::ffff:127.0.0.1, GET, 200, /

API를 호출하면 이렇게 깔끔하게 한줄로 로그가 찍힌다.

728x90

댓글