Skip to main content
Glama
logger.ts4.25 kB
export const LogLevel = { ERROR: 0, WARN: 1, INFO: 2, DEBUG: 3, } as const; export type LogLevel = (typeof LogLevel)[keyof typeof LogLevel]; export interface LoggerOptions { level: LogLevel; prefix?: string; timestamp?: boolean; colors?: boolean; } export class Logger { private level: LogLevel; private prefix: string; private timestamp: boolean; private colors: boolean; constructor(options: LoggerOptions = { level: LogLevel.INFO }) { this.level = options.level; this.prefix = options.prefix || ""; this.timestamp = options.timestamp !== false; this.colors = options.colors !== false && process.stdout.isTTY; } private getTimestamp(): string { if (!this.timestamp) return ""; return `[${new Date().toISOString()}] `; } private colorize(text: string, color: string): string { if (!this.colors) return text; const colors: { [key: string]: string } = { reset: "\x1b[0m", red: "\x1b[31m", yellow: "\x1b[33m", blue: "\x1b[34m", green: "\x1b[32m", cyan: "\x1b[36m", magenta: "\x1b[35m", gray: "\x1b[90m", }; return `${colors[color] || ""}${text}${colors.reset}`; } private formatMessage(level: string, message: string, color: string): string { const timestamp = this.getTimestamp(); const prefix = this.prefix ? `[${this.prefix}] ` : ""; const levelStr = this.colorize(`[${level}]`, color); return `${this.colorize(timestamp, "gray")}${levelStr} ${prefix}${message}`; } private log( level: LogLevel, levelName: string, color: string, message: string, ...args: any[] ): void { if (level > this.level) return; const formattedMessage = this.formatMessage(levelName, message, color); if (level === LogLevel.ERROR) { console.error(formattedMessage, ...args); } else { console.log(formattedMessage, ...args); } } error(message: string, ...args: any[]): void { this.log(LogLevel.ERROR, "ERROR", "red", message, ...args); } warn(message: string, ...args: any[]): void { this.log(LogLevel.WARN, "WARN", "yellow", message, ...args); } info(message: string, ...args: any[]): void { this.log(LogLevel.INFO, "INFO", "blue", message, ...args); } debug(message: string, ...args: any[]): void { this.log(LogLevel.DEBUG, "DEBUG", "gray", message, ...args); } success(message: string, ...args: any[]): void { this.log(LogLevel.INFO, "SUCCESS", "green", message, ...args); } // Convenience methods for common scenarios server(message: string, ...args: any[]): void { this.log(LogLevel.INFO, "SERVER", "cyan", message, ...args); } websocket(message: string, ...args: any[]): void { this.log(LogLevel.INFO, "WS", "magenta", message, ...args); } mcp(message: string, ...args: any[]): void { this.log(LogLevel.INFO, "MCP", "cyan", message, ...args); } // Port-specific logging methods portCheck(message: string, ...args: any[]): void { this.log(LogLevel.INFO, "PORT", "blue", message, ...args); } portError(message: string, ...args: any[]): void { this.log(LogLevel.ERROR, "PORT", "red", message, ...args); } portSuccess(message: string, ...args: any[]): void { this.log(LogLevel.INFO, "PORT", "green", message, ...args); } // Create a child logger with additional prefix child(prefix: string): Logger { const childPrefix = this.prefix ? `${this.prefix}:${prefix}` : prefix; return new Logger({ level: this.level, prefix: childPrefix, timestamp: this.timestamp, colors: this.colors, }); } // Set log level at runtime setLevel(level: LogLevel): void { this.level = level; } // Get current log level getLevel(): LogLevel { return this.level; } } // Create default logger instance export const logger = new Logger({ level: process.env.LOG_LEVEL ? (parseInt(process.env.LOG_LEVEL, 10) as LogLevel) : LogLevel.INFO, timestamp: true, colors: true, }); // Create specialized loggers export const serverLogger = logger.child("server"); export const mcpLogger = logger.child("mcp"); export const portLogger = logger.child("port"); export const wsLogger = logger.child("websocket");

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/nfishel48/conduit'

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