Skip to content

Commit

Permalink
Gap 2421 add logging in middleware (#92)
Browse files Browse the repository at this point in the history
* logs incoming and outgoing request

* add error filter to log errors

* remove unused log

* fix status in errorFIlter
  • Loading branch information
a-lor-cab authored Apr 25, 2024
1 parent 3df6bf4 commit 14c13a8
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 3 deletions.
17 changes: 14 additions & 3 deletions src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { SchedulerLockModule } from 'src/scheduler/scheduler-lock.module';
import { Module } from '@nestjs/common';
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { ScheduleModule } from '@nestjs/schedule';
import { TypeOrmModule } from '@nestjs/typeorm';
Expand All @@ -26,6 +26,9 @@ import { HealthCheckModule } from './healthCheck/healthCheck.module';
import { v2NotificationsModule } from './notifications/v2/v2notifications.module';
import { Unsubscribe } from './notifications/v2/unsubscribe/unsubscribe.entity';
import { migrations } from './app.migrations';
import { LoggerMiddleware } from './middleware';
import { APP_FILTER } from '@nestjs/core';
import { ErrorFilter } from './filters/error.filter';

@Module({
imports: [
Expand Down Expand Up @@ -73,8 +76,16 @@ import { migrations } from './app.migrations';
HealthCheckModule,
],
controllers: [],
providers: [],
providers: [
{
provide: APP_FILTER,
useClass: ErrorFilter,
},
],
})
export class AppModule {
export class AppModule implements NestModule {
constructor(private connection: Connection) {}
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('*');
}
}
37 changes: 37 additions & 0 deletions src/filters/error.filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {
Catch,
ArgumentsHost,
Logger,
HttpException,
HttpStatus,
} from '@nestjs/common';
import { BaseExceptionFilter } from '@nestjs/core';

@Catch(Error)
export class ErrorFilter extends BaseExceptionFilter {
catch(exception: Error, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const stack = exception.stack;
const message = exception.message;
const request = ctx.getRequest<Request>();
const httpStatus =
exception instanceof HttpException
? exception.getStatus()
: HttpStatus.INTERNAL_SERVER_ERROR;

Logger.error({
message: 'Caught Error',
path: request.url,
error: message,
status: httpStatus,
stack: stack,
});

response.status(httpStatus).json({
timestamp: new Date().toISOString(),
path: request.url,
errorMessage: message,
});
}
}
2 changes: 2 additions & 0 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ErrorFilter } from './filters/error.filter';

async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalFilters(new ErrorFilter());
await app.listen(process.env.PORT || 3001);
}
bootstrap();
9 changes: 9 additions & 0 deletions src/middleware/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,21 @@ export class LoggerMiddleware implements NestMiddleware {
const { ip, method, originalUrl } = request;
const userAgent = request.get('user-agent') || '';

this.logger.log({
message: 'Incoming request',
method,
originalUrl,
userAgent,
ip,
});

response.on('finish', () => {
const { statusCode } = response;
const contentLength = response.get('content-length');
const endAt = process.hrtime.bigint();
const responseTime = `${(endAt - startAt) / BigInt(1000)}ms`;
this.logger.log({
message: 'Outgoing response',
method,
originalUrl,
statusCode,
Expand Down

0 comments on commit 14c13a8

Please sign in to comment.