【问题标题】:Set logging levels设置日志记录级别
【发布时间】:2016-11-27 00:48:43
【问题描述】:

我正在尝试使用标准库来调试我的代码:

这很好用:

import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
logger.info('message')

我无法让较低级别的记录器工作:

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.info('message')

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
logger.debug('message')

我没有得到任何回应。

【问题讨论】:

    标签: python logging


    【解决方案1】:

    什么 Python 版本?这在 3.4 中对我有用。但请注意,basicConfig() 不会影响已设置的根处理程序:

    如果根记录器已经为其配置了处理程序,则此函数不执行任何操作。

    要在 root 上显式设置级别,请执行 logging.getLogger().setLevel(logging.DEBUG)。但请确保您事先已调用basicConfig(),以便根记录器最初进行一些设置。即:

    import logging
    logging.basicConfig()
    logging.getLogger().setLevel(logging.DEBUG)
    logging.getLogger('foo').debug('bah')
    logging.getLogger().setLevel(logging.INFO)
    logging.getLogger('foo').debug('bah')
    

    还请注意,“记录器”和它们的“处理程序”都具有不同的独立日志级别。因此,如果您之前在 Python 脚本中显式加载了一些复杂的记录器配置,并且与根记录器的处理程序混淆,那么这可能会产生影响,并且仅使用 logging.getLogger().setLevel(..) 更改记录器日志级别可能不会工作。这是因为附加的处理程序可能具有独立设置的日志级别。这种情况不太可能发生,您通常不必担心。

    【讨论】:

    • 您现在可以向 basicConfig 发送 force=True 以使其工作,即使它已经设置好了。
    【解决方案2】:

    我使用以下设置进行日志记录

    基于 Yaml 的配置

    像这样创建一个名为 logging.yml 的 yaml 文件

    version: 1
    
    formatters:
        simple:
            format: "%(name)s - %(lineno)d -  %(message)s"
    
        complex:
            format: "%(asctime)s - %(name)s - %(lineno)d -  %(message)s"
    
    
    handlers:
        console:
            class: logging.StreamHandler
            level: DEBUG
            formatter: simple
    
        file:
            class: logging.handlers.TimedRotatingFileHandler
            when: midnight
            backupCount: 5
            level: DEBUG
            formatter: simple
            filename : Thrift.log
    
    loggers:
    
        qsoWidget:
            level: INFO
            handlers: [console,file]
            propagate: yes
    
        __main__:   
            level: DEBUG
            handlers: [console]
            propagate: yes
    

    Python - 主要

    “主”模块应如下所示

    import logging.config
    import logging
    
    with open('logging.yaml','rt') as f:
            config=yaml.safe_load(f.read())
            f.close()
    logging.config.dictConfig(config)
    logger=logging.getLogger(__name__)
    logger.info("Contest is starting")
    

    子模块/类

    这些应该像这样开始

    import logging
    
    class locator(object):
        def __init__(self):
            self.logger = logging.getLogger(__name__)
            self.logger.debug('{} initialized')
    

    希望对你有帮助...

    【讨论】:

    • qsoWidget 只是您应用的名称吗?
    • __init__.py 中包含所有日志配置不是最佳做法吗?这是一个问题。
    • 我会说 - 您应该尝试将日志记录设置放在项目中可能的最高点。然后让依赖的模块使用它。这样你就有了一致的日志记录。对每个模块执行模块将导致不同级别、不同的日志格式输出。这将使下游日志处理(Humio、Splunk、PIG)变得更加困难。
    • 很好的例子!谢谢你。通过 .yaml 设置记录器配置听起来是一个非常有效的解决方案
    • @AlexSkorokhod 我认为 yaml 是可读的,但是将日志记录在外部文件中,可以让您在不接触代码的情况下改变日志级别。
    【解决方案3】:

    在我看来,这是大多数情况下的最佳方法。

    通过 INI 文件配置

    在项目根目录下创建文件名logging.ini,如下:

    [loggers]
    keys=root
    
    [logger_root]
    level=DEBUG
    handlers=screen,file
    
    [formatters]
    keys=simple,verbose
    
    [formatter_simple]
    format=%(asctime)s [%(levelname)s] %(name)s: %(message)s
    
    [formatter_verbose]
    format=[%(asctime)s] %(levelname)s [%(filename)s %(name)s %(funcName)s (%(lineno)d)]: %(message)s
    
    [handlers]
    keys=file,screen
    
    [handler_file]
    class=handlers.TimedRotatingFileHandler
    interval=midnight
    backupCount=5
    formatter=verbose
    level=WARNING
    args=('debug.log',)
    
    [handler_screen]
    class=StreamHandler
    formatter=simple
    level=DEBUG
    args=(sys.stdout,)
    

    然后配置如下:

    import logging
    
    from logging.config import fileConfig
    
    fileConfig('logging.ini')
    logger = logging.getLogger('dev')
    
    
    name = "stackoverflow"
    
    logger.info(f"Hello {name}!")
    logger.critical('This message should go to the log file.')
    logger.error('So should this.')
    logger.warning('And this, too.')
    logger.debug('Bye!')
    

    如果您运行脚本,sysout 将是:

    2021-01-31 03:40:10,241 [INFO] dev: Hello stackoverflow!
    2021-01-31 03:40:10,242 [CRITICAL] dev: This message should go to the log file.
    2021-01-31 03:40:10,243 [ERROR] dev: So should this.
    2021-01-31 03:40:10,243 [WARNING] dev: And this, too.
    2021-01-31 03:40:10,243 [DEBUG] dev: Bye!
    

    debug.log 文件应包含:

    [2021-01-31 03:40:10,242] CRITICAL [my_loger.py dev <module> (12)]: This message should go to the log file.
    [2021-01-31 03:40:10,243] ERROR [my_loger.py dev <module> (13)]: So should this.
    [2021-01-31 03:40:10,243] WARNING [my_loger.py dev <module> (14)]: And this, too.
    

    全部完成。

    【讨论】:

      【解决方案4】:

      我想将默认记录器保留在警告级别,但我的代码有详细的低级记录器。但它不会显示任何东西。在另一个答案的基础上,事先运行logging.basicConfig() 至关重要。

      import logging
      logging.basicConfig()
      logging.getLogger('foo').setLevel(logging.INFO)
      logging.getLogger('foo').info('info')
      logging.getLogger('foo').debug('info')
      logging.getLogger('foo').setLevel(logging.DEBUG)
      logging.getLogger('foo').info('info')
      logging.getLogger('foo').debug('debug')
      

      预期输出

      INFO:foo:info
      INFO:foo:info
      DEBUG:foo:debug
      

      对于跨模块的日志记录解决方案,我这样做了

      # cfg.py
      
      import logging
      logging.basicConfig()
      logger = logging.getLogger('foo')
      logger.setLevel(logging.INFO)
      logger.info(f'active')
      
      # main.py
      
      import cfg
      cfg.logger.info(f'main')
      

      【讨论】:

        猜你喜欢
        • 2023-03-23
        • 2011-07-26
        • 1970-01-01
        • 2017-07-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多