Mr_*_*uet 12 python logging python-2.7
Python 2.7.
同一文件夹中的两个文件:
可以在logging没有任何冲突的情况下使用模块(参见下面的输出).
import logging
from b import test_b
def test_a(logger):
logger.debug("debug")
logger.info("info")
logger.warning("warning")
logger.error("error")
if __name__ == "__main__":
# Custom logger.
logger = logging.getLogger("test")
formatter = logging.Formatter('[%(levelname)s] %(message)s')
handler = logging.StreamHandler()
handler.setFormatter(formatter)
logger.setLevel(logging.DEBUG)
logger.addHandler(handler)
# Test A and B.
print "B"
test_b()
print "A"
test_a(logger)
Run Code Online (Sandbox Code Playgroud)
import logging
def test_b():
logging.debug("debug")
logging.info("info")
logging.warning("warning")
logging.error("error")
Run Code Online (Sandbox Code Playgroud)
如下所示,日志显示两次.
python a.py
B
WARNING:root:warning
ERROR:root:error
A
[DEBUG] debug
DEBUG:test:debug
[INFO] info
INFO:test:info
[WARNING] warning
WARNING:test:warning
[ERROR] error
ERROR:test:error
Run Code Online (Sandbox Code Playgroud)
有人会有解决方案吗?
编辑:未运行test_b()将导致没有日志重复和正确的日志格式(预期).
aba*_*ert 31
我不确定我理解你的情况,因为描述与输出不符......但我想我知道你的问题是什么.
正如文档解释:
注意:如果将处理程序附加到记录器及其一个或多个祖先,则它可能会多次发出相同的记录.通常,您不需要将处理程序附加到多个记录器 - 如果您只是将其附加到记录器层次结构中最高的相应记录器,那么它将看到所有后代记录器记录的所有事件,前提是它们的传播设置左侧设置为True.常见的情况是仅将处理程序附加到根记录程序,并让传播处理其余部分.
而"常见场景"通常效果很好,但我认为你需要附加一个自定义处理程序来"测试",而不会影响根记录器.
因此,如果您想在"test"上使用自定义处理程序,并且您不希望其消息也转到根处理程序,那么答案很简单:关闭其propagate标志:
logger.propagate = False
Run Code Online (Sandbox Code Playgroud)
这种情况只会在您调用时发生test_b,否则,根记录器永远不会被初始化.第一次登录到尚未配置的任何记录器时,它会有效地basicConfig()对该记录器执行操作.因此,调用logging.getLogger().info(msg)或logging.info(msg)将配置根记录器.但是从儿童记录器传播不会.
我相信这是双方在日志HOWTO或食谱,地方解释的HOWTO,但在实际模块的文档,它埋在即将线程音符的中间logging.log:
注意:委托给根记录器的上述模块级函数不应该在早于2.7.1和3.2的Python版本的线程中使用,除非在线程启动之前已经将至少一个处理程序添加到根记录器中.这些便捷函数调用basicConfig()以确保至少有一个处理程序可用; ; 在早期版本的Python中,这可以(在极少数情况下)导致处理程序被多次添加到根记录器,这反过来可以导致同一事件的多个消息.
很容易看出你怎么会错过它!
| 归档时间: |
|
| 查看次数: |
8765 次 |
| 最近记录: |