import winston from 'winston'; import path from 'path'; const logDir = process.env.LOG_FILE_PATH || './logs'; // Create logger instance const logger = winston.createLogger({ level: process.env.LOG_LEVEL || 'info', format: winston.format.combine( winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss', }), winston.format.errors({ stack: true }), winston.format.json() ), defaultMeta: { service: 're-workflow-backend' }, transports: [ // Write all logs with level 'error' and below to error.log new winston.transports.File({ filename: path.join(logDir, 'error.log'), level: 'error', maxsize: 5242880, // 5MB maxFiles: 5, }), // Write all logs with level 'info' and below to combined.log new winston.transports.File({ filename: path.join(logDir, 'combined.log'), maxsize: 5242880, // 5MB maxFiles: 5, }), ], }); // If we're not in production, log to the console as well if (process.env.NODE_ENV !== 'production') { logger.add( new winston.transports.Console({ format: winston.format.combine( winston.format.colorize(), winston.format.simple() ), }) ); } // Create a stream object for Morgan HTTP logging // Use type assertion to bypass TypeScript's strict checking for the stream property const loggerWithStream = logger as any; loggerWithStream.stream = { write: (message: string) => { logger.info(message.trim()); }, }; export default loggerWithStream as winston.Logger;