Spaces:
Sleeping
Sleeping
File size: 3,292 Bytes
2929135 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# src/utils/logger.py
import logging
import sys
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
from pathlib import Path
from datetime import datetime
from typing import Optional
from ..config.settings import Settings
class CustomFormatter(logging.Formatter):
"""Custom formatter with color coding for different log levels"""
COLORS = {
'DEBUG': '\033[0;36m', # Cyan
'INFO': '\033[0;32m', # Green
'WARNING': '\033[0;33m', # Yellow
'ERROR': '\033[0;31m', # Red
'CRITICAL': '\033[0;37;41m' # White on Red
}
RESET = '\033[0m'
def format(self, record):
# Add color to log level if on console
if hasattr(self, 'use_color') and self.use_color:
record.levelname = f"{self.COLORS.get(record.levelname, '')}{record.levelname}{self.RESET}"
return super().format(record)
def setup_logger(
name: str,
log_level: Optional[str] = None,
log_file: Optional[str] = None
) -> logging.Logger:
"""
Set up logger with both file and console handlers
Args:
name: Logger name
log_level: Optional override for log level
log_file: Optional override for log file path
Returns:
Configured logger instance
"""
try:
# Create logger
logger = logging.getLogger(name)
logger.setLevel(log_level or Settings.LOG_LEVEL)
# Avoid adding handlers if they already exist
if logger.handlers:
return logger
# Create formatters
file_formatter = logging.Formatter(
'%(asctime)s - %(name)s - [%(levelname)s] - %(message)s'
)
console_formatter = CustomFormatter(
'%(asctime)s - %(name)s - [%(levelname)s] - %(message)s'
)
console_formatter.use_color = True
# Create and configure file handler
log_file = log_file or Settings.LOG_FILE
log_dir = Path(log_file).parent
log_dir.mkdir(parents=True, exist_ok=True)
# Rotating file handler (size-based)
file_handler = RotatingFileHandler(
log_file,
maxBytes=10 * 1024 * 1024, # 10MB
backupCount=5
)
file_handler.setFormatter(file_formatter)
# Time-based rotating handler for daily logs
daily_handler = TimedRotatingFileHandler(
str(log_dir / f"daily_{datetime.now():%Y-%m-%d}.log"),
when="midnight",
interval=1,
backupCount=30
)
daily_handler.setFormatter(file_formatter)
# Console handler
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setFormatter(console_formatter)
# Add handlers
logger.addHandler(file_handler)
logger.addHandler(daily_handler)
logger.addHandler(console_handler)
return logger
except Exception as e:
# Fallback to basic logging if setup fails
basic_logger = logging.getLogger(name)
basic_logger.setLevel(logging.INFO)
basic_logger.addHandler(logging.StreamHandler(sys.stdout))
basic_logger.error(f"Error setting up logger: {str(e)}")
return basic_logger# Logging configuration implementation
|