@songm_d/standalone-toolbar-service
Version:
独立的Stagewise工具栏服务 - 支持SRPC通信和WebSocket广播,可与MCP反馈收集器集成
155 lines (154 loc) • 5.18 kB
JavaScript
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();