import logging import os from logging.handlers import RotatingFileHandler from typing import Any, Dict def setup_logging(config: Dict[str, Any]) -> None: """根据配置初始化日志。 - 控制台输出 - 可选文件轮转输出(默认启用) - 不重复添加 handler(幂等) """ debug_cfg = (config or {}).get("debug", {}) log_level_name = str(debug_cfg.get("log_level", "INFO")).upper() log_to_file = bool(debug_cfg.get("log_to_file", True)) out_dir = debug_cfg.get("out_dir", "debug_out") file_name = debug_cfg.get("file_name", "txm.log") max_bytes = int(debug_cfg.get("max_bytes", 10 * 1024 * 1024)) backup_count = int(debug_cfg.get("backup_count", 5)) try: level = getattr(logging, log_level_name) except Exception: level = logging.INFO root_logger = logging.getLogger() if root_logger.handlers: # 已经初始化过 root_logger.setLevel(level) return fmt = ( "%(asctime)s.%(msecs)03d | %(levelname)s | %(name)s | " "%(message)s" ) datefmt = "%Y-%m-%d %H:%M:%S" root_logger.setLevel(level) console = logging.StreamHandler() console.setLevel(level) console.setFormatter(logging.Formatter(fmt=fmt, datefmt=datefmt)) root_logger.addHandler(console) if log_to_file: os.makedirs(out_dir, exist_ok=True) file_path = os.path.join(out_dir, file_name) file_handler = RotatingFileHandler( file_path, maxBytes=max_bytes, backupCount=backup_count, encoding="utf-8" ) file_handler.setLevel(level) file_handler.setFormatter(logging.Formatter(fmt=fmt, datefmt=datefmt)) root_logger.addHandler(file_handler)