【问题标题】:Configuring Python logging for a local module differently to the main file为本地模块配置 Python 日志记录与主文件不同
【发布时间】:2019-01-14 06:07:52
【问题描述】:

使用Config Dict,我想在本地 Python 3 模块中将日志配置为日志级别 INFO,而在主文件中我想配置日志级别 DEBUG。所有配置都应该在主文件中完成,而不是在模块中,这样我就可以在不接触模块的情况下更改日志记录。

这里是一个例子。给定模块文件log_try_module.py

import logging
log = logging.getLogger(__name__)

def do_something():
    log.debug("This is something to DEBUG.")
    log.info("This is something to INFO.")
    log.warning("This is something to WARN.")

和主文件log_try_main.py

import logging
log = logging.getLogger(__name__)
import log_try_module

log.debug("This is mainly to DEBUG.")
log.info("This is mainly to INFO.")
log.warning("This is mainly to WARN.")

log_try_module.do_something()

logging.config.dictConfig(dict(
        version=1,
        disable_existing_loggers=False,
        handlers={
            'hr': {'class': 'logging.StreamHandler',
                  'level': logging.DEBUG},
            'hm': {'class': 'logging.StreamHandler',
                  'level': logging.INFO}
            },
        loggers={
            'log_try_module': {'handlers': ['hm'],
                               'level': logging.INFO}
            },
        root={
            'handlers': ['hr'],
            'level': logging.DEBUG,
            }
        ))

我正在寻找这样的运行输出:

$ python3 log_try_main.py
This is mainly to DEBUG.
This is mainly to INFO.
This is mainly to WARN.
This is something to INFO.
This is something to WARN.

请注意没有来自log_try_module 的调试消息发出

我已经尝试过传递各种配置字典,但我从来没有得到我正在寻找的输出。出了什么问题?

【问题讨论】:

    标签: python python-3.x logging module


    【解决方案1】:

    您的代码有两个问题:

    1. 您在主模块log_try_main.py 中使用getLogger(__name__),但是当在命令行上从Python 调用主模块时,__main__ 评估为字符串"__main__",而不是"log_try_main"
    2. 您配置了根记录器。如果您向根记录器添加另一个处理程序,则模块记录的日志将显示两次。

    所以我在这里写了一个我认为运行如你所愿的例子:

    main.py:

    import logging
    import logging.config
    import module
    
    logging.config.dictConfig(dict(
            version=1,
            disable_existing_loggers=False,
            handlers={
                'hr': {'class': 'logging.StreamHandler',
                      'level': logging.DEBUG},
                'hm': {'class': 'logging.StreamHandler',
                      'level': logging.INFO}
                },
            loggers={
                'module': {'handlers': ['hm'],
                                   'level': logging.INFO},
                'main': {'handlers': ["hr"],
                                   'level': logging.DEBUG}
                },
            ))
    
    log = logging.getLogger("main")
    
    log.debug("This is mainly to DEBUG.")
    log.info("This is mainly to INFO.")
    log.warning("This is mainly to WARN.")
    
    module.do_something()
    

    moduel.py:

    import logging
    log = logging.getLogger("module")
    
    def do_something():
        log.debug("This is something to DEBUG.")
        log.info("This is something to INFO.")
        log.warning("This is something to WARN.")
    

    输出:

    This is mainly to DEBUG.
    This is mainly to INFO.
    This is mainly to WARN.
    This is something to INFO.
    This is something to WARN.
    

    我明确命名这两个记录器,而不是使用__name__。我觉得这样更可控,在命令行运行log_try_module.py时不会给出不同的结果。

    【讨论】:

    • 注意:您可以通过log.propagate = False 显式禁用module 记录器上的传播,这将允许您继续使用root 作为未明确定义的记录器的后备。
    • 我已经编辑了我的问题,以更清楚地说明我使用了dictConfig,但您的回答显示了我的问题:配置根记录器并在主模块上使用getLogger(__name__)
    • 此外,我在您的答案中添加了我问题中的代码所遇到的两个问题。 - 最后:谢谢你的回答!这对我帮助很大。 :-)
    猜你喜欢
    • 2014-06-11
    • 2015-01-13
    • 1970-01-01
    • 2017-03-02
    • 2022-08-18
    • 2013-05-21
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    相关资源
    最近更新 更多