Spaces:
Running
Running
import logging | |
import sys | |
import os | |
from datetime import datetime | |
from typing import Optional | |
class CustomFormatter(logging.Formatter): | |
"""Custom formatter with color coding and detailed formatting""" | |
grey = "\x1b[38;21m" | |
blue = "\x1b[38;5;39m" | |
yellow = "\x1b[38;5;226m" | |
red = "\x1b[38;5;196m" | |
bold_red = "\x1b[31;1m" | |
reset = "\x1b[0m" | |
def __init__(self, include_path: bool = False): | |
date_fmt = "%Y-%m-%d %H:%M:%S.%f" | |
if include_path: | |
fmt = ("%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s " | |
"[%(pathname)s:%(lineno)d] - %(message)s") | |
else: | |
fmt = "%(asctime)s.%(msecs)03d - %(name)s - %(levelname)s - %(message)s" | |
super().__init__(fmt=fmt, datefmt=date_fmt) | |
def format(self, record): | |
# Save original format | |
format_orig = self._style._fmt | |
# Apply color based on log level | |
if record.levelno == logging.DEBUG: | |
self._style._fmt = self.grey + format_orig + self.reset | |
elif record.levelno == logging.INFO: | |
self._style._fmt = self.blue + format_orig + self.reset | |
elif record.levelno == logging.WARNING: | |
self._style._fmt = self.yellow + format_orig + self.reset | |
elif record.levelno == logging.ERROR: | |
self._style._fmt = self.red + format_orig + self.reset | |
elif record.levelno == logging.CRITICAL: | |
self._style._fmt = self.bold_red + format_orig + self.reset | |
# Call original format | |
result = logging.Formatter.format(self, record) | |
# Restore original format | |
self._style._fmt = format_orig | |
return result | |
def setup_logger( | |
name: str = __name__, | |
log_level: int = logging.DEBUG, | |
log_file: Optional[str] = None | |
) -> logging.Logger: | |
""" | |
Sets up a configured logger with both console and file handlers. | |
Args: | |
name: Logger name | |
log_level: Logging level | |
log_file: Optional specific log file path | |
Returns: | |
Configured logger instance | |
""" | |
logger = logging.getLogger(name) | |
# Only add handlers if logger doesn't have any | |
if not logger.handlers: | |
logger.setLevel(log_level) | |
# Ensure logs directory exists | |
os.makedirs('logs', exist_ok=True) | |
# Console handler with minimal formatting | |
console_handler = logging.StreamHandler(sys.stdout) | |
console_handler.setLevel(logging.INFO) | |
console_formatter = CustomFormatter(include_path=False) | |
console_handler.setFormatter(console_formatter) | |
# File handler with detailed formatting | |
if not log_file: | |
log_file = f'logs/sse_stream_{datetime.now():%Y%m%d}.log' | |
file_handler = logging.FileHandler(log_file) | |
file_handler.setLevel(logging.DEBUG) | |
file_formatter = CustomFormatter(include_path=True) | |
file_handler.setFormatter(file_formatter) | |
# Debug file handler for trace-level logging | |
debug_file = f'logs/debug_{datetime.now():%Y%m%d}.log' | |
debug_handler = logging.FileHandler(debug_file) | |
debug_handler.setLevel(logging.DEBUG) | |
debug_formatter = CustomFormatter(include_path=True) | |
debug_handler.setFormatter(debug_formatter) | |
logger.addHandler(console_handler) | |
logger.addHandler(file_handler) | |
logger.addHandler(debug_handler) | |
return logger |