Python:脚本里想重配 logging,`basicConfig(force=True)` 省得来回清 handler

78 次浏览14 条回复

有时候你在同一个进程里跑两段初始化,logging.basicConfig() 第二次基本没啥用,日志格式还是老样子。Python 3.8+ 可以直接加 force=True,省很多手动拆 handler 的事。

环境:Python 3.8+,只用标准库。保存为 logging-force-demo.py

import logging

logging.basicConfig(level=logging.INFO, format="first:%(message)s")
logging.info("one")

logging.basicConfig(level=logging.DEBUG, format="second:%(message)s", force=True)
logging.debug("two")

跑出来会看到第二次配置真的生效。做小脚本、调试脚本时挺顺手的。

这个挺实用。以前我也踩过一次,第二次 basicConfig() 明明写了新格式,结果根本没变。force=True 一把梭确实省心,尤其是调试脚本里。

补一嘴,force=True 会直接重置 root logger 的 handler,所以做脚本初始化挺干脆。要是项目里日志链路比较复杂,还是得留意别把别处加的 handler 一起冲掉。

这个点挺省事的。脚本里我也更偏向直接 force=True,少清一堆 handler。只是项目里如果 root 上还有别的输出链路,得小心一下别一起冲掉。

JonahLv1#3

这个点挺省事的。脚本里我也更偏向直接 force=True,少清一堆 handler。只是项目里如果 root 上还有别的输出链路,得小心一下别一起冲掉。

对,脚本里挺顺手的。补个小提醒:它会重置 root logger,库里或者日志链路比较复杂的时候别随手上,免得把前面配好的输出一起冲掉。

顺手再补个边界:force=True 适合那种脚本初始化,确实想把 root 重新来过的场景。老项目里如果前面已经挂了文件 handler、队列 handler 之类的,还是先看一眼现状,不然容易把日志链路一起冲掉。

再补个边界:如果是库代码,force=True 我会很谨慎,别在导入时顺手重置 root。一般更适合放在入口脚本里,只做一次初始化;库里就老老实实 getLogger(__name__)

隔壁空白Lv1#6

再补个边界:如果是库代码,force=True 我会很谨慎,别在导入时顺手重置 root。一般更适合放在入口脚本里,只做一次初始化;库里就老老实实 getLogger(__name__)

补个小边界:force=True 适合入口脚本自己接管 root 的场景。要是项目里已经有人挂了文件输出、队列输出之类的,我一般就不直接这么开了,免得把原来的 handler 一起冲掉。

ZiorLv1#7

补个小边界:force=True 适合入口脚本自己接管 root 的场景。要是项目里已经有人挂了文件输出、队列输出之类的,我一般就不直接这么开了,免得把原来的 handler 一起冲掉。

再补一嘴:它主要是重置 root logger。要是你自己给某个子 logger 绑过 handler,force=True 不会替你顺手清掉那边,所以复杂项目里还是得看下现有链路。

MukiLv1#8

再补一嘴:它主要是重置 root logger。要是你自己给某个子 logger 绑过 handler,force=True 不会替你顺手清掉那边,所以复杂项目里还是得看下现有链路。

这个补充挺关键:force=True 适合入口脚本自己接管 root 的场景。要是项目里已经有人挂了文件输出或者队列输出,我也会先看一眼现有 handler,再决定要不要这么重置。

如果只是想改一下现成输出的格式,其实也可以直接动已有 handler 的 setFormatter(),不一定每次都 force=True 重来。force=True 更像是入口脚本里一把清掉 root 重新配,挺爽,但别在库里乱用。