"""tg_bridge 日志:控制台 + 按日切分的本地文件(午夜滚动,历史文件带日期后缀)。""" from __future__ import annotations import logging import logging.handlers import os from pathlib import Path from dotenv import load_dotenv _ROOT = Path(__file__).resolve().parent.parent load_dotenv(_ROOT / ".env") load_dotenv() def _parse_log_level(name: str) -> int: return getattr(logging, name.upper(), logging.INFO) def setup_logging() -> None: """为 logger ``tg_bridge`` 及其子 logger 配置 StreamHandler + TimedRotatingFileHandler。 当前日志文件:``<目录>/tg_bridge.log``;每日午夜滚动后重命名为 ``tg_bridge.log.YYYY-MM-DD``。 重复调用不会重复添加 handler。 """ root_tg = logging.getLogger("tg_bridge") if root_tg.handlers: return log_dir_raw = os.environ.get("BRIDGE_LOG_DIR", "").strip() log_dir = Path(log_dir_raw).expanduser().resolve() if log_dir_raw else (_ROOT / "logs").resolve() log_dir.mkdir(parents=True, exist_ok=True) backup_raw = os.environ.get("BRIDGE_LOG_BACKUP_COUNT", "30").strip() try: backup_count = max(1, int(backup_raw)) except ValueError: backup_count = 30 level = _parse_log_level(os.environ.get("BRIDGE_LOG_LEVEL", "INFO")) root_tg.setLevel(level) fmt = logging.Formatter( "%(asctime)s [%(levelname)s] %(name)s: %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) file_path = log_dir / "tg_bridge.log" fh = logging.handlers.TimedRotatingFileHandler( filename=str(file_path), when="midnight", interval=1, backupCount=backup_count, encoding="utf-8", delay=True, ) fh.suffix = "%Y-%m-%d" fh.setFormatter(fmt) sh = logging.StreamHandler() sh.setFormatter(fmt) root_tg.addHandler(fh) root_tg.addHandler(sh) root_tg.propagate = False