我不知道如何使用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。
根据文件:过滤功能正在回答这个问题:
是否要记录指定的记录?对于否返回零,对于是返回非零。
因此您需要相应地调整您的函数。