Skip to content

Commit

Permalink
logging requests, responses and exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
mrkeksz committed Oct 21, 2023
1 parent fa62fb2 commit 64828c0
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 61 deletions.
9 changes: 4 additions & 5 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ module.exports = {
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
extends: ['plugin:@typescript-eslint/recommended', 'plugin:prettier/recommended'],
root: true,
env: {
node: true,
Expand All @@ -21,5 +18,7 @@ module.exports = {
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-unused-vars': ['warn'],
'prettier/prettier': ['warn'],
},
};
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"start:prod": "NODE_ENV=production node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"lint:check": "eslint \"{src,apps,libs,test}/**/*.ts\"",
"test": "NODE_ENV=test jest",
Expand Down
20 changes: 13 additions & 7 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {AppController} from './app.controller'
import {AppService} from './app.service'
import {DevtoolsModule} from '@nestjs/devtools-integration'
import {UsersModule} from './users/users.module'
import {LoggerMiddleware} from './middlewares/logger.middleware'
import {RequestLoggerMiddleware} from './middlewares/request-logger.middleware'
import {APP_FILTER, APP_INTERCEPTOR, APP_PIPE} from '@nestjs/core'
import {HttpExceptionFilter} from './filters/http-exception.filter'
import {LoggingInterceptor} from './interceptors/logging.interceptor'
Expand All @@ -30,19 +30,25 @@ import {configModule, configProviders} from './config'
whitelist: true,
}),
},
{
provide: APP_INTERCEPTOR,
useClass: LoggingInterceptor,
},
{
provide: APP_INTERCEPTOR,
useClass: TimeoutInterceptor,
},
...(process.env[NODE_ENV.name] === NODE_ENV.options.DEVELOPMENT
? [
{
provide: APP_INTERCEPTOR,
useClass: LoggingInterceptor,
},
]
: []),
...configProviders,
],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer): any {
consumer.apply(LoggerMiddleware).forRoutes({path: '*', method: RequestMethod.ALL})
configure(consumer: MiddlewareConsumer) {
if (process.env[NODE_ENV.name] === NODE_ENV.options.DEVELOPMENT) {
consumer.apply(RequestLoggerMiddleware).forRoutes({path: '*', method: RequestMethod.ALL})
}
}
}
23 changes: 15 additions & 8 deletions src/filters/http-exception.filter.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
import {ExceptionFilter, Catch, ArgumentsHost, HttpException, HttpStatus} from '@nestjs/common'
import {
ExceptionFilter,
Catch,
ArgumentsHost,
HttpException,
HttpStatus,
Logger,
} from '@nestjs/common'
import {Request, Response} from 'express'
import {EnvironmentConfigService} from '../config/environment/environment.config.service'

@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
private readonly logger = new Logger(HttpExceptionFilter.name)

constructor(private readonly environmentConfigService: EnvironmentConfigService) {}

catch(exception: HttpException, host: ArgumentsHost) {
Expand All @@ -14,13 +23,11 @@ export class HttpExceptionFilter implements ExceptionFilter {

response.status(status).json(exception.getResponse())

if (status < HttpStatus.INTERNAL_SERVER_ERROR && !this.environmentConfigService.isTest) {
console.error(
`[Response] [${
request.method
}] ${new Date().toLocaleDateString()}, ${new Date().toLocaleTimeString()} - Path ${
request.url
}, Status ${status}, Message: ${exception.cause || exception.message}`,
if (status < HttpStatus.INTERNAL_SERVER_ERROR && this.environmentConfigService.isDevelopment) {
const timeAgo = Date.now() - response.locals.startTime
this.logger.verbose(
`Response {${request.url}, ${request.method}, ${status}} \x1b[33m+${timeAgo}ms`,
`Body ${JSON.stringify(exception.getResponse())}`,
)
}
}
Expand Down
33 changes: 12 additions & 21 deletions src/interceptors/logging.interceptor.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,26 @@
import {Injectable, NestInterceptor, ExecutionContext, CallHandler} from '@nestjs/common'
import {Injectable, NestInterceptor, ExecutionContext, CallHandler, Logger} from '@nestjs/common'
import {Observable} from 'rxjs'
import {tap} from 'rxjs/operators'
import {Response} from 'express'
import {EnvironmentConfigService} from '../config/environment/environment.config.service'

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
constructor(private readonly environmentConfigService: EnvironmentConfigService) {}
private readonly logger = new Logger(LoggingInterceptor.name)

intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
if (this.environmentConfigService.isTest) return next.handle()

const ctx = context.switchToHttp()
const response = ctx.getResponse<Response>()
const request = ctx.getRequest<Request>()
response.locals.startTime = Date.now()

const now = Date.now()
return next
.handle()
.pipe(
tap(value =>
console.log(
`[Response] [${
request.method
}] ${new Date().toLocaleDateString()}, ${new Date().toLocaleTimeString()} - Path ${
request.url
}, Status ${response.statusCode}, Returned: ${JSON.stringify(value)} +${
Date.now() - now
}ms`,
),
),
)
return next.handle().pipe(
tap(value => {
const timeAgo = Date.now() - response.locals.startTime
this.logger.verbose(
`Response {${request.url}, ${request.method}, ${response.statusCode}} \x1b[33m+${timeAgo}ms`,
`Body ${JSON.stringify(value)}`,
)
}),
)
}
}
19 changes: 0 additions & 19 deletions src/middlewares/logger.middleware.ts

This file was deleted.

12 changes: 12 additions & 0 deletions src/middlewares/request-logger.middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import {Injectable, Logger, NestMiddleware} from '@nestjs/common'
import {Request, Response, NextFunction} from 'express'

@Injectable()
export class RequestLoggerMiddleware implements NestMiddleware {
private readonly logger = new Logger(RequestLoggerMiddleware.name)

use(req: Request, res: Response, next: NextFunction) {
this.logger.verbose(`Request {${req.url}, ${req.method}}`)
next()
}
}

0 comments on commit 64828c0

Please sign in to comment.