import { Injectable } from '@nestjs/common'; import * as winston from 'winston'; import * as path from 'path'; import * as fs from 'fs'; @Injectable() export class LoggerService { private logger: winston.Logger; constructor() { const logsDir = path.join(process.cwd(), 'data', 'logs'); if (!fs.existsSync(logsDir)) { fs.mkdirSync(logsDir, { recursive: true }); } const today = new Date().toISOString().split('T')[0]; const logFile = path.join(logsDir, `requests-${today}.log`); this.logger = winston.createLogger({ format: winston.format.combine( winston.format.timestamp(), winston.format.json(), ), transports: [ new winston.transports.Console({ format: winston.format.combine( winston.format.colorize(), winston.format.simple(), ), }), new winston.transports.File({ filename: logFile, format: winston.format.combine( winston.format.timestamp(), winston.format.json(), ), }), ], }); } logRequest(method: string, path: string, body: any, response: any, duration: number) { this.logger.info('Request', { meta: { method, path, body, response, duration }, }); } logError(error: any, context?: string) { this.logger.error('Error', { meta: { error: error?.message ?? String(error), stack: error?.stack, context }, }); } log(message: string, meta?: any) { this.logger.info(message, { meta }); } warn(message: string, meta?: any) { this.logger.warn(message, { meta }); } }