| 
					
				 | 
			
			
				@@ -4,77 +4,118 @@ import sys 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from pathlib import Path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import colorlog 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from logging.handlers import TimedRotatingFileHandler 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-import datetime 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 创建日志记录器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-log = logging.getLogger(__name__) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-log.setLevel(logging.INFO) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 获取项目根目录 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 project_root = Path(os.path.abspath(os.path.dirname(__file__))).parent.parent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 日志目录设置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-if sys.platform.startswith('linux'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    log_dir = Path('/home/crossborder/logs') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    log_dir = project_root / 'logs' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-os.makedirs(log_dir, exist_ok=True)  # 自动创建目录(如果不存在) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 创建带日期归档的文件处理器 - 关键修改点 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-log_file = log_dir / 'cross.log' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-file_handler = TimedRotatingFileHandler( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    filename=str(log_file), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    when='midnight',  # 每天午夜切换新日志 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    interval=1,       # 每天的间隔 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    backupCount=30,    # 保留30天的日志 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    encoding='utf-8', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    utc=False         # 使用本地时间 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 设置时间后缀格式 - 在日志文件名后添加日期 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-file_handler.suffix = "%Y-%m-%d" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-file_handler.setLevel(logging.INFO) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 创建控制台处理器(带颜色) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-console_handler = colorlog.StreamHandler() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-console_handler.setLevel(logging.DEBUG if os.getenv('DEBUG') else logging.INFO) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 文件格式器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-plain_formatter = logging.Formatter( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '%(asctime)s - %(name)s:%(lineno)d - %(levelname)s - %(message)s', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    datefmt='%Y-%m-%d %H:%M:%S' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 控制台颜色格式器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-color_formatter = colorlog.ColoredFormatter( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '%(log_color)s%(asctime)s - %(name)s:%(lineno)d - %(levelname)s - %(message)s', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    datefmt='%Y-%m-%d %H:%M:%S', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    log_colors={ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'DEBUG': 'cyan', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'INFO': 'green', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'WARNING': 'yellow', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'ERROR': 'red', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'CRITICAL': 'red,bg_white', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 应用格式器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-file_handler.setFormatter(plain_formatter) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-console_handler.setFormatter(color_formatter) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 添加处理器到记录器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-log.addHandler(file_handler) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-log.addHandler(console_handler) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 禁用不必要库的日志 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-logging.getLogger("urllib3").setLevel(logging.WARNING) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-logging.getLogger("selenium").setLevel(logging.WARNING) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# 测试日志 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-if __name__ == "__main__": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    log.debug("DEBUG级别日志 - 通常不会显示") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    log.info("INFO级别日志 - 程序运行信息") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    log.warning("WARNING级别日志 - 需要注意的问题") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    log.error("ERROR级别日志 - 错误信息") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    log.critical("CRITICAL级别日志 - 严重错误") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def configure_logging(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """配置全局日志系统(只执行一次)""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 移除之前直接创建log实例的代码 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 创建根记录器并配置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    root_logger = logging.getLogger() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    root_logger.setLevel(logging.DEBUG) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 清除可能存在的旧处理器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for handler in root_logger.handlers[:]: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        root_logger.removeHandler(handler) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 日志目录设置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if sys.platform.startswith('linux'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log_dir = Path('/home/crossborder/logs') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log_dir = project_root / 'logs' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    os.makedirs(log_dir, exist_ok=True) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 创建带日期归档的文件处理器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    log_file = log_dir / 'cross.log' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    file_handler = TimedRotatingFileHandler( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        filename=str(log_file), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        when='midnight', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        interval=1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        backupCount=30, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        encoding='utf-8', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        utc=False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    file_handler.suffix = "%Y-%m-%d" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    file_handler.setLevel(logging.INFO) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 创建控制台处理器(带颜色) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console_handler = colorlog.StreamHandler() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console_handler.setLevel(logging.DEBUG if os.getenv('DEBUG') else logging.INFO) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 文件格式器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    plain_formatter = logging.Formatter( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        '%(asctime)s - %(name)s:%(lineno)d - %(levelname)s - %(message)s', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        datefmt='%Y-%m-%d %H:%M:%S' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 控制台颜色格式器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    color_formatter = colorlog.ColoredFormatter( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        '%(log_color)s%(asctime)s - %(name)s:%(lineno)d - %(levelname)s - %(message)s', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        datefmt='%Y-%m-%d %H:%M:%S', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        log_colors={ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            'DEBUG': 'cyan', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            'INFO': 'green', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            'WARNING': 'yellow', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            'ERROR': 'red', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            'CRITICAL': 'red,bg_white', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    file_handler.setFormatter(plain_formatter) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    console_handler.setFormatter(color_formatter) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 添加处理器到根记录器 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    root_logger.addHandler(file_handler) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    root_logger.addHandler(console_handler) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 禁用不必要库的日志 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    logging.getLogger("urllib3").setLevel(logging.WARNING) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    logging.getLogger("selenium").setLevel(logging.WARNING) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 项目顶级记录器(用于统一控制项目日志级别) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    project_logger = logging.getLogger("crossborder") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    project_logger.setLevel(logging.INFO) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def get_logger(name=None): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if not name: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        name = "crossborder" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 处理主模块 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if name == "__main__": 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        main_module = sys.modules['__main__'] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # 获取入口文件的绝对路径 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if hasattr(main_module, '__file__'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            main_file = Path(main_module.__file__).resolve() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # 计算相对于项目根目录的路径 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                relative_path = main_file.relative_to(project_root) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # 转换为模块名:去掉扩展名,分隔符替换为点 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                name = str(relative_path.with_suffix('')).replace(os.sep, '.') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            except ValueError: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                # 如果入口文件不在项目根目录下,则使用文件名(不含扩展名) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                name = main_file.stem 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            # 例如交互式环境,没有__file__,则保留为"__main__" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            pass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 确保日志系统已配置 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if not logging.getLogger().hasHandlers(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        configure_logging() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    # 添加项目顶级命名空间(如果还没有),除非已经是crossborder开头 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if not name.startswith("crossborder."): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        name = "crossborder." + name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return logging.getLogger(name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# 在模块导入时自动配置(可选) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+configure_logging() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# ====== 注意:不再直接导出log实例 ====== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# 业务模块应使用 get_logger(__name__) 获取记录器 
			 |