Python logging模块主进程与子进程日志归属异常问题
问题原因与解决方案
核心原因
子进程从主程序导入func时,主程序中未被if __name__ == '__main__':包裹的日志配置代码会在子进程中执行,导致子进程继承了主进程的日志Handler,而非使用自身的独立配置。即使子进程后续配置了日志,若未清理已继承的Handler,仍会沿用主进程的格式(包括processName)。
解决步骤
1. 主程序:日志配置仅限主进程执行
将主程序的日志初始化逻辑放在if __name__ == '__main__':代码块内,避免子进程导入时重复执行:
# mainprogram.py import logging from multiprocessing import Process import subprogram def func(): logging.info("来自主程序func的日志") if __name__ == '__main__': # 仅主进程执行此配置 formatter = logging.Formatter('%(processName)s - %(message)s') handler = logging.StreamHandler() handler.setFormatter(formatter) root_logger = logging.getLogger() root_logger.addHandler(handler) root_logger.setLevel(logging.INFO) # 创建子进程时可指定名称,便于日志区分 p = Process(target=subprogram.run_sub, name="SubProcess-1") p.start() p.join()
2. 子进程:清理继承的Handler,配置独立日志
子进程启动后,先清空根日志器的所有Handler,再配置自己的日志格式:
# subprogram.py import logging from mainprogram import func def run_sub(): # 清理从主进程继承的Handler,避免干扰 root_logger = logging.getLogger() for handler in root_logger.handlers[:]: root_logger.removeHandler(handler) # 子进程独立日志配置 formatter = logging.Formatter('%(processName)s - %(message)s') handler = logging.StreamHandler() handler.setFormatter(formatter) root_logger.addHandler(handler) root_logger.setLevel(logging.INFO) logging.info("子进程自身的日志") func() # 调用主程序的func,此时日志会使用子进程的配置
3. 验证效果
运行主程序后,子进程的日志会显示指定的processName(如SubProcess-1),而非MainProcess。
补充说明
如果使用Windows系统,Python多进程默认采用spawn启动方式,子进程会重新导入主程序模块,此时if __name__ == '__main__':的隔离作用更关键——避免主程序的初始化逻辑在子进程中重复执行。
内容的提问来源于stack exchange,提问作者Aya
相关产品推荐
相关产品推荐

