coffee-core
Version:
Coffee IT API core library
65 lines (53 loc) • 1.75 kB
text/typescript
import {
CallHandler,
ExecutionContext,
Injectable,
NestInterceptor,
Logger,
} from '@nestjs/common';
import { Observable, tap } from 'rxjs';
import { LogLevel } from '../domain/loglevel.type';
import { LoggingInterceptorConfig } from '../domain/loginterceptorconfig.interface';
()
export class LoggingInterceptor implements NestInterceptor {
private readonly logger = new Logger(LoggingInterceptor.name);
private readonly pathConfig: Record<string, LogLevel>;
constructor(config?: LoggingInterceptorConfig) {
this.pathConfig = config?.pathConfig ?? { '/health': 'skip' };
}
public intercept(
context: ExecutionContext,
next: CallHandler,
): Observable<any> {
const req = context.switchToHttp().getRequest();
const logLevel = this.pathConfig[req.path] ?? 'full';
if (logLevel === 'skip') {
return next.handle();
}
if (!req.id) {
req.id = this.generateRequestId();
}
const userId = req.user?.userId ?? '';
const hasBody = req.body && Object.keys(req.body).length > 0;
const includeBody = logLevel === 'full' && hasBody;
let logMessage = `[Request ${req.id}] ${req.method} ${req.url} by user ${userId}`;
if (includeBody) {
logMessage += ` with body ${JSON.stringify(req.body, null, 2)}`;
}
this.logger.log(logMessage);
const startOfRequest = Date.now();
return next
.handle()
.pipe(
tap(() =>
this.logger.log(
`[Request ${req.id}] Completed after... ${Date.now() - startOfRequest}ms`,
),
),
);
}
private generateRequestId(): string {
const randomString = Math.random().toString(36).substring(2, 8);
return `${Date.now()}-${randomString}`;
}
}