UNPKG

azureai-optimizer

Version:

AI-Powered Azure Infrastructure Optimization via Model Context Protocol

207 lines â€ĸ 6.66 kB
/** * Logger Utility * Centralized logging with configurable levels and formatting */ export class Logger { component; static logLevel = 'info'; static logLevels = { debug: 0, info: 1, warn: 2, error: 3 }; constructor(component) { this.component = component; } static setLogLevel(level) { this.logLevel = level; } static getLogLevel() { return this.logLevel; } shouldLog(level) { return Logger.logLevels[level] >= Logger.logLevels[Logger.logLevel]; } formatMessage(level, message, data) { const timestamp = new Date().toISOString(); const levelIcon = this.getLevelIcon(level); const levelColor = this.getLevelColor(level); const resetColor = '\x1b[0m'; let formattedMessage = `${levelColor}${timestamp} ${levelIcon} [${this.component}] ${message}${resetColor}`; if (data !== undefined) { if (typeof data === 'object') { formattedMessage += `\n${JSON.stringify(data, null, 2)}`; } else { formattedMessage += ` ${data}`; } } return formattedMessage; } getLevelIcon(level) { switch (level) { case 'debug': return '🔍'; case 'info': return 'â„šī¸'; case 'warn': return 'âš ī¸'; case 'error': return '❌'; default: return '📝'; } } getLevelColor(level) { switch (level) { case 'debug': return '\x1b[36m'; // Cyan case 'info': return '\x1b[32m'; // Green case 'warn': return '\x1b[33m'; // Yellow case 'error': return '\x1b[31m'; // Red default: return '\x1b[0m'; // Reset } } log(level, message, data) { if (!this.shouldLog(level)) { return; } // When running as MCP server in stdio mode, don't log to stdout/stderr // as it interferes with the protocol const isMCPStdio = process.env.MCP_TRANSPORT === 'stdio' || (!process.env.MCP_TRANSPORT && process.argv.includes('server') && process.argv.includes('start')); if (!isMCPStdio) { const formattedMessage = this.formatMessage(level, message, data); // Write to appropriate stream if (level === 'error') { console.error(formattedMessage); } else { console.log(formattedMessage); } } // In production, you might want to send logs to external services this.sendToExternalLogger(level, message, data); } sendToExternalLogger(_level, _message, _data) { // Placeholder for external logging services (Application Insights, etc.) // This would be implemented based on the monitoring configuration // Example: Send to Application Insights if (process.env.APPLICATIONINSIGHTS_CONNECTION_STRING) { // Log entry would be sent to Application Insights // const logEntry: LogEntry = { // timestamp: new Date().toISOString(), // level, // component: this.component, // message, // data // }; // Implementation would go here } } debug(message, data) { this.log('debug', message, data); } info(message, data) { this.log('info', message, data); } warn(message, data) { this.log('warn', message, data); } error(message, data) { this.log('error', message, data); } // Convenience methods for common logging patterns startOperation(operation) { this.info(`🚀 Starting ${operation}...`); } completeOperation(operation, duration) { const durationText = duration ? ` (${duration}ms)` : ''; this.info(`✅ Completed ${operation}${durationText}`); } failOperation(operation, error) { this.error(`❌ Failed ${operation}:`, error); } // Performance logging time(label) { console.time(`[${this.component}] ${label}`); } timeEnd(label) { console.timeEnd(`[${this.component}] ${label}`); } // Structured logging for metrics metric(name, value, unit, tags) { const metricData = { metric: name, value, unit, tags, timestamp: new Date().toISOString() }; this.debug(`📊 Metric: ${name}`, metricData); } // Security-related logging securityEvent(event, details) { const securityData = { event, details, timestamp: new Date().toISOString(), component: this.component }; this.warn(`🔒 Security Event: ${event}`, securityData); } // API call logging apiCall(method, url, statusCode, duration) { const apiData = { method, url, statusCode, duration, timestamp: new Date().toISOString() }; if (statusCode && statusCode >= 400) { this.warn(`🌐 API Call Failed: ${method} ${url}`, apiData); } else { this.debug(`🌐 API Call: ${method} ${url}`, apiData); } } // User action logging userAction(action, userId, details) { const actionData = { action, userId, details, timestamp: new Date().toISOString() }; this.info(`👤 User Action: ${action}`, actionData); } // Cost-related logging costEvent(event, amount, currency, details) { const costData = { event, amount, currency, details, timestamp: new Date().toISOString() }; this.info(`💰 Cost Event: ${event}`, costData); } // Tool execution logging toolExecution(toolName, status, duration, error) { const toolData = { tool: toolName, status, duration, error, timestamp: new Date().toISOString() }; switch (status) { case 'start': this.info(`🔧 Tool Started: ${toolName}`); break; case 'success': this.info(`✅ Tool Completed: ${toolName}`, toolData); break; case 'error': this.error(`❌ Tool Failed: ${toolName}`, toolData); break; } } } //# sourceMappingURL=logger.js.map