diff --git a/server/src/app.module.ts b/server/src/app.module.ts index 16cec94325..40fa95aefc 100644 --- a/server/src/app.module.ts +++ b/server/src/app.module.ts @@ -15,6 +15,7 @@ import { entities } from 'src/entities'; import { AuthGuard } from 'src/middleware/auth.guard'; import { ErrorInterceptor } from 'src/middleware/error.interceptor'; import { FileUploadInterceptor } from 'src/middleware/file-upload.interceptor'; +import { LoggingInterceptor } from 'src/middleware/logging.interceptor'; import { repositories } from 'src/repositories'; import { services } from 'src/services'; import { ApiService } from 'src/services/api.service'; @@ -26,6 +27,7 @@ const common = [...services, ...repositories]; const middleware = [ FileUploadInterceptor, { provide: APP_PIPE, useValue: new ValidationPipe({ transform: true, whitelist: true }) }, + { provide: APP_INTERCEPTOR, useClass: LoggingInterceptor }, { provide: APP_INTERCEPTOR, useClass: ErrorInterceptor }, { provide: APP_GUARD, useClass: AuthGuard }, ]; diff --git a/server/src/middleware/logging.interceptor.ts b/server/src/middleware/logging.interceptor.ts new file mode 100644 index 0000000000..ee8161d9c7 --- /dev/null +++ b/server/src/middleware/logging.interceptor.ts @@ -0,0 +1,28 @@ +import { CallHandler, ExecutionContext, Inject, Injectable, NestInterceptor } from '@nestjs/common'; +import { Observable, finalize } from 'rxjs'; +import { ILoggerRepository } from 'src/interfaces/logger.interface'; + +@Injectable() +export class LoggingInterceptor implements NestInterceptor { + constructor(@Inject(ILoggerRepository) private logger: ILoggerRepository) { + this.logger.setContext(LoggingInterceptor.name); + } + + intercept(context: ExecutionContext, next: CallHandler): Observable { + const handler = context.switchToHttp(); + const req = handler.getRequest(); + const res = handler.getResponse(); + + const { method, ip, path } = req; + + const start = performance.now(); + return next.handle().pipe( + finalize(() => { + const finish = performance.now(); + const duration = (finish - start).toFixed(2); + const { statusCode } = res; + this.logger.verbose(`${method} ${path} ${statusCode} ${duration}ms ${ip}`); + }), + ); + } +}