67 lines
1.9 KiB
Python
67 lines
1.9 KiB
Python
"""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
|