semblance-dev/backend/logging_config.py
2025-08-04 09:07:59 -05:00

101 lines
No EOL
3.6 KiB
Python

"""
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
# 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'