3

我不知道如何使用python3.2的这个新属性。在那里,可以使用可调用对象,而不是实现 logging.Filter 类。

  • 我正在尝试将dictConfig用于我的记录器(在 python 中)。在那,我想添加一个过滤器,如果记录的消息包含某个短语,它将通过。
  • 我知道如何通过实现 logging.Filter 类来做到这一点。
  • 但我不知道如何使用 python 3.2 的可调用“花式”属性,如此处所述

好代码在这里

class ignore_progress(logging.Filter):
    def filter(self, record):

        return not ('Progress' in record.getMessage())
class log_progress(logging.Filter):
    def filter(self, record):
        return ('Progress' in record.getMessage())
def contain_progress(record):
    return not ('Progress' in record.message)
logging_dict = {
    "version": 1,
    "disable_existing_loggers": False,  
    "formatters": {
        "standard": {
            "format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s",
        }
    },
    "filters": {
         "ignore_progress": {
            '()': ignore_progress,
        }
    },
    "handlers": {
        "default": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "standard",
        },
        "file": {
            "class": "logging.FileHandler",
            "level": "DEBUG",
            "formatter": "standard",
            "filename": 'training_{}.log'.format(str(datetime.date.today())),
            "filters": ["ignore_progress"],
        },
    },
    "loggers": {
        "": {"handlers": ["default", "file"], "level": "DEBUG", "propagate": True, },
    },
}
# Configurate the logger
logging.config.dictConfig(logging_dict)
logger = logging.getLogger(__name__)

logger.info("Run training")
logger.info("Progress.test")

这里的代码不好

class ignore_progress(logging.Filter):
    def filter(self, record):

        return not ('Progress' in record.getMessage())
class log_progress(logging.Filter):
    def filter(self, record):
        return ('Progress' in record.getMessage())
def contain_progress(record):
    return not ('Progress' in record.message)
logging_dict = {
    "version": 1,
    "disable_existing_loggers": False,  
    "formatters": {
        "standard": {
            "format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s",
        }
    },
    "filters": {
         "ignore_progress": {
            '()': contain_progress,
        }
    },
    "handlers": {
        "default": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "formatter": "standard",
        },
        "file": {
            "class": "logging.FileHandler",
            "level": "DEBUG",
            "formatter": "standard",
            "filename": 'training_{}.log'.format(str(datetime.date.today())),
            "filters": ["ignore_progress"],
        },
    },
    "loggers": {
        "": {"handlers": ["default", "file"], "level": "DEBUG", "propagate": True, },
    },
}
# Configurate the logger
logging.config.dictConfig(logging_dict)
logger = logging.getLogger(__name__)

logger.info("Run training")
logger.info("Progress.test")

上面的坏代码在这一有问题config.py

4

3 回答 3

1

在 dictConfig 中使用 Callable 时,您放入 dictConfig 值的 Callable 必须是一个 Callable,它返回一个 Callable,如 Python Bug Tracker 中所述:

例如

def my_filter_wrapper():
    # the returned Callable has to accept a single argument (the LogRecord instance passed in this callable) with return value of 1 or 0
    return lambda record: 0 if <your_condition_here> else 1

logging_dict = {
    ...
    'filters': {
         'ignore_progress': {
            '()': my_filter_wrapper,
        }
    },
    ...

如果您的自定义过滤逻辑是单行的并且独立于日志记录实例,则甚至更简单:

logging_dict = {
    ...
    'filters': {
         'ignore_progress': {
            '()': lambda : lambda _: 0 if <your_condition> else 1
        }
    },
    ...

我花了很长时间才弄清楚这一点。希望它可以帮助任何有同样问题的人。

在它的 Python 实现中肯定需要一些东西来使它更优雅。

于 2021-02-23T08:12:17.507 回答
0

这不起作用,因为它是一个错误或文档不正确。

在任何一种情况下,我都在这里与 python 人开了一张票:https ://bugs.python.org/issue41906

解决方法

如果您返回一个返回函数的函数,那么一切都会正常工作。

例如:

def no_error_logs():
    """
    :return: function that returns 0 if log should show, 1 if not
    """
    return lambda param: 1 if param.levelno < logging.ERROR else 0

然后

    "filters": {
        "myfilter": {
            "()": no_error_logs,
        }
    },

注意:您的过滤器函数返回真/假。

根据文档:过滤器功能正在回答问题:

是否要记录指定的记录?返回零表示否,非零表示是。

所以你需要相应地调整你的功能。

于 2020-10-02T01:11:06.257 回答
0

我建议使用loguru作为日志包。您可以轻松地为您的记录器添加一个处理程序。

于 2019-09-12T10:13:27.197 回答