Spaces:
Sleeping
Sleeping
File size: 1,738 Bytes
50dca14 | 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 | """
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)
|