# -*- encoding=utf8 -*- """ 统一的日志配置模块 此模块提供了整个项目的日志管理功能,包括: - 统一的日志格式 - 集中的日志级别控制 - 第三方库日志管理 - 支持文件和控制台输出 """ import logging import sys from pathlib import Path from typing import Optional, List # 默认日志格式 DEFAULT_LOG_FORMAT = '%(asctime)s %(name)-20s %(levelname)-8s %(message)s' DEFAULT_DATE_FORMAT = '%Y-%m-%d %H:%M:%S' # 需要抑制的第三方库logger THIRD_PARTY_LOGGERS = [ # Airtest相关 'airtest', 'adb', 'airtest.core.android.adb', # 网络相关 'urllib3', 'urllib3.connectionpool', 'requests', # AI/ML相关 'transformers', 'torch', 'tensorflow', # 图像处理 'PIL', 'PIL.PngImagePlugin', 'PIL.Image', 'matplotlib', 'cv2', # 其他 'filelock', 'webdriver_manager', ] def setup_logging( level: int = logging.INFO, log_file: Optional[str] = None, log_format: str = DEFAULT_LOG_FORMAT, date_format: str = DEFAULT_DATE_FORMAT, debug_mode: bool = False, enable_file_handler: bool = True, enable_console_handler: bool = True, third_party_level: int = logging.WARNING, custom_third_party_loggers: Optional[List[str]] = None ) -> logging.Logger: """ 统一配置项目日志系统 Args: level: 主日志级别 (默认: logging.INFO) log_file: 日志文件路径,None表示不写入文件 log_format: 日志格式字符串 date_format: 日期格式字符串 debug_mode: 是否启用调试模式(会将level设为DEBUG) enable_file_handler: 是否启用文件处理器 enable_console_handler: 是否启用控制台处理器 third_party_level: 第三方库的日志级别 custom_third_party_loggers: 额外需要抑制的第三方logger名称列表 Returns: 配置好的根logger对象 Example: # 基本使用 setup_logging() logger = logging.getLogger(__name__) logger.info("Application started") # 带文件输出 setup_logging(log_file="app.log", debug_mode=True) # 仅文件输出,不输出到控制台 setup_logging(log_file="app.log", enable_console_handler=False) """ # Debug模式覆盖级别设置 if debug_mode: level = logging.DEBUG # 准备handlers handlers = [] formatter = logging.Formatter(log_format, datefmt=date_format) # 控制台handler if enable_console_handler: console_handler = logging.StreamHandler(sys.stdout) console_handler.setFormatter(formatter) console_handler.setLevel(level) handlers.append(console_handler) # 文件handler if enable_file_handler and log_file: # 确保日志目录存在 log_path = Path(log_file) log_path.parent.mkdir(parents=True, exist_ok=True) file_handler = logging.FileHandler(log_file, encoding='utf-8') file_handler.setFormatter(formatter) file_handler.setLevel(level) handlers.append(file_handler) # 配置根logger logging.basicConfig( level=level, format=log_format, datefmt=date_format, handlers=handlers, force=True # 强制覆盖已有配置 ) # 配置第三方库日志级别 all_third_party = THIRD_PARTY_LOGGERS.copy() if custom_third_party_loggers: all_third_party.extend(custom_third_party_loggers) for logger_name in all_third_party: logging.getLogger(logger_name).setLevel(third_party_level) root_logger = logging.getLogger() return root_logger def get_logger(name: str = None) -> logging.Logger: """ 获取logger实例的便捷函数 Args: name: logger名称,通常传入 __name__。如果为None,返回root logger Returns: Logger实例 Example: logger = get_logger(__name__) logger.info("Message") """ return logging.getLogger(name) def set_module_log_level(module_name: str, level: int): """ 设置特定模块的日志级别 Args: module_name: 模块名称 level: 日志级别 Example: # 只看DroidBot的DEBUG日志 set_module_log_level('DroidBot', logging.DEBUG) # 完全禁用某个模块的日志 set_module_log_level('noisy_module', logging.CRITICAL) """ logging.getLogger(module_name).setLevel(level) def disable_third_party_logs(): """ 完全禁用所有第三方库的日志输出 Example: disable_third_party_logs() """ for logger_name in THIRD_PARTY_LOGGERS: logging.getLogger(logger_name).setLevel(logging.CRITICAL + 1) # 便捷的配置预设 def setup_basic_logging(): """基础配置:INFO级别,仅控制台输出""" return setup_logging(level=logging.INFO, enable_file_handler=False) def setup_debug_logging(log_file: str = None): """调试配置:DEBUG级别,控制台+文件输出""" return setup_logging( level=logging.DEBUG, log_file=log_file, debug_mode=True ) def setup_production_logging(log_file: str): """生产配置:INFO级别,仅文件输出""" return setup_logging( level=logging.INFO, log_file=log_file, enable_console_handler=False ) if __name__ == "__main__": # 测试日志配置 print("=== 测试日志配置 ===\n") # 测试1: 基础配置 print("1. 基础配置测试") setup_basic_logging() logger = get_logger(__name__) logger.debug("这条DEBUG不会显示") logger.info("这条INFO会显示") logger.warning("这条WARNING会显示") print("\n2. 调试模式测试") setup_debug_logging() logger.debug("调试模式下,这条DEBUG会显示") logger.info("这条INFO也会显示") print("\n3. 第三方库日志抑制测试") third_party_logger = logging.getLogger('urllib3') third_party_logger.warning("这条第三方WARNING不会显示(被抑制到WARNING级别以上)") print("\n测试完成!")