| """
|
| caff/utils/logging.py
|
| =====================
|
| Centralized logging setup. All modules use Python's standard
|
| `logging` module — never `print` for diagnostic output.
|
| """
|
|
|
| from __future__ import annotations
|
|
|
| import logging
|
| import sys
|
| from pathlib import Path
|
|
|
|
|
| def setup_logging(
|
| level: str = "INFO",
|
| log_file: str | Path | None = None,
|
| fmt: str = "%(asctime)s | %(levelname)-8s | %(name)s | %(message)s",
|
| ) -> None:
|
| """Configure root logger to stream to stdout and (optionally) a file.
|
|
|
| Parameters
|
| ----------
|
| level : str
|
| One of DEBUG, INFO, WARNING, ERROR.
|
| log_file : path or None
|
| If set, ALSO write logs to this file.
|
| fmt : str
|
| Format string for log records.
|
| """
|
| handlers: list[logging.Handler] = [logging.StreamHandler(sys.stdout)]
|
| if log_file is not None:
|
| log_file = Path(log_file)
|
| log_file.parent.mkdir(parents=True, exist_ok=True)
|
| handlers.append(logging.FileHandler(log_file, mode="a", encoding="utf-8"))
|
|
|
| formatter = logging.Formatter(fmt)
|
| for h in handlers:
|
| h.setFormatter(formatter)
|
|
|
| root = logging.getLogger()
|
| root.handlers.clear()
|
| for h in handlers:
|
| root.addHandler(h)
|
| root.setLevel(getattr(logging, level.upper()))
|
|
|
|
|
| for noisy in ("urllib3", "filelock", "huggingface_hub", "transformers"):
|
| logging.getLogger(noisy).setLevel(logging.WARNING) |