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