跨平台下Python多进程与Pytest实时日志实现方案问询
解决Pytest下多进程Spawn模式日志丢失问题(跨Windows/macOS/Linux)
核心原因
Spawn模式下,子进程会重新启动Python解释器,父进程的日志配置(包括handler、sink)不会被继承,导致子进程日志无法输出到终端。单独运行多进程时可能因初始化逻辑不同正常,但Pytest环境下父进程的日志上下文不会传递给子进程。
内置logging解决方案
在子进程任务函数内部重新初始化日志配置,直接将日志输出到stdout,无需依赖父进程配置:
import logging import sys from multiprocessing import Process def child_task(): # 获取根logger,重置配置 root_logger = logging.getLogger() root_logger.setLevel(logging.INFO) # 避免重复添加handler(防止多次调用任务时日志重复输出) if not root_logger.handlers: stdout_handler = logging.StreamHandler(sys.stdout) formatter = logging.Formatter('%(asctime)s | %(levelname)s | %(message)s') stdout_handler.setFormatter(formatter) root_logger.addHandler(stdout_handler) root_logger.info("子进程日志:这是一条测试输出") root_logger.warning("子进程日志:警告信息") def test_multiprocess_logging(): # 强制使用spawn模式(Windows默认,跨平台兼容) process = Process(target=child_task, start_method='spawn') process.start() process.join()
Loguru解决方案
Loguru在spawn模式下同样会丢失父进程的sink配置,需要在子进程中重新添加stdout sink:
from loguru import logger import sys from multiprocessing import Process def child_task(): # 移除所有现有sink,避免重复输出 logger.remove() # 重新添加指向stdout的sink,自定义格式 logger.add( sys.stdout, format="{time:YYYY-MM-DD HH:mm:ss} | {level} | {message}", level="INFO" ) logger.info("Loguru子进程:正常日志输出") logger.error("Loguru子进程:错误日志输出") def test_loguru_multiprocess(): process = Process(target=child_task, start_method='spawn') process.start() process.join()
关键注意事项
- 无需使用队列、日志服务器或自定义Pytest钩子,所有配置都在子进程任务内部完成,完全兼容跨平台需求。
- logging方案中需检查
handlers是否为空,避免多次运行任务时重复添加handler导致日志重复输出。 - Loguru方案中使用
logger.remove()清空默认sink,确保子进程日志只输出到指定的stdout。
内容的提问来源于stack exchange,提问作者Eduardo Davalos
相关产品推荐
相关产品推荐

