不管过滤器如何,Python记录器始终输出调试消息

时间:2019-06-12 08:42:14

标签: python-3.x python-logging

我当前正在创建logging.Logger的子类,该子类具有基于级别的过滤器,并且该级别可以在记录调用之间更改(因此,为什么我使用过滤器而不是{{ 1}})。但是,无论过滤器如何,看来我的记录器始终会打印出级别为setLevel()的消息。这是我的下面的代码

DEBUG

上面的代码提供以下输出:

import logging


class _LevelFilter(logging.Filter):

    def filter(self, record):
        SimpleLogger.setLevel(_DEFAULT_LEVEL)
        return 1 if SimpleLogger.isEnabledFor(record.levelno) else 0


class _SimpleLogger(logging.getLoggerClass()):
    def __init__(self, name=None, level=logging.DEBUG):
        super().__init__(name, level)
        self.setLevel(logging.DEBUG)
        _handler = logging.StreamHandler()
        _handler.setLevel(logging.DEBUG)
        self.addHandler(_handler)
        self.addFilter(_LevelFilter())


_DEFAULT_LEVEL = 'WARNING'
SimpleLogger = _SimpleLogger()

if __name__ == '__main__':
    SimpleLogger.debug('testing debug')
    SimpleLogger.info('testing info')
    SimpleLogger.warning('testing warning')
    SimpleLogger.critical('testing critical')
    SimpleLogger.debug('testing debug')

我知道,如果我将testing debug testing warning testing critical testing debug 声明为一个单独的变量而不是一个子类,则它可以工作,但是出于各种原因,我需要使用该子类。作为参考,这是一个不使用有效子类的版本。

SimpleLogger

我一生都无法弄清为什么总是打印调试消息。子类版本和非子类版本之间的差异不是很大,并且设置级别应该导致调试和信息消息不出现。任何帮助将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:2)

我终于找到了解决方案!因此,事实证明python 3.7向记录器引入了缓存,该记录器缓存了isEnabledFor()的结果。由于筛选器是在最初的isEnabledFor()检查之后运行的,因此仍会缓存旧的结果,从而导致这种奇怪的行为。解决方案是不要以这种方式使用过滤器。取而代之的是,我确实想要获得记录器有效级别的替代方法。 这是固定记录器的代码:

编辑:事实证明,我原来的解决方案仍然不起作用,并且缓存问题仍然存在。看来这是特定于logging.getLoggerClass()子类的记录器的,因此您每次都需要清除缓存。新的解决方案如下。 (此外,我将其简化为仅包含必要的内容。)

Forms(frmName).Label80.Caption = Format(CDbl(Replace(Forms(frmName).Label123.Caption, "%", "")) + CDbl(Replace(Forms(frmName).Label162.Caption, "%", "")), "Percent")