logging.error() 被调用了多少次?

发布于 2024-07-17 19:44:54 字数 85 浏览 9 评论 0原文

也许它根本不存在,因为我找不到它。 但是使用 python 的日志记录包,有没有办法查询记录器以找出特定函数被调用的次数? 例如,报告了多少错误/警告?

Maybe it's just doesn't exist, as I cannot find it. But using python's logging package, is there a way to query a Logger to find out how many times a particular function was called? For example, how many errors/warnings were reported?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夜清冷一曲。 2024-07-24 19:44:55

日志记录模块似乎不支持此功能。 从长远来看,您可能最好创建一个新模块,并通过对现有日志记录模块中的项目进行子类化来添加此功能,以添加您需要的功能,但您也可以使用装饰器轻松实现此行为:

class CallCounted:
    """Decorator to determine number of calls for a method"""

    def __init__(self,method):
        self.method=method
        self.counter=0

    def __call__(self,*args,**kwargs):
        self.counter+=1
        return self.method(*args,**kwargs)


import logging
logging.error = CallCounted(logging.error)
logging.error('one')
logging.error('two')
print(logging.error.counter)

输出:

ERROR:root:one
ERROR:root:two
2

The logging module doesn't appear to support this. In the long run you'd probably be better off creating a new module, and adding this feature via sub-classing the items in the existing logging module to add the features you need, but you could also achieve this behavior pretty easily with a decorator:

class CallCounted:
    """Decorator to determine number of calls for a method"""

    def __init__(self,method):
        self.method=method
        self.counter=0

    def __call__(self,*args,**kwargs):
        self.counter+=1
        return self.method(*args,**kwargs)


import logging
logging.error = CallCounted(logging.error)
logging.error('one')
logging.error('two')
print(logging.error.counter)

Output:

ERROR:root:one
ERROR:root:two
2
路还长,别太狂 2024-07-24 19:44:55

您还可以向记录器添加一个新的处理程序来计算所有调用:

class MsgCounterHandler(logging.Handler):
    level2count = None

    def __init__(self, *args, **kwargs):
        super(MsgCounterHandler, self).__init__(*args, **kwargs)
        self.level2count = {}

    def emit(self, record):
        l = record.levelname
        if (l not in self.level2count):
            self.level2count[l] = 0
        self.level2count[l] += 1

然后您可以使用字典来输出调用数。

You can also add a new Handler to the logger which counts all calls:

class MsgCounterHandler(logging.Handler):
    level2count = None

    def __init__(self, *args, **kwargs):
        super(MsgCounterHandler, self).__init__(*args, **kwargs)
        self.level2count = {}

    def emit(self, record):
        l = record.levelname
        if (l not in self.level2count):
            self.level2count[l] = 0
        self.level2count[l] += 1

You can then use the dict afterwards to output the number of calls.

困倦 2024-07-24 19:44:55

有一个 warnings 模块 -在某种程度上——做了一些这样的事情。

您可能希望将此计数功能添加到自定义 Handler 。 问题是有一百万个处理程序,您可能希望将其添加到多个类型中。

您可能想将其添加到过滤器,因为那是独立于正在使用的处理程序。

There'a a warnings module that -- to an extent -- does some of that.

You might want to add this counting feature to a customized Handler. The problem is that there are a million handlers and you might want to add it to more than one kind.

You might want to add it to a Filter, since that's independent of the Handlers in use.

乜一 2024-07-24 19:44:55

基于罗尔夫的回答如何将字典写入文件,这里是另一个将计数存储在 json 文件中的解决方案。 如果 json 文件存在并且 continue_counts=True,它将恢复初始化时的计数。

import json
import logging
import logging.handlers
import os


class MsgCounterHandler(logging.Handler):
    """
    A handler class which counts the logging records by level and periodically writes the counts to a json file.
    """

    level2count_dict = None

    def __init__(self, filename, continue_counts=True, *args, **kwargs):
        """
        Initialize the handler.

        PARAMETER
        ---------
        continue_counts: bool, optional
            defines if the counts should be loaded and restored if the json file exists already.
        """
        super(MsgCounterHandler, self).__init__(*args, **kwargs)

        filename = os.fspath(filename)
        self.baseFilename = os.path.abspath(filename)

        self.continue_counts = continue_counts

        # if another instance of this class is created, get the actual counts
        if self.level2count_dict is None:
            self.level2count_dict = self.load_counts_from_file()

    def emit(self, record):
        """
        Counts a record.
        In case, create add the level to the dict.
        If the time has come, update the json file.
        """
        level = record.levelname
        if level not in self.level2count_dict:
            self.level2count_dict[level] = 0
        self.level2count_dict[level] += 1

        self.flush()

    def flush(self):
        """
        Flushes the dictionary.
        """
        self.acquire()
        try:
            json.dump(self.level2count_dict, open(self.baseFilename, 'w'))
        finally:
            self.release()

    def load_counts_from_file(self):
        """
        Load the dictionary from a json file or create an empty dictionary
        """
        if os.path.exists(self.baseFilename) and self.continue_counts:
            try:
                level2count_dict = json.load(open(self.baseFilename))
            except Exception as a:
                logging.warning(f'Failed to load counts with: {a}')
                level2count_dict = {}
        else:
            level2count_dict = {}
        return level2count_dict

Based on Rolf's answer and how to write a dictionary to a file, here another solution which stores the counts in a json file. In case the json file exists and continue_counts=True, it restores the counts on initialisation.

import json
import logging
import logging.handlers
import os


class MsgCounterHandler(logging.Handler):
    """
    A handler class which counts the logging records by level and periodically writes the counts to a json file.
    """

    level2count_dict = None

    def __init__(self, filename, continue_counts=True, *args, **kwargs):
        """
        Initialize the handler.

        PARAMETER
        ---------
        continue_counts: bool, optional
            defines if the counts should be loaded and restored if the json file exists already.
        """
        super(MsgCounterHandler, self).__init__(*args, **kwargs)

        filename = os.fspath(filename)
        self.baseFilename = os.path.abspath(filename)

        self.continue_counts = continue_counts

        # if another instance of this class is created, get the actual counts
        if self.level2count_dict is None:
            self.level2count_dict = self.load_counts_from_file()

    def emit(self, record):
        """
        Counts a record.
        In case, create add the level to the dict.
        If the time has come, update the json file.
        """
        level = record.levelname
        if level not in self.level2count_dict:
            self.level2count_dict[level] = 0
        self.level2count_dict[level] += 1

        self.flush()

    def flush(self):
        """
        Flushes the dictionary.
        """
        self.acquire()
        try:
            json.dump(self.level2count_dict, open(self.baseFilename, 'w'))
        finally:
            self.release()

    def load_counts_from_file(self):
        """
        Load the dictionary from a json file or create an empty dictionary
        """
        if os.path.exists(self.baseFilename) and self.continue_counts:
            try:
                level2count_dict = json.load(open(self.baseFilename))
            except Exception as a:
                logging.warning(f'Failed to load counts with: {a}')
                level2count_dict = {}
        else:
            level2count_dict = {}
        return level2count_dict
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文