Logging request/response in Nest.js Logging request/response in Nest.js typescript typescript

Logging request/response in Nest.js


I ended up injecting a classic logger on the raw app.This solution is not the best since it is not integrated to the Nest flow but works well for standard logging needs.

import { NestFactory } from '@nestjs/core';import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';import { ApplicationModule } from './app.module';import * as morgan from 'morgan';async function bootstrap() {    const app = await NestFactory.create<NestFastifyApplication>(ApplicationModule, new FastifyAdapter());    app.use(morgan('tiny'));    await app.listen(process.env.PORT, '0.0.0.0');}if (isNaN(parseInt(process.env.PORT))) {    console.error('No port provided. 👏');    process.exit(666);}bootstrap().then(() => console.log('Service listening 👍: ', process.env.PORT));


https://github.com/julien-sarazin/nest-playground/issues/1#issuecomment-682588094

You can use middleware for that.

import { Injectable, NestMiddleware, Logger } from '@nestjs/common';import { Request, Response, NextFunction } from 'express';@Injectable()export class AppLoggerMiddleware implements NestMiddleware {  private logger = new Logger('HTTP');  use(request: Request, response: Response, next: NextFunction): void {    const { ip, method, path: url } = request;    const userAgent = request.get('user-agent') || '';    response.on('close', () => {      const { statusCode } = response;      const contentLength = response.get('content-length');      this.logger.log(        `${method} ${url} ${statusCode} ${contentLength} - ${userAgent} ${ip}`      );    });    next();  }}

and in the AppModule

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


How about use finish event instead of close event.

import { Request, Response, NextFunction } from "express";import { Injectable, NestMiddleware, Logger } from "@nestjs/common";@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();  }}

Because as far as know express connection is maintained after send response.
So close event can't be fired

Reference

01. Node document about response event.
02. Github issue