Skip to main content
Glama
ogbm77

Cisco CX Cloud MCP Server

by ogbm77
logger.ts4.69 kB
import * as fs from 'fs'; import * as path from 'path'; export enum LogLevel { ERROR = 0, WARN = 1, INFO = 2, DEBUG = 3, } export class Logger { private logLevel: LogLevel; private logToFile: boolean; private logFilePath: string; constructor() { // Read log level from environment (default: INFO) const envLevel = process.env.LOG_LEVEL?.toUpperCase() || 'INFO'; this.logLevel = LogLevel[envLevel as keyof typeof LogLevel] ?? LogLevel.INFO; // Read log to file setting this.logToFile = process.env.LOG_TO_FILE === 'true'; // Set log file path const logDir = process.env.LOG_DIR || './logs'; if (this.logToFile && !fs.existsSync(logDir)) { fs.mkdirSync(logDir, { recursive: true }); } const timestamp = new Date().toISOString().split('T')[0]; this.logFilePath = path.join(logDir, `mcp-server-${timestamp}.log`); } private shouldLog(level: LogLevel): boolean { return level <= this.logLevel; } private formatMessage(level: string, message: string, data?: any): string { const timestamp = new Date().toISOString(); let formatted = `[${timestamp}] [${level}] ${message}`; if (data !== undefined) { if (typeof data === 'object') { formatted += `\n${JSON.stringify(data, null, 2)}`; } else { formatted += ` ${data}`; } } return formatted; } private write(level: string, message: string, data?: any): void { const formatted = this.formatMessage(level, message, data); // Always write to stderr for MCP compatibility console.error(formatted); // Optionally write to file if (this.logToFile) { try { fs.appendFileSync(this.logFilePath, formatted + '\n'); } catch (error) { console.error(`Failed to write to log file: ${error}`); } } } error(message: string, error?: any): void { if (this.shouldLog(LogLevel.ERROR)) { const errorData = error instanceof Error ? { message: error.message, stack: error.stack } : error; this.write('ERROR', message, errorData); } } warn(message: string, data?: any): void { if (this.shouldLog(LogLevel.WARN)) { this.write('WARN', message, data); } } info(message: string, data?: any): void { if (this.shouldLog(LogLevel.INFO)) { this.write('INFO', message, data); } } debug(message: string, data?: any): void { if (this.shouldLog(LogLevel.DEBUG)) { this.write('DEBUG', message, data); } } // Special logging for API requests apiRequest(method: string, url: string, headers?: any): void { if (this.shouldLog(LogLevel.DEBUG)) { const sanitizedHeaders = this.sanitizeHeaders(headers); this.debug(`API Request: ${method} ${url}`, { headers: sanitizedHeaders }); } } // Special logging for API responses apiResponse(method: string, url: string, status: number, data?: any): void { if (this.shouldLog(LogLevel.DEBUG)) { const summary = data ? this.summarizeData(data) : 'No data'; this.debug(`API Response: ${method} ${url} - ${status}`, { summary }); } } // Special logging for API errors apiError(method: string, url: string, error: any): void { const errorInfo = { status: error.response?.status, statusText: error.response?.statusText, message: error.message, data: error.response?.data, }; this.error(`API Error: ${method} ${url}`, errorInfo); } // Sanitize sensitive data from headers private sanitizeHeaders(headers?: any): any { if (!headers) return {}; const sanitized = { ...headers }; if (sanitized.Authorization) { sanitized.Authorization = 'Bearer ***'; } return sanitized; } // Summarize response data to avoid logging huge payloads private summarizeData(data: any): any { if (Array.isArray(data)) { return `Array with ${data.length} items`; } if (typeof data === 'object') { return `Object with keys: ${Object.keys(data).join(', ')}`; } return data; } // Log tool invocation toolInvoked(toolName: string, args?: any): void { if (this.shouldLog(LogLevel.INFO)) { this.info(`Tool invoked: ${toolName}`, { arguments: args }); } } // Log tool completion toolCompleted(toolName: string, success: boolean, duration?: number): void { if (this.shouldLog(LogLevel.INFO)) { const status = success ? 'SUCCESS' : 'FAILED'; const message = `Tool ${status}: ${toolName}`; const data = duration ? { duration: `${duration}ms` } : undefined; this.info(message, data); } } } // Export singleton instance export const logger = new Logger();

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ogbm77/cisco-cx-cloud-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server