Study_Develop/인프런 - Slack 클론코딩(백엔드)

loggerMiddleware로 morgan처럼 로깅하기

hiijihyun 2023. 7. 31. 17:20
반응형

 

 

express에서 처럼 똑같이 app.use(morgan()) 라고 해도 된다.

이를, global middleware라고 부른다.

 

Moragn 모듈이란?

 

HTTP request logger middleware for node.js : node.js를 위한 요청들에 대한 로거를 출력하는 미들웨어!

 

요청이 들어오면 클라이언트들이 어떤 요청을 했고, 어떻게 응답했는지 터미널에 출력하는 역할을 하는 모듈

 

이런 모듈은 직접 미들웨어로 구현할 수 있다.

 

실무에선 그냥 Morgan을 사용하면 되긴 하지만, nest에서 일반 미들웨어로 이런 역할을 하는 모듈을 생성해보았다.

 

 

- src 안에 middlewares폴더 안에 logger.middleware.ts를 만든다

 

export class LoggerMiddleware implements NestMiddleware {

 

-> NestMiddelware를 implement해서 LoggerMiddelware를 생성했다.

 

-> 여기서 implements는 반드시 구현해야 하는 강제사항이 생긴다.

 

-> private logger = new Logger('HTTP'); 는 context를 생성하는 문장이넫, 출력문이 많을 때 이 출력문이 언제 생기는 건지를 보여준다.

 

 

 

  use(request: Request, response: Response, next: NextFunction) : void {

}

 

-> 위의 코드 부분만 보면 express의 middleware 구조와 같다.

 

-> 인자로 req, res, next를 갖는 것을 알 수 있고, 그렇게 받은 request 정보를 저장했다.

 

 

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  private logger = new Logger('HTTP');

  use(request: Request, response: Response, next: NextFunction) : void {
    const { ip, method, originalUrl } = request;
    const userAgent = request.get('user-agent') || '';

    response.on('finish', () => {
      const { statusCode } = response;
      const contentLength = response.get('content-length');
      this.logger.log(
        `${method} ${originalUrl} ${statusCode} ${contentLength} - ${userAgent} ${ip}`,
      );
    });
    next();
  }
}

 

-> 이후에 실행되는 것은 next() 인데 그 이유는 on()함수는 라우터 실행이 끝났을 때 'finish'가 실행되고 그 전에 비동기로 인해 next()함수가 먼저 실행되기 때문이다.

 

-> 라우터 실행이 끝났을 때는 on() 함수에서 response의 정볼르 저장하여 this.logger.log함수를 이용해 출력한다.

 

-> 만약 context를 생성하지 않았다면, Logger.log()를 호출하면 된다.

 

-> Nest.js에서는 console.log() 대신 Logger를 사용하도록 하자!

(이유 : console.log는 어디서 연결이 되어있는지 추적이 힘들기 때문)

 

 

아래 예시>

 

new Logger('HTTP');

 

- HTTP가 context 이다.

 

- http관련된 요청들은 특별하게 this.logger에서 보여준다.

 

 

module.ts>

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer): any {
    consumer.apply(LoggerMiddleware).forRoutes('*');
  }

 

-> middleware연결을 위해, consumer 에서 꺼내서 LoggerMiddeleware를 연결해준다.