UNPKG

@songm_d/standalone-toolbar-service

Version:

独立的Stagewise工具栏服务 - 支持SRPC通信和WebSocket广播,可与MCP反馈收集器集成

155 lines (154 loc) 5.18 kB
import fs from 'fs'; import path from 'path'; const LOG_LEVELS = { error: 0, warn: 1, info: 2, debug: 3, silent: 999 }; const LOG_COLORS = { error: '\x1b[31m', warn: '\x1b[33m', info: '\x1b[36m', debug: '\x1b[37m', silent: '' }; const RESET_COLOR = '\x1b[0m'; class Logger { constructor() { this.currentLevel = 'info'; this.fileLoggingEnabled = false; this.colorsDisabled = false; } setLevel(level) { this.currentLevel = level; } getLevel() { return this.currentLevel; } disableColors() { this.colorsDisabled = true; } enableFileLogging(logDir = 'logs') { try { if (!fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }); } const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); this.logFile = path.join(logDir, `toolbar-service-${timestamp}.log`); this.fileLoggingEnabled = true; const header = `=== Standalone Toolbar Service Log ===\n` + `Start Time: ${new Date().toISOString()}\n` + `Log Level: ${this.currentLevel}\n` + `======================================\n\n`; fs.writeFileSync(this.logFile, header); console.log(`📁 日志文件已创建: ${this.logFile}`); } catch (error) { console.error('❌ 无法创建日志文件:', error); this.fileLoggingEnabled = false; } } shouldLog(level) { if (this.currentLevel === 'silent') { return false; } return LOG_LEVELS[level] <= LOG_LEVELS[this.currentLevel]; } formatTimestamp() { const now = new Date(); const month = String(now.getMonth() + 1).padStart(2, '0'); const day = String(now.getDate()).padStart(2, '0'); const hours = String(now.getHours()).padStart(2, '0'); const minutes = String(now.getMinutes()).padStart(2, '0'); const seconds = String(now.getSeconds()).padStart(2, '0'); return `${month}-${day} ${hours}:${minutes}:${seconds}`; } formatMessage(level, message, ...args) { const timestamp = this.formatTimestamp(); const levelStr = level.toUpperCase().padEnd(5); let formattedMessage; if (this.colorsDisabled) { formattedMessage = `[${timestamp}] ${levelStr} ${message}`; } else { const color = LOG_COLORS[level]; formattedMessage = `${color}[${timestamp}] ${levelStr}${RESET_COLOR} ${message}`; } if (args.length > 0) { const argsStr = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)).join(' '); formattedMessage += ` ${argsStr}`; } return formattedMessage; } log(level, message, ...args) { if (!this.shouldLog(level)) return; const formattedMessage = this.formatMessage(level, message, ...args); if (level === 'error') { console.error(formattedMessage); } else if (level === 'warn') { console.warn(formattedMessage); } else { console.log(formattedMessage); } if (this.fileLoggingEnabled && this.logFile) { try { const cleanMessage = this.removeColorCodes(formattedMessage); fs.appendFileSync(this.logFile, cleanMessage + '\n'); } catch (error) { console.error('❌ 写入日志文件失败:', error); } } } removeColorCodes(text) { return text.replace(/\x1b\[[0-9;]*m/g, ''); } error(message, ...args) { this.log('error', message, ...args); } warn(message, ...args) { this.log('warn', message, ...args); } info(message, ...args) { this.log('info', message, ...args); } debug(message, ...args) { this.log('debug', message, ...args); } request(method, url, statusCode, duration) { let message = `${method} ${url}`; if (statusCode !== undefined) { message += ` - ${statusCode}`; } if (duration !== undefined) { message += ` (${duration}ms)`; } this.info(`[HTTP] ${message}`); } socket(event, sessionId, data) { let message = `[WebSocket] ${event}`; if (sessionId) { message += ` (session: ${sessionId})`; } if (data !== undefined) { message += ` - ${typeof data === 'object' ? JSON.stringify(data) : data}`; } this.debug(message); } toolbar(action, params, result) { let message = `[Toolbar] ${action}`; if (params !== undefined) { message += ` - params: ${typeof params === 'object' ? JSON.stringify(params) : params}`; } if (result !== undefined) { message += ` - result: ${typeof result === 'object' ? JSON.stringify(result) : result}`; } this.debug(message); } } export const logger = new Logger();