loggerMiddleware로 morgan처럼 로깅하기
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를 연결해준다.