Skip to main content
Glama

Debugg AI MCP

Official
by debugg-ai
logger.tsโ€ข4.86 kB
/** * Centralized logging utility using Winston * Replaces all console.error calls with structured logging */ import winston from 'winston'; import { config } from '../config/index.js'; import { LogLevel, LogContext } from '../types/index.js'; /** * Create winston logger instance */ const createLogger = (): winston.Logger => { const { level, format } = config.logging; const logFormat = format === 'json' ? winston.format.combine( winston.format.timestamp(), winston.format.errors({ stack: true }), winston.format.json() ) : winston.format.combine( winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), winston.format.errors({ stack: true }), winston.format.printf(({ timestamp, level, message, ...meta }) => { const metaStr = Object.keys(meta).length > 0 ? ` ${JSON.stringify(meta)}` : ''; return `[${timestamp}] ${level.toUpperCase()}: ${message}${metaStr}`; }) ); return winston.createLogger({ level, format: logFormat, transports: [ new winston.transports.Console({ stderrLevels: ['error', 'warn', 'info', 'debug'], }), ], // Ensure uncaught exceptions and rejections are logged exceptionHandlers: [ new winston.transports.Console({ format: winston.format.combine( winston.format.timestamp(), winston.format.errors({ stack: true }), winston.format.json() ), }), ], rejectionHandlers: [ new winston.transports.Console({ format: winston.format.combine( winston.format.timestamp(), winston.format.errors({ stack: true }), winston.format.json() ), }), ], }); }; /** * Global logger instance - created lazily to avoid import-time config loading */ let _logger: winston.Logger | undefined; export const logger = { error: (message: string, meta?: any) => getLogger().error(message, meta), warn: (message: string, meta?: any) => getLogger().warn(message, meta), info: (message: string, meta?: any) => getLogger().info(message, meta), debug: (message: string, meta?: any) => getLogger().debug(message, meta), }; function getLogger(): winston.Logger { if (!_logger) { _logger = createLogger(); } return _logger; } /** * Enhanced logging functions with context support */ export class Logger { private context: LogContext; constructor(context: LogContext = {}) { this.context = context; } /** * Create a child logger with additional context */ child(additionalContext: LogContext): Logger { return new Logger({ ...this.context, ...additionalContext }); } /** * Log error messages */ error(message: string, meta?: any): void { logger.error(message, { ...this.context, ...meta }); } /** * Log warning messages */ warn(message: string, meta?: any): void { logger.warn(message, { ...this.context, ...meta }); } /** * Log info messages */ info(message: string, meta?: any): void { logger.info(message, { ...this.context, ...meta }); } /** * Log debug messages */ debug(message: string, meta?: any): void { logger.debug(message, { ...this.context, ...meta }); } /** * Log tool execution start */ toolStart(toolName: string, input: any): void { this.info(`Tool execution started: ${toolName}`, { toolName, input: this.sanitizeInput(input) }); } /** * Log tool execution completion */ toolComplete(toolName: string, duration: number): void { this.info(`Tool execution completed: ${toolName}`, { toolName, duration: `${duration}ms` }); } /** * Log tool execution error */ toolError(toolName: string, error: Error, duration: number): void { this.error(`Tool execution failed: ${toolName}`, { toolName, error: error.message, stack: error.stack, duration: `${duration}ms` }); } /** * Log progress updates */ progress(message: string, progress: number, total: number): void { this.info(`Progress: ${message}`, { progress, total, percentage: Math.round((progress / total) * 100) }); } /** * Sanitize input data for logging (remove sensitive information) */ private sanitizeInput(input: any): any { if (typeof input !== 'object' || input === null) { return input; } const sanitized = { ...input }; const sensitiveKeys = ['password', 'token', 'key', 'secret', 'apiKey']; for (const key of Object.keys(sanitized)) { if (sensitiveKeys.some(sensitive => key.toLowerCase().includes(sensitive))) { sanitized[key] = '[REDACTED]'; } } return sanitized; } } /** * Default logger instance */ export const defaultLogger = new 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/debugg-ai/debugg-ai-mcp'

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