import { CallHandler, ExecutionContext, Injectable, Logger, NestInterceptor, } from '@nestjs/common'; import type { Request, Response } from 'express'; import { Observable, tap } from 'rxjs'; @Injectable() export class LoggingInterceptor implements NestInterceptor { private readonly logger = new Logger(LoggingInterceptor.name); intercept(context: ExecutionContext, next: CallHandler): Observable { const http = context.switchToHttp(); const req = http.getRequest(); const res = http.getResponse(); const { method, url, body } = req; const start = Date.now(); this.logger.debug(`→ ${method} ${url} ${JSON.stringify(body)}`); return next.handle().pipe( tap((responseBody) => { const ms = Date.now() - start; this.logger.debug(`← ${method} ${url} ${res.statusCode} (${ms}ms) ${JSON.stringify(responseBody)}`); }), ); } }