azureai-optimizer
Version:
AI-Powered Azure Infrastructure Optimization via Model Context Protocol
207 lines âĸ 6.66 kB
JavaScript
/**
* 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