Spaces:
Paused
Paused
| import winston from 'winston'; | |
| import DailyRotateFile from 'winston-daily-rotate-file'; | |
| import chalk from 'chalk'; | |
| const { combine, timestamp, printf, colorize, errors, json } = winston.format; | |
| // Define log levels | |
| const levels = { | |
| error: 0, | |
| warn: 1, | |
| info: 2, | |
| http: 3, | |
| debug: 4, | |
| }; | |
| // Colors for different log levels | |
| const colors = { | |
| error: 'red', | |
| warn: 'yellow', | |
| info: 'green', | |
| http: 'magenta', | |
| debug: 'white', | |
| }; | |
| // Add colors to winston | |
| winston.addColors(colors); | |
| // Custom log format for console | |
| const consoleFormat = printf(({ level, message, timestamp, stack, label }) => { | |
| let color; | |
| switch (level) { | |
| case 'error': color = chalk.red.bold; break; | |
| case 'warn': color = chalk.yellow; break; | |
| case 'info': color = chalk.green; break; | |
| case 'http': color = chalk.magenta; break; | |
| case 'debug': color = chalk.blue; break; | |
| default: color = chalk.white; | |
| } | |
| let logMessage = `${chalk.gray(timestamp)} ${color(`[${level.toUpperCase()}]`)}`; | |
| if (label) { | |
| logMessage += ` ${chalk.cyan(`(${label})`)}`; | |
| } | |
| logMessage += `: ${message}`; | |
| if (stack) { | |
| logMessage += `\n${chalk.red(stack)}`; | |
| } | |
| return logMessage; | |
| }); | |
| // Custom log format for files | |
| const fileFormat = combine( | |
| errors({ stack: true }), | |
| timestamp(), | |
| json() | |
| ); | |
| // Create transports array | |
| const transports = [ | |
| new winston.transports.Console({ | |
| format: combine( | |
| colorize({ level: true }), | |
| timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), | |
| errors({ stack: true }), | |
| consoleFormat | |
| ), | |
| }), | |
| new DailyRotateFile({ | |
| filename: 'logs/error-%DATE%.log', | |
| datePattern: 'YYYY-MM-DD', | |
| zippedArchive: true, | |
| maxSize: '20m', | |
| maxFiles: '14d', | |
| level: 'error', | |
| format: fileFormat, | |
| }), | |
| new DailyRotateFile({ | |
| filename: 'logs/combined-%DATE%.log', | |
| datePattern: 'YYYY-MM-DD', | |
| zippedArchive: true, | |
| maxSize: '20m', | |
| maxFiles: '14d', | |
| format: fileFormat, | |
| }), | |
| ]; | |
| // Create the logger instance | |
| const logger = winston.createLogger({ | |
| level: process.env.LOG_LEVEL || 'info', | |
| levels, | |
| format: combine( | |
| timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), | |
| errors({ stack: true }) | |
| ), | |
| transports, | |
| exitOnError: false, | |
| }); | |
| // Create a child logger with default metadata | |
| export const createLogger = (label: string) => { | |
| return logger.child({ label }); | |
| }; | |
| // Stream for morgan HTTP logging | |
| export const httpLogStream = { | |
| write: (message: string) => { | |
| logger.http(message.trim()); | |
| }, | |
| }; | |
| export default logger; |