Django 日志记录 - 自定义过滤器适用于处理程序,但不适用于记录器



我有一个这样的自定义过滤器:

proj/proj/log_utils/filters.py:

import logging
class OnlyThisSeverity(logging.Filter):
def filter(self, record):
print('levelname: {}'.format(record.levelname))
return record.levelno == logging.INFO

Django 设置看起来像这样:

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},        
},
'filters': {
'only_this_severity': {
'()': 'android_blend.log_utils.filters.OnlyThisSeverity',
}
},
'loggers': {
'my_app': {
'handlers': ('console',),  # 'console'
'level': 'INFO',
'propagate': False,
'filters': ['only_this_severity']
},
}
}

my_app/test.py里面,我有一个这样的函数:

import logging
logger = logging.getLogger(__name__)
def handle(self, *args, **kwargs):
logger.info('Reporting info......')
logger.error('Reporting error......')

如果我的筛选器工作正常,我应该只在控制台中看到Reporting info,而我看到两行。 所以问题是only_this_severity过滤器被忽略了。 但是,如果我在console处理程序定义中移动filters,则实现了我的目标。我做错了什么?我希望过滤器工作 对于记录器my_app,而不仅仅是在处理程序级别。 我的最终目标是改变日志记录库的自定义行为。也就是说,对于级别"X"的处理程序,我希望他们只尊重级别"X"的记录,而不是"X 及更高"的记录。

即使在记录器级别添加过滤器,您的过滤器似乎也能正常工作。

这是我当前的输出:

levelname: INFO
Reporting info......
levelname: ERROR

这显示了代码如何在两个日志操作中到达筛选器,但筛选错误记录。

我认为问题可能出在记录器层次结构中。当您将test.py用作导入的模块时,您获得的不是'my_app'记录器,而是不存在的'my_app.test'

发生这种情况时,核心将检索根记录器并将默认配置"传播"到名为'my_app.test'的新记录器,并将其包含在日志层次结构中。此记录器没有启用您的过滤器。

尝试通过传递其名称来强制获取'my_app'记录器:

import logging
logger = logging.getLogger('my_app')
def handle(self, *args, **kwargs):
logger.info('Reporting info......')
logger.error('Reporting error......')

或者,可以使用根记录器定义筛选器,然后让应用程序为您创建层次结构:

LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},        
},
'filters': {
'only_this_severity': {
'()': 'android_blend.log_utils.filters.OnlyThisSeverity',
}
},
'loggers': {
'root': {
'handlers': ('console',),  # 'console'
'level': 'INFO',
'filters': ['only_this_severity']
},
}
}

我个人喜欢这种方法,因为可以安全地调用

logger = logging.getLogger(__name__)

以显示(使用正确的格式化程序(您正在记录的模块。

从 https://docs.python-guide.org/writing/logging/

在库中实例化记录器的最佳做法是仅 使用__name__全局变量创建它们:日志记录模块 使用点表示法创建记录器的层次结构,因此使用__name__确保没有名称冲突。

相关内容

最新更新