Skip to main content
Glama
logger.ts4.79 kB
import pino, { Logger } from 'pino'; /** * Simplified logging context for basic structured logging */ export interface LogContext { component?: string; operation?: string; requestId?: string; [key: string]: any; // Allow additional context } /** * Simple logger configuration */ function createSimpleLogger(): Logger { const isTest = process.env.NODE_ENV === 'test' || process.env.JEST_WORKER_ID !== undefined; // Allow info level in test mode for server startup messages const level = isTest ? 'info' : 'info'; return pino( { level, formatters: { level: (label: string) => ({ level: label }), }, redact: ['password', 'token', 'secret', 'apiKey', 'authorization'], }, process.stderr, ); } /** * Root logger instance */ let rootLogger: Logger; /** * Get or create the root logger */ export function getRootLogger(): Logger { if (!rootLogger) { rootLogger = createSimpleLogger(); } return rootLogger; } /** * Create a child logger with component-specific context */ export function createLogger(componentName: string, baseContext: LogContext = {}): Logger { const root = getRootLogger(); return root.child({ component: componentName, ...baseContext }); } /** * Create a request-scoped logger with correlation ID */ export function createRequestLogger( componentName: string, requestId: string, baseContext: LogContext = {}, ): Logger { return createLogger(componentName, { ...baseContext, requestId }); } /** * Component-specific logger factories (simplified) */ export const loggers = { kuzudb: () => createLogger('KuzuDB'), memoryService: () => createLogger('MemoryService'), controller: () => createLogger('Controller'), mcpStdio: () => createLogger('MCP-Stdio'), mcpHttp: () => createLogger('MCP-HTTP'), repository: () => createLogger('Repository'), search: () => createLogger('Search'), } as const; /** * Simplified performance logging utility */ export class PerformanceLogger { private logger: Logger; private startTime: number; private operation: string; constructor(logger: Logger, operation: string) { this.logger = logger; this.operation = operation; this.startTime = Date.now(); } complete(context: Record<string, any> = {}): void { const duration = Date.now() - this.startTime; this.logger.info({ operation: this.operation, duration, ...context }, 'Operation completed'); } fail(error: Error, context: Record<string, any> = {}): void { const duration = Date.now() - this.startTime; this.logger.error( { operation: this.operation, duration, error: error.message, ...context, }, 'Operation failed', ); } checkpoint(message: string, context: Record<string, any> = {}): void { const elapsed = Date.now() - this.startTime; this.logger.debug({ operation: this.operation, elapsed, ...context }, message); } } /** * Create a performance logger for timing operations */ export function createPerformanceLogger(logger: Logger, operation: string): PerformanceLogger { return new PerformanceLogger(logger, operation); } /** * Simplified error logging utility */ export function logError(logger: Logger, error: Error, context: Record<string, any> = {}): void { logger.error({ error: error.message, stack: error.stack, ...context }, 'Error occurred'); } /** * Middleware function to redirect console.log to stderr for MCP compliance * This should be called early in stdio server initialization */ export function enforceStdioCompliance(): void { // For MCP stdio servers, we need absolutely minimal output to stderr // The sophisticated logging was causing protocol interference // Simple redirection without structured logging to avoid pino-pretty interference const originalConsoleLog = console.log; console.log = (...args: unknown[]): void => { // Direct stderr output without any formatting to avoid MCP protocol interference console.error(...args); }; // Keep console.error as-is for backward compatibility const originalConsoleError = console.error; console.error = (...args: unknown[]): void => { originalConsoleError(...args); }; // Use a simple stderr message instead of structured logging to avoid pretty-printing console.error('stdio compliance enforced - console.log redirected to stderr'); } /** * Export default logger for simple usage */ export const logger = getRootLogger(); /** * Export configured loggers for immediate use */ export const kuzuLogger = loggers.kuzudb(); export const memoryLogger = loggers.memoryService(); export const controllerLogger = loggers.controller(); export const mcpStdioLogger = loggers.mcpStdio(); export const searchLogger = loggers.search();

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/Jakedismo/KuzuMem-MCP'

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