// debug_logger.ts - 调试日志模块 export enum LogLevel { ERROR = 0, WARN = 1, INFO = 2, DEBUG = 3, TRACE = 4 } export interface LogConfig { level: LogLevel; enableTimestamp: boolean; enableColors: boolean; enableFileOutput: boolean; logFilePath?: string; modules: { [moduleName: string]: LogLevel; }; } const DEFAULT_CONFIG: LogConfig = { level: LogLevel.INFO, enableTimestamp: true, enableColors: true, enableFileOutput: false, modules: {} }; class DebugLogger { private config: LogConfig; private logFile?: Deno.FsFile; constructor(config: Partial = {}) { this.config = { ...DEFAULT_CONFIG, ...config }; if (this.config.enableFileOutput && this.config.logFilePath) { this.initLogFile(); } } private async initLogFile() { try { this.logFile = await Deno.open(this.config.logFilePath!, { create: true, write: true, append: true }); } catch (error) { console.error(`Failed to open log file: ${error}`); } } private getTimestamp(): string { if (!this.config.enableTimestamp) return ""; return `[${new Date().toISOString()}] `; } private getColorCode(level: LogLevel): string { if (!this.config.enableColors) return ""; switch (level) { case LogLevel.ERROR: return "\x1b[31m"; // Red case LogLevel.WARN: return "\x1b[33m"; // Yellow case LogLevel.INFO: return "\x1b[36m"; // Cyan case LogLevel.DEBUG: return "\x1b[32m"; // Green case LogLevel.TRACE: return "\x1b[35m"; // Magenta default: return ""; } } private getResetCode(): string { return this.config.enableColors ? "\x1b[0m" : ""; } private getLevelName(level: LogLevel): string { switch (level) { case LogLevel.ERROR: return "ERROR"; case LogLevel.WARN: return "WARN "; case LogLevel.INFO: return "INFO "; case LogLevel.DEBUG: return "DEBUG"; case LogLevel.TRACE: return "TRACE"; default: return "UNKNOWN"; } } private shouldLog(level: LogLevel, module?: string): boolean { // 检查模块特定的日志级别 if (module && this.config.modules[module] !== undefined) { return level <= this.config.modules[module]; } // 使用全局日志级别 return level <= this.config.level; } private formatMessage(level: LogLevel, module: string, message: string, ...args: any[]): string { const timestamp = this.getTimestamp(); const colorCode = this.getColorCode(level); const resetCode = this.getResetCode(); const levelName = this.getLevelName(level); const formattedArgs = args.length > 0 ? " " + args.map(arg => typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg) ).join(" ") : ""; return `${timestamp}${colorCode}[${levelName}]${resetCode} [${module}] ${message}${formattedArgs}`; } private async writeLog(formattedMessage: string) { // 输出到控制台 console.log(formattedMessage); // 输出到文件 if (this.logFile) { try { const encoder = new TextEncoder(); await this.logFile.write(encoder.encode(formattedMessage + "\n")); await this.logFile.sync(); } catch (error) { console.error(`Failed to write to log file: ${error}`); } } } log(level: LogLevel, module: string, message: string, ...args: any[]) { if (!this.shouldLog(level, module)) return; const formattedMessage = this.formatMessage(level, module, message, ...args); this.writeLog(formattedMessage); } error(module: string, message: string, ...args: any[]) { this.log(LogLevel.ERROR, module, message, ...args); } warn(module: string, message: string, ...args: any[]) { this.log(LogLevel.WARN, module, message, ...args); } info(module: string, message: string, ...args: any[]) { this.log(LogLevel.INFO, module, message, ...args); } debug(module: string, message: string, ...args: any[]) { this.log(LogLevel.DEBUG, module, message, ...args); } trace(module: string, message: string, ...args: any[]) { this.log(LogLevel.TRACE, module, message, ...args); } // 设置模块特定的日志级别 setModuleLevel(module: string, level: LogLevel) { this.config.modules[module] = level; } // 设置全局日志级别 setGlobalLevel(level: LogLevel) { this.config.level = level; } // 获取当前配置 getConfig(): LogConfig { return { ...this.config }; } // 关闭日志文件 async close() { if (this.logFile) { await this.logFile.close(); } } } // 创建全局调试器实例 export const debugLogger = new DebugLogger({ level: LogLevel.DEBUG, enableTimestamp: true, enableColors: true, enableFileOutput: false, logFilePath: "./debug.log", modules: { "DEVICE_SIMULATOR": LogLevel.ERROR, "MODBUS": LogLevel.ERROR, "MQTT": LogLevel.ERROR, "REGISTER_CONFIG": LogLevel.ERROR, "DEVICE_MANAGER": LogLevel.ERROR, "SIMULATOR_MAIN": LogLevel.ERROR } }); // 便捷的模块日志器创建函数 export function createModuleLogger(moduleName: string) { return { error: (message: string, ...args: any[]) => debugLogger.error(moduleName, message, ...args), warn: (message: string, ...args: any[]) => debugLogger.warn(moduleName, message, ...args), info: (message: string, ...args: any[]) => debugLogger.info(moduleName, message, ...args), debug: (message: string, ...args: any[]) => debugLogger.debug(moduleName, message, ...args), trace: (message: string, ...args: any[]) => debugLogger.trace(moduleName, message, ...args) }; } // 性能监控工具 export class PerformanceMonitor { private timers: Map = new Map(); private logger = createModuleLogger("PERFORMANCE"); start(label: string) { this.timers.set(label, performance.now()); this.logger.trace(`⏱️ Started timer: ${label}`); } end(label: string): number { const startTime = this.timers.get(label); if (!startTime) { this.logger.trace(`⚠️ Timer not found: ${label}`); return 0; } const duration = performance.now() - startTime; this.timers.delete(label); this.logger.trace(`⏱️ ${label}: ${duration.toFixed(2)}ms`); return duration; } measure(label: string, fn: () => T): T { this.start(label); try { const result = fn(); this.end(label); return result; } catch (error) { this.end(label); this.logger.error(`❌ Error in ${label}:`, error); throw error; } } async measureAsync(label: string, fn: () => Promise): Promise { this.start(label); try { const result = await fn(); this.end(label); return result; } catch (error) { this.end(label); this.logger.error(`❌ Error in ${label}:`, error); throw error; } } } export const perfMonitor = new PerformanceMonitor(); // 内存使用监控 export function logMemoryUsage(module: string) { if (typeof Deno !== 'undefined' && Deno.memoryUsage) { const memory = Deno.memoryUsage(); const logger = createModuleLogger(module); logger.debug(`💾 Memory usage:`, { rss: `${(memory.rss / 1024 / 1024).toFixed(2)}MB`, heapTotal: `${(memory.heapTotal / 1024 / 1024).toFixed(2)}MB`, heapUsed: `${(memory.heapUsed / 1024 / 1024).toFixed(2)}MB`, external: `${(memory.external / 1024 / 1024).toFixed(2)}MB` }); } } // 调试配置管理 export function setDebugLevel(level: LogLevel | string, module?: string) { const logLevel = typeof level === 'string' ? LogLevel[level.toUpperCase() as keyof typeof LogLevel] : level; if (module) { debugLogger.setModuleLevel(module, logLevel); console.log(`🔧 Set debug level for ${module}: ${LogLevel[logLevel]}`); } else { debugLogger.setGlobalLevel(logLevel); console.log(`🔧 Set global debug level: ${LogLevel[logLevel]}`); } } // 调试工具已在上面导出