如何查看Python日志的最大错误级别?

问题描述 投票:0回答:2

使用 python 的

logging
模块,如果记录了错误或关键,我想返回非零,如果没有记录错误或关键,则返回零。我是否必须添加一个层来捕获它,或者这是本机功能吗?

import logging
def CheckMaxErr():
        pass

logging.debug("Cat")
CheckMaxErr() #should return logging.DEBUG
logging.error("Dog")
CheckMaxErr() #should return logging.ERROR
python logging
2个回答
1
投票

您可以实现日志处理程序的子类,并在实例上设置标志属性(如果曾经调用过该实例)。您可以将处理程序的级别设置为

logging.ERROR
级别,以使其在这些消息上触发。

import logging

class MyHandler(logging.Handler):
    def __init__(self):
        super().__init__()
        self.flag = False

    def emit(self, record):
        self.flag = True

logger = logging.getLogger(__name__)
handle = MyHandler()
handle.setLevel(logging.ERROR)

logger.addHandler(handle)

logger.debug("debug message")
print(handle.flag)  # False
logger.error("ERROR")
print(handle.flag)  # True

在此示例中,处理程序实际上并未对消息执行任何操作,只是在触发时设置标志。您可以添加另一个处理程序来记录到您想要的任何位置(控制台、文件等)


0
投票

@Alex 提供的解决方案有一个令人沮丧的限制,那就是

CheckMaxError()
如何获取对处理程序的引用以查询所看到的最大级别。

如果您位于包含自定义处理程序的变量范围内,这当然是微不足道的,但否则就相当困难。例如,在一个多类项目中,您有

A.py

class A:
    def __init__(self):
        self.log = logging.Logger("MyLog")
        ...
    def myMethodA():
        ...
        self.log.info("some message")
        ...

B.py

class B:
    def __init__(self):
        self.log = logging.Logger("MyLog")
        ...
    def myMethodB():
        ...
        self.log.info("some message")
        ...

main.py

...
if __name__== "__main__":
    log = logging.Logger("MyLog")
    hdlr = MyHandler()
    log.addHandler(hdlr)
    ...

现在,如何实现

CheckMaxError()
,使其可以从项目中的任何位置调用,即从类
A
B
中调用?他们没有对自定义处理程序的引用,只有
Logger
。记录器保留已注册处理程序的列表,但没有简单的方法来检索特定处理程序,并且如果没有对自定义处理程序的引用,您将无法查询最大级别。

有一个非常简单的解决方案,子类化

logging.Logger

MyLogger.py

class MyLogger(logging.Logger):
    def __init__(self, name, level=logging.NOTSET):
        logging.Logger.__init__(self, name, level)
        self.maxLevel = 0
    
    # Override _log() method to save maximum level seen
    def _log(self, level, msg, *args, **kwargs):
        super()._log(level, msg, *args, **kwargs)
        self.maxLevel = max(level, self.maxLevel)

main
中记录初始化:

logging.setLoggerClass(MyLogger)
logger = logging.getLogger(name)

现在可以查询任意点的最大等级为

logger.maxLevel

OO 纯粹主义者会反对,认为覆盖“私有”方法

_log()
是不行的,但文档和代码都表明它是为了
logging.Logger
进行子类化。

我认为“理想”的解决方案是通过添加公共方法

Logger
来扩展
logHook(logger:Logger)
,该方法在
Logger
中为空,但在子类中可以重写。
logHook
将在
_log()
方法中调用,让您有机会以某种方式对每个日志条目做出反应。

© www.soinside.com 2019 - 2024. All rights reserved.