logging_setup.py 1.27 KB
"""Configure dedicated eval run logs (defaults: repo ``logs/``; override via ``config.yaml`` ``search_evaluation.eval_log_dir``)."""

from __future__ import annotations

import logging
import sys
from pathlib import Path

from .constants import EVAL_LOG_DIR

_setup_done = False


def setup_eval_logging(eval_log_dir: Path | None = None) -> Path:
    """Attach file + stderr handlers to ``search_eval`` once; ensure log directories exist.

    Returns the path to the primary ``eval.log`` file.
    """
    global _setup_done
    log_dir = Path(eval_log_dir).resolve() if eval_log_dir is not None else EVAL_LOG_DIR.resolve()
    verbose_dir = log_dir / "verbose"
    log_file = log_dir / "eval.log"

    log_dir.mkdir(parents=True, exist_ok=True)
    verbose_dir.mkdir(parents=True, exist_ok=True)

    fmt = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s")
    root = logging.getLogger("search_eval")
    root.setLevel(logging.INFO)
    if root.handlers:
        _setup_done = True
        return log_file

    fh = logging.FileHandler(log_file, encoding="utf-8")
    fh.setFormatter(fmt)
    sh = logging.StreamHandler(sys.stderr)
    sh.setFormatter(fmt)
    root.addHandler(fh)
    root.addHandler(sh)
    root.propagate = False
    _setup_done = True
    return log_file