Add structured logging throughout the backend: - logging_config.py: Centralized logging configuration with colored output - main.py: Enhanced startup logging showing initialization progress - init_blockchain.py: Detailed blockchain initialization logging - services.py: Election creation logging Logging features: - Emoji prefixes for different log levels (INFO, DEBUG, ERROR, etc.) - Color-coded output for better visibility - Timestamp and module information - Exception stack traces on errors - Separate loggers for different modules This helps debug: - Backend startup sequence - Database initialization - Blockchain election recording - Service operations - Configuration issues
94 lines
2.8 KiB
Python
94 lines
2.8 KiB
Python
"""
|
||
Logging configuration for E-Voting Backend.
|
||
|
||
Provides structured logging with appropriate levels for different modules.
|
||
"""
|
||
|
||
import logging
|
||
import sys
|
||
from datetime import datetime
|
||
|
||
# Create custom formatter with emojis and colors
|
||
class ColoredFormatter(logging.Formatter):
|
||
"""Custom formatter with colors and emojis for better visibility"""
|
||
|
||
# ANSI color codes
|
||
COLORS = {
|
||
'DEBUG': '\033[36m', # Cyan
|
||
'INFO': '\033[32m', # Green
|
||
'WARNING': '\033[33m', # Yellow
|
||
'ERROR': '\033[31m', # Red
|
||
'CRITICAL': '\033[35m', # Magenta
|
||
}
|
||
RESET = '\033[0m'
|
||
|
||
# Emoji prefixes
|
||
EMOJIS = {
|
||
'DEBUG': '🔍',
|
||
'INFO': 'ℹ️ ',
|
||
'WARNING': '⚠️ ',
|
||
'ERROR': '❌',
|
||
'CRITICAL': '🔥',
|
||
}
|
||
|
||
def format(self, record):
|
||
# Add color and emoji
|
||
levelname = record.levelname
|
||
emoji = self.EMOJIS.get(levelname, '')
|
||
color = self.COLORS.get(levelname, '')
|
||
|
||
# Format message
|
||
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
||
formatted = f"{color}{emoji} {timestamp} - {record.name} - {levelname} - {record.getMessage()}{self.RESET}"
|
||
|
||
# Add exception info if present
|
||
if record.exc_info:
|
||
formatted += f"\n{self.format_exception(record.exc_info)}"
|
||
|
||
return formatted
|
||
|
||
def format_exception(self, exc_info):
|
||
"""Format exception info"""
|
||
import traceback
|
||
return '\n'.join(traceback.format_exception(*exc_info))
|
||
|
||
|
||
def setup_logging(level=logging.INFO):
|
||
"""
|
||
Setup logging for the entire application.
|
||
|
||
Args:
|
||
level: Logging level (default: logging.INFO)
|
||
"""
|
||
# Remove existing handlers
|
||
root_logger = logging.getLogger()
|
||
for handler in root_logger.handlers[:]:
|
||
root_logger.removeHandler(handler)
|
||
|
||
# Create console handler with colored formatter
|
||
console_handler = logging.StreamHandler(sys.stdout)
|
||
console_handler.setLevel(level)
|
||
formatter = ColoredFormatter()
|
||
console_handler.setFormatter(formatter)
|
||
|
||
# Add handler to root logger
|
||
root_logger.addHandler(console_handler)
|
||
root_logger.setLevel(level)
|
||
|
||
# Set specific loggers
|
||
logging.getLogger('backend').setLevel(level)
|
||
logging.getLogger('backend.blockchain_elections').setLevel(logging.DEBUG)
|
||
logging.getLogger('backend.init_blockchain').setLevel(logging.INFO)
|
||
logging.getLogger('backend.services').setLevel(logging.INFO)
|
||
logging.getLogger('backend.main').setLevel(logging.INFO)
|
||
|
||
# Suppress verbose third-party logging
|
||
logging.getLogger('sqlalchemy.engine').setLevel(logging.WARNING)
|
||
logging.getLogger('sqlalchemy.pool').setLevel(logging.WARNING)
|
||
logging.getLogger('uvicorn').setLevel(logging.INFO)
|
||
logging.getLogger('uvicorn.access').setLevel(logging.WARNING)
|
||
|
||
|
||
# Setup logging on import
|
||
setup_logging()
|