30 lines
1.2 KiB
TypeScript
30 lines
1.2 KiB
TypeScript
import { CallHandler, ExecutionContext, HttpException, Injectable, Logger, NestInterceptor } from '@nestjs/common';
|
|
import { Observable, tap } from 'rxjs';
|
|
|
|
/** One line per request, failed ones included: 4xx as a warning, 5xx as an error. */
|
|
@Injectable()
|
|
export class LoggingInterceptor implements NestInterceptor {
|
|
private readonly logger = new Logger('HTTP');
|
|
|
|
intercept(context: ExecutionContext, next: CallHandler): Observable<unknown> {
|
|
const http = context.switchToHttp();
|
|
const request = http.getRequest();
|
|
const start = Date.now();
|
|
const line = (status: number) => {
|
|
const actor = request.user?.id ?? request.device?.id ?? 'anonymous';
|
|
const venueId = request.user?.venueId ?? request.device?.venueId ?? '-';
|
|
return `${request.method} ${request.url} ${status} | actor=${actor} venue=${venueId} | ${Date.now() - start}ms`;
|
|
};
|
|
return next.handle().pipe(
|
|
tap({
|
|
next: () => this.logger.log(line(http.getResponse().statusCode)),
|
|
error: (error: unknown) => {
|
|
const status = error instanceof HttpException ? error.getStatus() : 500;
|
|
if (status >= 500) this.logger.error(line(status));
|
|
else this.logger.warn(line(status));
|
|
},
|
|
}),
|
|
);
|
|
}
|
|
}
|