如何在日志python中使用可调用文件作为过滤器



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

  • 我正在尝试使用dictConfig作为我的记录器(在python中)。在那个里,我想添加一个过滤器,这样,如果记录的消息包含某个短语,它就会通过
  • 我知道如何通过实现日志记录来做到这一点。筛选器类
  • 但我不知道如何使用这里所说的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的这一行出现问题

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

  • https://bugs.python.org/issue41906

例如

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实现中肯定需要一些东西来使它更加优雅。

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

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

无论哪种情况,我都在这里与蟒蛇爱好者开了一张罚单: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,
}
},

注意:您的filter函数返回true/false。

根据文件:过滤功能正在回答这个问题:

是否要记录指定的记录?对于否返回零,对于是返回非零。

因此您需要相应地调整您的函数。

最新更新