Search code examples
typescriptnestjs

Logging request/response in Nest.js


New to Nest.js,
I am trying to implement a simple logger for tracing HTTP requests like :

:method :url :status :res[content-length] - :response-time ms

From my understanding the best place for that would be interceptors. But I Also use Guards and as mentionned, Guards are triggered after middlewares but before interceptors.

Meaning, my forrbidden accesses are not logged. I could write the logging part in two different places but rather not. Any idea?

Thanks!

My Interceptor code:

import { Injectable, NestInterceptor, ExecutionContext, HttpException, HttpStatus } from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError, tap } from 'rxjs/operators';

@Injectable()
export class HTTPLoggingInterceptor implements NestInterceptor {

  intercept(context: ExecutionContext, call$: Observable<any>): Observable<any> {
    const now = Date.now();
    const request = context.switchToHttp().getRequest();

    const method = request.method;
    const url = request.originalUrl;

    return call$.pipe(
      tap(() => {
        const response = context.switchToHttp().getResponse();
        const delay = Date.now() - now;
        console.log(`${response.statusCode} | [${method}] ${url} - ${delay}ms`);
      }),
      catchError((error) => {
        const response = context.switchToHttp().getResponse();
        const delay = Date.now() - now;
        console.error(`${response.statusCode} | [${method}] ${url} - ${delay}ms`);
        return throwError(error);
      }),
    );
  }
}

Solution

  • 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));