const winston = require('winston'); const DailyRotateFile = require('winston-daily-rotate-file'); const path = require('path'); // Define log format const logFormat = winston.format.combine( winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.errors({ stack: true }), winston.format.splat(), winston.format.json() ); // Console format (more readable) const consoleFormat = winston.format.combine( winston.format.colorize(), winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.printf(({ timestamp, level, message, ...meta }) => { let msg = `${timestamp} [${level}]: ${message}`; if (Object.keys(meta).length > 0) { msg += ` ${JSON.stringify(meta)}`; } return msg; }) ); // Create logs directory if it doesn't exist const logsDir = path.join(__dirname, '..', 'logs'); // Logger configuration const logger = winston.createLogger({ level: process.env.LOG_LEVEL || 'info', format: logFormat, defaultMeta: { service: 'govt-travel-estimator' }, transports: [ // Error logs new DailyRotateFile({ filename: path.join(logsDir, 'error-%DATE%.log'), datePattern: 'YYYY-MM-DD', level: 'error', maxFiles: '30d', maxSize: '20m' }), // Combined logs new DailyRotateFile({ filename: path.join(logsDir, 'combined-%DATE%.log'), datePattern: 'YYYY-MM-DD', maxFiles: '14d', maxSize: '20m' }), // Console output new winston.transports.Console({ format: consoleFormat }) ], exceptionHandlers: [ new DailyRotateFile({ filename: path.join(logsDir, 'exceptions-%DATE%.log'), datePattern: 'YYYY-MM-DD', maxFiles: '30d' }) ], rejectionHandlers: [ new DailyRotateFile({ filename: path.join(logsDir, 'rejections-%DATE%.log'), datePattern: 'YYYY-MM-DD', maxFiles: '30d' }) ] }); // Create a stream object for Morgan (HTTP request logging) logger.stream = { write: (message) => { logger.info(message.trim()); } }; module.exports = logger;