103 lines
No EOL
3.8 KiB
Python
Executable file
103 lines
No EOL
3.8 KiB
Python
Executable file
"""
|
|
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' |