""" Custom logging configuration for the application to reduce noise. """ import logging import sys from typing import Dict, Any class CustomHTTPFilter(logging.Filter): """Filter to reduce noise from routine HTTP requests.""" # Define routes that should be logged only on errors/warnings QUIET_ROUTES = { '/api/focus-groups/', '/api/focus-group-ai/key-themes/', '/api/focus-group-ai/autonomous/status/', '/api/personas', '/api/ai-personas', '/static/', '/favicon.ico', '/health', '/ping' } # Define HTTP methods that should be quiet for routine operations QUIET_METHODS = {'GET', 'OPTIONS'} def filter(self, record: logging.LogRecord) -> bool: """Filter log records to reduce noise from routine operations.""" # Allow all non-HTTP logs if not hasattr(record, 'pathname') and not hasattr(record, 'msg'): return True # Check if this is an HTTP access log msg = str(record.msg) if hasattr(record, 'msg') else str(record) # If it's not an HTTP request log, allow it if not any(method in msg for method in ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS']): return True # Check if it's a successful response (2xx) to a quiet route if any(route in msg for route in self.QUIET_ROUTES): # Allow if it's an error response (4xx, 5xx) or warning/error level if record.levelno >= logging.WARNING: return True # Check if it's a successful response (2xx) if ' 2' in msg and any(method in msg for method in self.QUIET_METHODS): return False # Filter out successful GET requests to quiet routes return True def setup_logging(log_level: str = 'INFO') -> None: """Setup custom logging configuration.""" # Convert log level string to logging constant numeric_level = getattr(logging, log_level.upper(), logging.INFO) # Create custom formatter formatter = logging.Formatter( '[%(asctime)s] %(levelname)s in %(name)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) # Setup root logger root_logger = logging.getLogger() root_logger.setLevel(numeric_level) # Clear existing handlers root_logger.handlers.clear() # Create console handler console_handler = logging.StreamHandler(sys.stdout) console_handler.setFormatter(formatter) console_handler.setLevel(numeric_level) # Add custom filter to reduce HTTP noise http_filter = CustomHTTPFilter() console_handler.addFilter(http_filter) root_logger.addHandler(console_handler) # Set specific logger levels logging.getLogger('pymongo').setLevel(logging.WARNING) # Reduce MongoDB driver noise logging.getLogger('werkzeug').setLevel(logging.WARNING) # Reduce Flask dev server noise logging.getLogger('hypercorn').setLevel(logging.WARNING) # Reduce Hypercorn noise logging.getLogger('hypercorn.access').setLevel(logging.WARNING) # Reduce access log noise logging.getLogger('engineio.server').setLevel(logging.WARNING) # Reduce WebSocket PING/PONG spam logging.getLogger('socketio.server').setLevel(logging.WARNING) # Reduce WebSocket noise # Keep application loggers at INFO level logging.getLogger('app').setLevel(numeric_level) # Setup MongoDB connection logging to be quieter logging.getLogger('app.db').setLevel(logging.WARNING) def create_app_logger(name: str) -> logging.Logger: """Create a logger for application modules.""" logger = logging.getLogger(f'app.{name}') return logger # Default configuration - changed to DEBUG for troubleshooting DEFAULT_LOG_LEVEL = 'INFO'