UNPKG

@spaik/mcp-server-roi

Version:

MCP server for AI ROI prediction and tracking with Monte Carlo simulations

144 lines 5.31 kB
export var LogLevel; (function (LogLevel) { LogLevel[LogLevel["ERROR"] = 0] = "ERROR"; LogLevel[LogLevel["WARN"] = 1] = "WARN"; LogLevel[LogLevel["INFO"] = 2] = "INFO"; LogLevel[LogLevel["DEBUG"] = 3] = "DEBUG"; LogLevel[LogLevel["TRACE"] = 4] = "TRACE"; })(LogLevel || (LogLevel = {})); class Logger { static instance; logLevel; isProduction; constructor() { this.logLevel = this.parseLogLevel(process.env.LOG_LEVEL || 'INFO'); this.isProduction = process.env.NODE_ENV === 'production'; } static getInstance() { if (!Logger.instance) { Logger.instance = new Logger(); } return Logger.instance; } parseLogLevel(level) { switch (level.toUpperCase()) { case 'ERROR': return LogLevel.ERROR; case 'WARN': return LogLevel.WARN; case 'INFO': return LogLevel.INFO; case 'DEBUG': return LogLevel.DEBUG; case 'TRACE': return LogLevel.TRACE; default: return LogLevel.INFO; } } shouldLog(level) { return level <= this.logLevel; } formatMessage(entry) { const levelStr = LogLevel[entry.level].padEnd(5); if (this.isProduction) { // Structured JSON logging for production return JSON.stringify({ timestamp: entry.timestamp, level: LogLevel[entry.level], message: entry.message, ...(entry.context && { context: entry.context }), ...(entry.error && { error: { name: entry.error.name, message: entry.error.message, stack: entry.error.stack } }) }); } else { // Human-readable format for development let output = `[${entry.timestamp}] ${levelStr} ${entry.message}`; if (entry.context && Object.keys(entry.context).length > 0) { output += ` | ${JSON.stringify(entry.context)}`; } if (entry.error) { output += `\n Error: ${entry.error.message}`; if (entry.error.stack) { output += `\n Stack: ${entry.error.stack}`; } } return output; } } log(level, message, context, error) { if (!this.shouldLog(level)) return; const entry = { timestamp: new Date().toISOString(), level, message, context, error }; const formattedMessage = this.formatMessage(entry); // Write to stderr to avoid mixing with MCP protocol messages on stdout console.error(formattedMessage); } error(message, error, context) { this.log(LogLevel.ERROR, message, context, error); } warn(message, context) { this.log(LogLevel.WARN, message, context); } info(message, context) { this.log(LogLevel.INFO, message, context); } debug(message, context) { this.log(LogLevel.DEBUG, message, context); } trace(message, context) { this.log(LogLevel.TRACE, message, context); } // Helper method for timing operations time(label) { const start = Date.now(); this.debug(`Timer started: ${label}`); return () => { const duration = Date.now() - start; this.debug(`Timer completed: ${label}`, { duration_ms: duration }); }; } // Helper method for logging method entry/exit methodEntry(className, methodName, args) { this.trace(`Entering ${className}.${methodName}`, { args }); } methodExit(className, methodName, result) { this.trace(`Exiting ${className}.${methodName}`, { result }); } // Helper method for logging async operations async asyncOperation(operationName, operation, context) { const endTimer = this.time(operationName); this.debug(`Starting async operation: ${operationName}`, context); try { const result = await operation(); this.debug(`Completed async operation: ${operationName}`, { ...context, success: true }); return result; } catch (error) { this.error(`Failed async operation: ${operationName}`, error, context); throw error; } finally { endTimer(); } } } // Export singleton instance export const logger = Logger.getInstance(); // Export helper function for child loggers with context export function createLogger(context) { return { error: (message, error, additionalContext) => logger.error(message, error, { ...context, ...additionalContext }), warn: (message, additionalContext) => logger.warn(message, { ...context, ...additionalContext }), info: (message, additionalContext) => logger.info(message, { ...context, ...additionalContext }), debug: (message, additionalContext) => logger.debug(message, { ...context, ...additionalContext }), trace: (message, additionalContext) => logger.trace(message, { ...context, ...additionalContext }) }; } //# sourceMappingURL=logger.js.map