"""Logging setup. Root logger writes to stdout (so tmux/systemd captures it) and to ``logs/relay-YYYY-MM-DD.log`` with daily rotation. Format includes timestamp, level, logger name, and message. """ from __future__ import annotations import logging import sys from logging.handlers import TimedRotatingFileHandler from pathlib import Path def configure(logs_dir: Path, level: int = logging.INFO) -> None: logs_dir.mkdir(parents=True, exist_ok=True) fmt = logging.Formatter( fmt="%(asctime)s %(levelname)-7s %(name)-22s %(message)s", datefmt="%Y-%m-%dT%H:%M:%S", ) root = logging.getLogger() root.setLevel(level) # Remove pre-existing handlers (idempotent across reload during tests) for handler in list(root.handlers): root.removeHandler(handler) stdout = logging.StreamHandler(stream=sys.stdout) stdout.setFormatter(fmt) root.addHandler(stdout) file_handler = TimedRotatingFileHandler( filename=str(logs_dir / "relay.log"), when="midnight", backupCount=14, encoding="utf-8", utc=True, ) file_handler.setFormatter(fmt) root.addHandler(file_handler) # Quiet libraries that are too chatty at INFO for noisy in ("urllib3", "httpx", "httpcore", "anthropic"): logging.getLogger(noisy).setLevel(logging.WARNING)