From f5a293da9c19463bd69dfd45efb29f2ad527167e Mon Sep 17 00:00:00 2001 From: Krystof Date: Fri, 18 Oct 2024 23:33:36 +0200 Subject: [PATCH] refactor(be): log interceptor --- .../modules/departure/departure.controller.ts | 16 ++++----- .../src/modules/logger/log.interceptor.ts | 29 ++++++++++++++++ .../modules/platform/platform.controller.ts | 34 +++++-------------- .../src/modules/stop/stop.controller.ts | 17 +++------- 4 files changed, 48 insertions(+), 48 deletions(-) create mode 100644 apps/backend/src/modules/logger/log.interceptor.ts diff --git a/apps/backend/src/modules/departure/departure.controller.ts b/apps/backend/src/modules/departure/departure.controller.ts index b9d0096e..6dc7b298 100644 --- a/apps/backend/src/modules/departure/departure.controller.ts +++ b/apps/backend/src/modules/departure/departure.controller.ts @@ -4,6 +4,7 @@ import { HttpException, HttpStatus, Query, + UseInterceptors, } from "@nestjs/common"; import { ApiTags } from "@nestjs/swagger"; import { z } from "zod"; @@ -14,17 +15,14 @@ import { departureSchema, type DepartureSchema, } from "src/modules/departure/schema/departure.schema"; -import { LoggerService } from "src/modules/logger/logger.service"; +import { LogInterceptor } from "src/modules/logger/log.interceptor"; import { toArray } from "src/utils/array.utils"; -import { measureDuration } from "src/utils/measure-duration"; @ApiTags("departure") @Controller("departure") +@UseInterceptors(LogInterceptor) export class DepartureController { - constructor( - private readonly departureService: DepartureService, - private readonly logger: LoggerService, - ) {} + constructor(private readonly departureService: DepartureService) {} @Get("/platform") async getDeparturesByPlatform(@Query("id") id): Promise { @@ -36,17 +34,15 @@ export class DepartureController { const parsed = platformSchema.safeParse(toArray(id)); if (!parsed.success) { - await this.logger.createRestErrorLog("/departure/platform", { id }); throw new HttpException( "Invalid query params", HttpStatus.BAD_REQUEST, ); } - const [departures, duration] = await measureDuration( - this.departureService.getDeparturesByPlatform(parsed.data), + const departures = this.departureService.getDeparturesByPlatform( + parsed.data, ); - await this.logger.createRestLog("/departure/platform", duration); return departureSchema.array().parse(departures); } diff --git a/apps/backend/src/modules/logger/log.interceptor.ts b/apps/backend/src/modules/logger/log.interceptor.ts new file mode 100644 index 00000000..0e1e8053 --- /dev/null +++ b/apps/backend/src/modules/logger/log.interceptor.ts @@ -0,0 +1,29 @@ +import { + CallHandler, + ExecutionContext, + Injectable, + NestInterceptor, +} from "@nestjs/common"; +import { Observable } from "rxjs"; +import { tap } from "rxjs/operators"; + +import { LoggerService } from "src/modules/logger/logger.service"; + +@Injectable() +export class LogInterceptor implements NestInterceptor { + constructor(private readonly logger: LoggerService) {} + + intercept(context: ExecutionContext, next: CallHandler): Observable { + const now = Date.now(); + const request = context.switchToHttp().getRequest(); + const { url, query } = request; + const endpoint = url.split("?")[0]; + + return next.handle().pipe( + tap(async () => { + const duration = Date.now() - now; + await this.logger.createRestLog(endpoint, duration, query); + }), + ); + } +} diff --git a/apps/backend/src/modules/platform/platform.controller.ts b/apps/backend/src/modules/platform/platform.controller.ts index 053e4f4d..86012027 100644 --- a/apps/backend/src/modules/platform/platform.controller.ts +++ b/apps/backend/src/modules/platform/platform.controller.ts @@ -11,7 +11,7 @@ import { ApiQuery, ApiTags } from "@nestjs/swagger"; import { z } from "zod"; import { ApiDescription, ApiQueries } from "src/decorators/swagger.decorator"; -import { LoggerService } from "src/modules/logger/logger.service"; +import { LogInterceptor } from "src/modules/logger/log.interceptor"; import { PlatformService } from "src/modules/platform/platform.service"; import { platformWithDistanceSchema, @@ -29,16 +29,12 @@ import { longitudeQuery, metroOnlyQuery, } from "src/swagger/query.swagger"; -import { measureDuration } from "src/utils/measure-duration"; @ApiTags("platform") @Controller("platform") -@UseInterceptors(CacheInterceptor) +@UseInterceptors(CacheInterceptor, LogInterceptor) export class PlatformController { - constructor( - private readonly platformService: PlatformService, - private readonly logger: LoggerService, - ) {} + constructor(private readonly platformService: PlatformService) {} @Get("/all") @ApiDescription({ @@ -51,20 +47,16 @@ export class PlatformController { }); const parsed = schema.safeParse(query); if (!parsed.success) { - await this.logger.createRestErrorLog("/platform/all", query); - throw new HttpException( parsed.error.format(), HttpStatus.BAD_REQUEST, ); } - const [platforms, duration] = await measureDuration( - this.platformService.getAllPlatforms(parsed.data), + const platforms = await this.platformService.getAllPlatforms( + parsed.data, ); - await this.logger.createRestLog("/platform/all", duration, query); - return platformSchema.array().parse(platforms); } @@ -103,20 +95,16 @@ Sort platforms by distance to a given location. Location may be saved in logs. const parsed = schema.safeParse(query); if (!parsed.success) { - await this.logger.createRestErrorLog("/platform/closest", query); - throw new HttpException( parsed.error.format(), HttpStatus.BAD_REQUEST, ); } - const [platforms, duration] = await measureDuration( - this.platformService.getPlatformsByDistance(parsed.data), + const platforms = await this.platformService.getPlatformsByDistance( + parsed.data, ); - await this.logger.createRestLog("/platform/closest", duration, query); - return platformWithDistanceSchema.array().parse(platforms); } @@ -139,20 +127,16 @@ Sort platforms by distance to a given location. Location may be saved in logs. }); if (!parsed.success) { - await this.logger.createRestErrorLog("/platform/in-box", query); - throw new HttpException( "Invalid query params", HttpStatus.BAD_REQUEST, ); } - const [platforms, duration] = await measureDuration( - this.platformService.getPlatformsInBoundingBox(parsed.data), + const platforms = await this.platformService.getPlatformsInBoundingBox( + parsed.data, ); - await this.logger.createRestLog("/platform/in-box", duration, query); - return platformSchema.array().parse(platforms); } } diff --git a/apps/backend/src/modules/stop/stop.controller.ts b/apps/backend/src/modules/stop/stop.controller.ts index 41930829..669fca67 100644 --- a/apps/backend/src/modules/stop/stop.controller.ts +++ b/apps/backend/src/modules/stop/stop.controller.ts @@ -2,19 +2,15 @@ import { CacheInterceptor } from "@nestjs/cache-manager"; import { Controller, Get, Query, UseInterceptors } from "@nestjs/common"; import { ApiQuery, ApiTags } from "@nestjs/swagger"; -import { LoggerService } from "src/modules/logger/logger.service"; +import { LogInterceptor } from "src/modules/logger/log.interceptor"; import { StopService } from "src/modules/stop/stop.service"; import { metroOnlyQuery } from "src/swagger/query.swagger"; -import { measureDuration } from "src/utils/measure-duration"; @ApiTags("stop") @Controller("stop") -@UseInterceptors(CacheInterceptor) +@UseInterceptors(CacheInterceptor, LogInterceptor) export class StopController { - constructor( - private readonly stopService: StopService, - private readonly logger: LoggerService, - ) {} + constructor(private readonly stopService: StopService) {} @Get("/all") @ApiQuery(metroOnlyQuery) @@ -23,12 +19,7 @@ export class StopController { metroOnlyQuery: unknown, ) { const metroOnly: boolean = metroOnlyQuery === "true"; - const [stops, duration] = await measureDuration( - this.stopService.getAll({ metroOnly }), - ); - await this.logger.createRestLog("/stop/all", duration); - - return stops; + return this.stopService.getAll({ metroOnly }); } }