From 0be419683e1cd4dd9ec3763ee4e3bf4517993fa0 Mon Sep 17 00:00:00 2001 From: ALGLAVE Ivan <ivan.alglave8@etu.univ-lorraine.fr> Date: Wed, 9 Nov 2022 15:08:31 +0100 Subject: [PATCH] Added interceptor with logging --- package.json | 1 + src/groups/groups.controller.ts | 3 ++ src/groups/groups.module.ts | 4 +- src/interceptors/http.interceptor.ts | 59 ++++++++++++++++++++++++++++ 4 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 src/interceptors/http.interceptor.ts diff --git a/package.json b/package.json index 75519d1..37f66f7 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "@nestjs/platform-express": "^9.0.0", "class-transformer": "^0.5.1", "class-validator": "^0.13.2", + "fastify": "^4.9.2", "mongoose": "^6.7.2", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", diff --git a/src/groups/groups.controller.ts b/src/groups/groups.controller.ts index 191fe59..4406b45 100644 --- a/src/groups/groups.controller.ts +++ b/src/groups/groups.controller.ts @@ -6,14 +6,17 @@ import { Delete, Param, Body, + UseInterceptors, } from '@nestjs/common'; import { Observable } from 'rxjs'; +import { HttpInterceptor } from '../interceptors/http.interceptor'; import { CreateGroupDto } from './dto/create-group.dto'; import { UpdateGroupDto } from './dto/update-group.dto'; import { GroupEntity } from './entities/group.entity'; import { GroupsService } from './groups.service'; @Controller('groups') +@UseInterceptors(HttpInterceptor) export class GroupsController { constructor(private readonly _groupsService: GroupsService) {} diff --git a/src/groups/groups.module.ts b/src/groups/groups.module.ts index 3320cf0..b8c3b67 100644 --- a/src/groups/groups.module.ts +++ b/src/groups/groups.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { Module, Logger } from '@nestjs/common'; import { MongooseModule } from '@nestjs/mongoose'; import { GroupsDao } from './dao/groups.dao'; import { GroupsController } from './groups.controller'; @@ -10,6 +10,6 @@ import { Group, GroupSchema } from './schemas/group.schema'; MongooseModule.forFeature([{ name: Group.name, schema: GroupSchema }]), ], controllers: [GroupsController], - providers: [GroupsService, GroupsDao], + providers: [GroupsService, GroupsDao, Logger], }) export class GroupsModule {} diff --git a/src/interceptors/http.interceptor.ts b/src/interceptors/http.interceptor.ts new file mode 100644 index 0000000..ebef03f --- /dev/null +++ b/src/interceptors/http.interceptor.ts @@ -0,0 +1,59 @@ +import { + CallHandler, + ExecutionContext, + Injectable, + Logger, + NestInterceptor, +} from '@nestjs/common'; +import { merge, Observable, of } from 'rxjs'; +import { filter, map, mergeMap, tap } from 'rxjs/operators'; +import { FastifyReply } from 'fastify'; + +@Injectable() +export class HttpInterceptor implements NestInterceptor { + /** + * Class constructor + * @param _logger + */ + constructor(private readonly _logger: Logger) {} + + /** + * Intercepts all HTTP requests and responses + * + * @param context + * @param next + */ + intercept = ( + context: ExecutionContext, + next: CallHandler, + ): Observable<any> => { + const cls = context.getClass(); + const handler = context.getHandler(); + const response: FastifyReply = context + .switchToHttp() + .getResponse<FastifyReply>(); + const logCtx = `${cls.name}.${handler.name}`; + + return next.handle().pipe( + map((_) => of(_)), + mergeMap((obs: Observable<any>) => + merge( + obs.pipe( + filter((_) => !!_), + map((_) => _), + ), + obs.pipe( + filter((_) => !_), + tap(() => response.status(204)), + map((_) => _), + ), + ), + ), + tap({ + next: (_) => + this._logger.log(!!_ ? JSON.stringify(_) : 'NO CONTENT', logCtx), + error: (_) => this._logger.error(_.message, JSON.stringify(_), logCtx), + }), + ); + }; +} -- GitLab