const fs = require('fs'); const path = require('path'); const chalk = require('chalk'); class Logger { constructor(level = 'INFO') { this.logLevels = ['INFO', 'WARN', 'ERROR']; this.level = level.toUpperCase(); // 默认日志目录 ./logs this.logDir = path.resolve(process.cwd(), 'logs'); if (!fs.existsSync(this.logDir)) { fs.mkdirSync(this.logDir, { recursive: true }); } } // 获取当天日志文件路径 getLogFilePath() { const dateStr = new Date().toISOString().split('T')[0]; // YYYY-MM-DD return path.join(this.logDir, `${dateStr}.log`); } log(level, message) { level = level.toUpperCase(); if (this.logLevels.indexOf(level) >= this.logLevels.indexOf(this.level)) { const timestamp = new Date().toLocaleString(); const logMessage = `${timestamp} [${level}] ${message}`; // 控制台颜色 let coloredMessage; switch (level) { case 'INFO': coloredMessage = chalk.white(logMessage); break; case 'WARN': coloredMessage = chalk.yellow(logMessage); break; case 'ERROR': coloredMessage = chalk.red(logMessage); break; default: coloredMessage = logMessage; } console.log(coloredMessage); // 保存到文件 const logFilePath = this.getLogFilePath(); fs.appendFile(logFilePath, `${logMessage}\n`, (err) => { if (err) console.error(chalk.red(`日志写入失败: ${err.message}`)); }); } } info(message) { this.log('INFO', message); } warn(message) { this.log('WARN', message); } error(message) { this.log('ERROR', message); } } module.exports = Logger;