UNPKG

mushcode-mcp-server

Version:

A specialized Model Context Protocol server for MUSHCODE development assistance. Provides AI-powered code generation, validation, optimization, and examples for MUD development.

299 lines 8.91 kB
/** * Comprehensive logging system for MUSHCODE MCP Server * Provides structured logging with different levels and contexts */ export var LogLevel; (function (LogLevel) { LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG"; LogLevel[LogLevel["INFO"] = 1] = "INFO"; LogLevel[LogLevel["WARN"] = 2] = "WARN"; LogLevel[LogLevel["ERROR"] = 3] = "ERROR"; LogLevel[LogLevel["FATAL"] = 4] = "FATAL"; })(LogLevel || (LogLevel = {})); /** * Logger class with structured logging capabilities */ export class Logger { static instance; logLevel = LogLevel.INFO; logEntries = []; maxLogEntries = 1000; constructor() { // Set log level from environment variable const envLogLevel = process.env['MUSHCODE_LOG_LEVEL']?.toLowerCase(); switch (envLogLevel) { case 'debug': this.logLevel = LogLevel.DEBUG; break; case 'info': this.logLevel = LogLevel.INFO; break; case 'warn': this.logLevel = LogLevel.WARN; break; case 'error': this.logLevel = LogLevel.ERROR; break; case 'fatal': this.logLevel = LogLevel.FATAL; break; default: this.logLevel = LogLevel.INFO; } } static getInstance() { if (!Logger.instance) { Logger.instance = new Logger(); } return Logger.instance; } /** * Set the minimum log level */ setLogLevel(level) { this.logLevel = level; } /** * Get current log level */ getLogLevel() { return this.logLevel; } /** * Log a debug message */ debug(message, context) { this.log(LogLevel.DEBUG, message, context); } /** * Log an info message */ info(message, context) { this.log(LogLevel.INFO, message, context); } /** * Log a warning message */ warn(message, context) { this.log(LogLevel.WARN, message, context); } /** * Log an error message */ error(message, error, context) { const logEntry = { timestamp: new Date().toISOString(), level: LogLevel.ERROR, message, ...(context && { context }) }; if (error) { logEntry.error = { name: error.name, message: error.message, ...(error.stack && { stack: error.stack }), ...(error.code && { code: error.code }) }; } this.addLogEntry(logEntry); } /** * Log a fatal error message */ fatal(message, error, context) { const logEntry = { timestamp: new Date().toISOString(), level: LogLevel.FATAL, message, ...(context && { context }) }; if (error) { logEntry.error = { name: error.name, message: error.message, ...(error.stack && { stack: error.stack }), ...(error.code && { code: error.code }) }; } this.addLogEntry(logEntry); } /** * Log performance metrics */ performance(operation, duration, context) { const logEntry = { timestamp: new Date().toISOString(), level: LogLevel.INFO, message: `Performance: ${operation} completed in ${duration}ms`, ...(context && { context }), performance: { duration, operation } }; this.addLogEntry(logEntry); } /** * Create a performance timer */ startTimer(operation, context) { const startTime = Date.now(); return () => { const duration = Date.now() - startTime; this.performance(operation, duration, context); }; } /** * Get recent log entries */ getRecentLogs(count = 100) { return this.logEntries.slice(-count); } /** * Get logs by level */ getLogsByLevel(level) { return this.logEntries.filter(entry => entry.level === level); } /** * Clear all log entries */ clearLogs() { this.logEntries = []; } /** * Get log statistics */ getLogStats() { const stats = { total: this.logEntries.length, debug: 0, info: 0, warn: 0, error: 0, fatal: 0 }; for (const entry of this.logEntries) { switch (entry.level) { case LogLevel.DEBUG: stats['debug'] = (stats['debug'] || 0) + 1; break; case LogLevel.INFO: stats['info'] = (stats['info'] || 0) + 1; break; case LogLevel.WARN: stats['warn'] = (stats['warn'] || 0) + 1; break; case LogLevel.ERROR: stats['error'] = (stats['error'] || 0) + 1; break; case LogLevel.FATAL: stats['fatal'] = (stats['fatal'] || 0) + 1; break; } } return stats; } /** * Internal logging method */ log(level, message, context) { if (level < this.logLevel) { return; } const logEntry = { timestamp: new Date().toISOString(), level, message, ...(context && { context }) }; this.addLogEntry(logEntry); } /** * Add log entry and manage log rotation */ addLogEntry(entry) { this.logEntries.push(entry); // Rotate logs if we exceed max entries if (this.logEntries.length > this.maxLogEntries) { this.logEntries = this.logEntries.slice(-this.maxLogEntries); } // Output to console in development if (process.env['NODE_ENV'] !== 'production') { this.outputToConsole(entry); } } /** * Output log entry to console */ outputToConsole(entry) { const levelName = LogLevel[entry.level]; const contextStr = entry.context ? ` [${JSON.stringify(entry.context)}]` : ''; const errorStr = entry.error ? ` Error: ${entry.error.message}` : ''; const perfStr = entry.performance ? ` (${entry.performance.duration}ms)` : ''; const logMessage = `[${entry.timestamp}] ${levelName}: ${entry.message}${contextStr}${errorStr}${perfStr}`; switch (entry.level) { case LogLevel.DEBUG: console.debug(logMessage); break; case LogLevel.INFO: console.info(logMessage); break; case LogLevel.WARN: console.warn(logMessage); break; case LogLevel.ERROR: case LogLevel.FATAL: console.error(logMessage); if (entry.error?.stack) { console.error(entry.error.stack); } break; } } } /** * Global logger instance */ export const logger = Logger.getInstance(); /** * Decorator for logging method calls */ export function logMethodCall(target, propertyName, descriptor) { const method = descriptor.value; descriptor.value = function (...args) { const className = target.constructor.name; const methodName = propertyName; const context = { operation: `${className}.${methodName}` }; logger.debug(`Calling ${className}.${methodName}`, context); const timer = logger.startTimer(`${className}.${methodName}`, context); try { const result = method.apply(this, args); // Handle async methods if (result && typeof result.then === 'function') { return result .then((value) => { timer(); logger.debug(`${className}.${methodName} completed successfully`, context); return value; }) .catch((error) => { timer(); logger.error(`${className}.${methodName} failed`, error, context); throw error; }); } timer(); logger.debug(`${className}.${methodName} completed successfully`, context); return result; } catch (error) { timer(); logger.error(`${className}.${methodName} failed`, error, context); throw error; } }; } //# sourceMappingURL=logger.js.map