|
| 1 | +import logging |
| 2 | +import sys |
| 3 | + |
| 4 | +# ASCII colors for console |
| 5 | +RESET_COLOR = "\033[0m" |
| 6 | +GREEN = "\033[32m" |
| 7 | +YELLOW = "\033[33m" |
| 8 | +RED = "\033[31m" |
| 9 | +CYAN = "\033[36m" |
| 10 | +WHITE = "\033[37m" |
| 11 | + |
| 12 | +class ColoredFormatter(logging.Formatter): |
| 13 | + """Custom formatter to add colors to log levels for better readability.""" |
| 14 | + |
| 15 | + FORMAT = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" |
| 16 | + |
| 17 | + FORMATS = { |
| 18 | + logging.DEBUG: WHITE + FORMAT + RESET_COLOR, |
| 19 | + logging.INFO: GREEN + FORMAT + RESET_COLOR, |
| 20 | + logging.WARNING: YELLOW + FORMAT + RESET_COLOR, |
| 21 | + logging.ERROR: RED + FORMAT + RESET_COLOR, |
| 22 | + logging.CRITICAL: RED + "\033[1m" + FORMAT + RESET_COLOR, # Bold Red |
| 23 | + } |
| 24 | + |
| 25 | + def format(self, record): |
| 26 | + log_fmt = self.FORMATS.get(record.levelno, self.FORMAT) |
| 27 | + formatter = logging.Formatter(log_fmt, datefmt="%Y-%m-%d %H:%M:%S") |
| 28 | + return formatter.format(record) |
| 29 | + |
| 30 | +def setup_logging(level: int = logging.INFO): |
| 31 | + """ |
| 32 | + Sets up the global logging configuration with colored output. |
| 33 | + should be called once at application startup. |
| 34 | + """ |
| 35 | + # Get root logger |
| 36 | + root_logger = logging.getLogger() |
| 37 | + root_logger.setLevel(level) |
| 38 | + |
| 39 | + # Clear existing handlers to prevent duplicate logs (common with uvicorn/fastapi) |
| 40 | + if root_logger.hasHandlers(): |
| 41 | + root_logger.handlers.clear() |
| 42 | + |
| 43 | + # Create console handler |
| 44 | + console_handler = logging.StreamHandler(sys.stdout) |
| 45 | + console_handler.setLevel(level) |
| 46 | + |
| 47 | + # Apply custom colored formatter |
| 48 | + console_handler.setFormatter(ColoredFormatter()) |
| 49 | + |
| 50 | + # Add handler to root logger |
| 51 | + root_logger.addHandler(console_handler) |
| 52 | + |
| 53 | + # Optional: Adjust third-party loggers if they are too noisy |
| 54 | + # logging.getLogger("uvicorn.access").setLevel(logging.WARNING) |
| 55 | + |
| 56 | + return root_logger |
0 commit comments