Skip to main content
Glama
by Coder-RL
logging.ts5.01 kB
export enum LogLevel { ERROR = 0, WARN = 1, INFO = 2, DEBUG = 3, } export interface LogEntry { timestamp: string; level: string; message: string; metadata?: Record<string, any>; source?: string; traceId?: string; } export interface LoggerConfig { level: LogLevel; enableConsole: boolean; enableFile: boolean; filePath?: string; enableStructured: boolean; source?: string; } class Logger { private config: LoggerConfig; constructor(config: Partial<LoggerConfig> = {}) { this.config = { level: this.parseLogLevel(process.env.LOG_LEVEL) || LogLevel.INFO, enableConsole: process.env.LOG_CONSOLE !== 'false', enableFile: process.env.LOG_FILE === 'true', filePath: process.env.LOG_FILE_PATH || './logs/app.log', enableStructured: process.env.LOG_STRUCTURED === 'true', source: process.env.LOG_SOURCE || 'claude-mcp-server', ...config, }; } private parseLogLevel(level?: string): LogLevel | undefined { if (!level) return undefined; switch (level.toUpperCase()) { case 'ERROR': return LogLevel.ERROR; case 'WARN': return LogLevel.WARN; case 'INFO': return LogLevel.INFO; case 'DEBUG': return LogLevel.DEBUG; default: return undefined; } } private shouldLog(level: LogLevel): boolean { return level <= this.config.level; } private formatMessage(level: LogLevel, message: string, metadata?: Record<string, any>): string { const timestamp = new Date().toISOString(); const levelStr = LogLevel[level]; if (this.config.enableStructured) { const logEntry: LogEntry = { timestamp, level: levelStr, message, metadata, source: this.config.source, }; return JSON.stringify(logEntry); } const metadataStr = metadata ? ` ${JSON.stringify(metadata)}` : ''; return `[${timestamp}] ${levelStr.padEnd(5)} ${message}${metadataStr}`; } private output(level: LogLevel, formattedMessage: string): void { if (this.config.enableConsole) { switch (level) { case LogLevel.ERROR: console.error(formattedMessage); break; case LogLevel.WARN: console.warn(formattedMessage); break; case LogLevel.INFO: console.info(formattedMessage); break; case LogLevel.DEBUG: console.debug(formattedMessage); break; } } // File logging can be implemented here if needed if (this.config.enableFile) { // TODO: Implement file logging } } error(message: string, metadata?: Record<string, any>): void { if (!this.shouldLog(LogLevel.ERROR)) return; const formatted = this.formatMessage(LogLevel.ERROR, message, metadata); this.output(LogLevel.ERROR, formatted); } warn(message: string, metadata?: Record<string, any>): void { if (!this.shouldLog(LogLevel.WARN)) return; const formatted = this.formatMessage(LogLevel.WARN, message, metadata); this.output(LogLevel.WARN, formatted); } info(message: string, metadata?: Record<string, any>): void { if (!this.shouldLog(LogLevel.INFO)) return; const formatted = this.formatMessage(LogLevel.INFO, message, metadata); this.output(LogLevel.INFO, formatted); } debug(message: string, metadata?: Record<string, any>): void { if (!this.shouldLog(LogLevel.DEBUG)) return; const formatted = this.formatMessage(LogLevel.DEBUG, message, metadata); this.output(LogLevel.DEBUG, formatted); } /** * Create a child logger with additional context */ child(source: string, defaultMetadata?: Record<string, any>): Logger { const childLogger = new Logger({ ...this.config, source: `${this.config.source}:${source}`, }); if (defaultMetadata) { // Override methods to include default metadata const originalError = childLogger.error.bind(childLogger); const originalWarn = childLogger.warn.bind(childLogger); const originalInfo = childLogger.info.bind(childLogger); const originalDebug = childLogger.debug.bind(childLogger); childLogger.error = (message: string, metadata?: Record<string, any>) => { originalError(message, { ...defaultMetadata, ...metadata }); }; childLogger.warn = (message: string, metadata?: Record<string, any>) => { originalWarn(message, { ...defaultMetadata, ...metadata }); }; childLogger.info = (message: string, metadata?: Record<string, any>) => { originalInfo(message, { ...defaultMetadata, ...metadata }); }; childLogger.debug = (message: string, metadata?: Record<string, any>) => { originalDebug(message, { ...defaultMetadata, ...metadata }); }; } return childLogger; } } // Create and export the default logger instance export const logger = new Logger(); // Export the Logger class for custom instances export { Logger };

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/Coder-RL/Claude_MCPServer_Dev1'

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