- add winston logger

- updated HTTP logging interceptor
This commit is contained in:
hannathkadher
2025-04-21 11:38:11 +04:00
parent 1e6503c072
commit be3c9f730d
5 changed files with 329 additions and 18 deletions

View File

@ -32,11 +32,14 @@ import { TagModule } from './tags/tags.module';
import { ClientModule } from './client/client.module';
import { DeviceCommissionModule } from './commission-device/commission-device.module';
import { PowerClampModule } from './power-clamp/power-clamp.module';
import { WinstonModule } from 'nest-winston';
import { winstonLoggerOptions } from './common/filters/http-exception/logger/winston.logger';
@Module({
imports: [
ConfigModule.forRoot({
load: config,
}),
WinstonModule.forRoot(winstonLoggerOptions),
ClientModule,
AuthenticationModule,
UserModule,

View File

@ -0,0 +1,24 @@
import { utilities as nestWinstonModuleUtilities } from 'nest-winston';
import * as winston from 'winston';
export const winstonLoggerOptions: winston.LoggerOptions = {
transports: [
new winston.transports.Console({
format: winston.format.combine(
winston.format.timestamp(),
nestWinstonModuleUtilities.format.nestLike('MyApp', {
prettyPrint: true,
}),
),
}),
new winston.transports.File({
filename: 'logs/error.log',
level: 'error',
format: winston.format.json(),
}),
new winston.transports.File({
filename: 'logs/combined.log',
format: winston.format.json(),
}),
],
};

View File

@ -3,39 +3,65 @@ import {
NestInterceptor,
ExecutionContext,
CallHandler,
Inject,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
import { Logger } from 'winston';
import { v4 as uuidv4 } from 'uuid';
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
constructor(
@Inject(WINSTON_MODULE_PROVIDER)
private readonly logger: Logger,
) {}
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const request = context.switchToHttp().getRequest();
const res = context.switchToHttp().getResponse();
const { method, url, body } = request;
const requestId = uuidv4();
const now = Date.now();
res.setHeader('X-Request-Id', requestId);
return next.handle().pipe(
map((response) => {
// Filter out sensitive fields from the request body for logging
const duration = Date.now() - now;
const filteredRequestBody = this.filterSensitiveFields(body);
console.log(
'-------------------------------------------------------------------',
);
console.log(`Request Method: ${method}`);
console.log(`Request URL: ${url}`);
if (
filteredRequestBody &&
Object.keys(filteredRequestBody).length > 0
) {
console.log(`Request Body: ${JSON.stringify(filteredRequestBody)}`);
}
// Filter out sensitive fields from the response for logging
const filteredResponse = this.filterSensitiveFields(response);
console.log(`Response: ${JSON.stringify(filteredResponse)}`);
return response; // Return the actual response unmodified
this.logger.info('--- Incoming Request ---', {
method,
url,
duration: `${duration}ms`,
requestBody: filteredRequestBody,
responseBody: filteredResponse,
});
this.logger.info('--- Outgoing Response ---', {
method,
url,
response: filteredResponse,
});
return response;
}),
catchError((error) => {
// Do not log anything if there is an error
return throwError(error);
const duration = Date.now() - now;
this.logger.error('--- Request Error ---', {
requestId,
method,
url,
message: error.message,
duration: `${duration}ms`,
stack: error.stack,
});
return throwError(() => error);
}),
);
}