Spaces:
Sleeping
Sleeping
| """ | |
| Structured logging configuration. | |
| Sets up file + console handlers with proper formatting. | |
| """ | |
| from __future__ import annotations | |
| import logging | |
| import logging.handlers | |
| import sys | |
| from pathlib import Path | |
| def configure_logging(log_level: str = "INFO", log_dir: str = "logs") -> None: | |
| """Configure root logger with rotating file and console handlers.""" | |
| log_path = Path(log_dir) | |
| log_path.mkdir(parents=True, exist_ok=True) | |
| level = getattr(logging, log_level.upper(), logging.INFO) | |
| fmt = logging.Formatter( | |
| "%(asctime)s [%(levelname)-8s] %(name)s: %(message)s", | |
| datefmt="%Y-%m-%d %H:%M:%S", | |
| ) | |
| # Root logger | |
| root = logging.getLogger() | |
| root.setLevel(level) | |
| root.handlers.clear() | |
| # Console handler | |
| console = logging.StreamHandler(sys.stdout) | |
| console.setFormatter(fmt) | |
| console.setLevel(level) | |
| root.addHandler(console) | |
| # Rotating file handler | |
| file_handler = logging.handlers.RotatingFileHandler( | |
| log_path / "app.log", | |
| maxBytes=10 * 1024 * 1024, # 10 MB | |
| backupCount=5, | |
| encoding="utf-8", | |
| ) | |
| file_handler.setFormatter(fmt) | |
| file_handler.setLevel(level) | |
| root.addHandler(file_handler) | |
| # Error-only file | |
| error_handler = logging.handlers.RotatingFileHandler( | |
| log_path / "errors.log", | |
| maxBytes=5 * 1024 * 1024, | |
| backupCount=3, | |
| encoding="utf-8", | |
| ) | |
| error_handler.setFormatter(fmt) | |
| error_handler.setLevel(logging.ERROR) | |
| root.addHandler(error_handler) | |
| # Suppress noisy libs | |
| logging.getLogger("urllib3").setLevel(logging.WARNING) | |
| logging.getLogger("requests").setLevel(logging.WARNING) | |
| logging.getLogger("playwright").setLevel(logging.WARNING) | |