/** * MCP Outline PostgreSQL - Logger * Optimized for MCP - reduce logs to not exhaust Claude context * @author Descomplicar® | @link descomplicar.pt | @copyright 2026 */ type LogLevel = 'error' | 'warn' | 'info' | 'debug'; interface LogEntry { timestamp: string; level: LogLevel; message: string; data?: Record; } const LOG_LEVELS: Record = { error: 0, warn: 1, info: 2, debug: 3 }; class Logger { private level: LogLevel; constructor() { this.level = (process.env.LOG_LEVEL as LogLevel) || 'error'; } private shouldLog(level: LogLevel): boolean { return LOG_LEVELS[level] <= LOG_LEVELS[this.level]; } private formatLog(level: LogLevel, message: string, data?: Record): string { const entry: LogEntry = { timestamp: new Date().toISOString(), level, message, ...(data && { data }) }; return JSON.stringify(entry); } private write(level: LogLevel, message: string, data?: Record): void { if (!this.shouldLog(level)) return; const formatted = this.formatLog(level, message, data); // For MCP, send logs to stderr if (process.env.MCP_MODE !== 'false') { process.stderr.write(formatted + '\n'); } else { console.log(formatted); } } error(message: string, data?: Record): void { this.write('error', message, data); } warn(message: string, data?: Record): void { this.write('warn', message, data); } info(message: string, data?: Record): void { this.write('info', message, data); } debug(message: string, data?: Record): void { this.write('debug', message, data); } } export const logger = new Logger(); // Log queries for auditing (if enabled) - OPTIMIZED export function logQuery( sql: string, _params?: any[], duration?: number, _clientId?: string ): void { // DISABLED by default to save Claude context if (process.env.ENABLE_AUDIT_LOG === 'true' && process.env.NODE_ENV !== 'production') { logger.debug('SQL', { sql: sql.substring(0, 50), duration }); } }