Python logging 添加 filter 实现自定义日志过滤
本文介绍如何在 Python 的 logging 模块中添加自定义 filter 以实现更灵活的日志过滤。通过示例展示了如何基于日志名称进行匹配过滤,以及如何结合 StreamHandler 对不同级别日志应用不同的过滤规则和输出格式,帮助开发者精确控制日志输出内容。
基于日志名称的自定义过滤逻辑
首先来看第一个示例,演示如何定义一个自定义的日志过滤逻辑。在 Python 的 logging 模块中,可以通过继承 logging.Filter 或为 Filter 实例的 filter 方法赋值来实现。以下代码展示了如何根据日志记录的名称(record.name)进行匹配过滤。如果 filters 列表为空,则默认允许所有日志通过;否则,遍历 filters 列表,检查日志名称是否完全匹配或为某个过滤名称的子级(以点号分隔),若匹配则允许记录通过。
def filter(self, record):
"""Our custom record filtering logic.
Built-in filtering logic (via logging.Filter) is too limiting.
"""
if not self.filters:
return True
matched = False
rname = record.name # shortcut
for name in self.filters:
if rname == name or rname.startswith(name+'.'):
matched = True
return matched
区分不同级别日志的输出格式
第二个示例展示了如何创建默认的日志处理程序列表,并区分不同级别的日志输出格式。该函数接收一个流对象(stream)作为参数,返回包含两个 StreamHandler 实例的列表。第一个处理程序(error_handler)负责输出 WARNING 级别及以上的日志,其格式包含日志级别和消息内容。第二个处理程序(non_error_handler)负责输出低于 WARNING 级别的日志,通过添加一个自定义的 logging.Filter 实例来实现过滤,该过滤器仅接受 levelno 小于 logging.WARNING 的记录,其格式仅包含消息内容,不包含级别信息。
def _create_log_handlers(stream):
"""Create and return a default list of logging.Handler instances.
Format WARNING messages and above to display the logging level, and
messages strictly below WARNING not to display it.
Args:
stream: See the configure_logging() docstring.
"""
# Handles logging.WARNING and above.
error_handler = logging.StreamHandler(stream)
error_handler.setLevel(logging.WARNING)
formatter = logging.Formatter("%(levelname)s: %(message)s")
error_handler.setFormatter(formatter)
# Create a logging.Filter instance that only accepts messages
# below WARNING (i.e. filters out anything WARNING or above).
non_error_filter = logging.Filter()
# The filter method accepts a logging.LogRecord instance.
non_error_filter.filter = lambda record: record.levelno < logging.WARNING
non_error_handler = logging.StreamHandler(stream)
non_error_handler.addFilter(non_error_filter)
formatter = logging.Formatter("%(message)s")
non_error_handler.setFormatter(formatter)
return [error_handler, non_error_handler]
特定模块日志的屏蔽处理
第三个示例演示了如何创建默认的日志处理程序,并应用特定的过滤规则以控制特定模块的日志输出。该函数同样接收流对象作为参数,返回一个包含单个 StreamHandler 实例的列表。首先定义一个 should_log 函数,用于判断日志记录是否应该被记录。在此示例中,如果日志名称以 'webkitpy.thirdparty.autoinstall' 开头,则返回 False 以过滤掉这些日志(注释中提到这是因为自动安装模块在导入已下载包时会产生过多的 INFO 日志)。接着,创建一个 logging.Filter 实例,并将其 filter 方法赋值为 should_log 函数。最后,创建 StreamHandler 并设置格式为包含日志名称、级别和消息,同时将该过滤器添加到处理程序中。
def _default_handlers(stream):
"""Return a list of the default logging handlers to use.
Args:
stream: See the configure_logging() docstring.
"""
# Create the filter.
def should_log(record):
"""Return whether a logging.LogRecord should be logged."""
# FIXME: Enable the logging of autoinstall messages once
# autoinstall is adjusted. Currently, autoinstall logs
# INFO messages when importing already-downloaded packages,
# which is too verbose.
if record.name.startswith("webkitpy.thirdparty.autoinstall"):
return False
return True
logging_filter = logging.Filter()
logging_filter.filter = should_log
# Create the handler.
handler = logging.StreamHandler(stream)
formatter = logging.Formatter("%(name)s: [%(levelname)s] %(message)s")
handler.setFormatter(formatter)
handler.addFilter(logging_filter)
return [handler]
以上介绍了在 Python logging 中添加 filter 的几个常见示例,涵盖了基于名称的过滤、不同级别日志的差异化处理以及特定模块的日志屏蔽。这些方法可以帮助开发者更精细地控制日志输出,提高日志系统的可用性和可读性。希望这些示例能为大家在实际项目中配置日志系统提供参考,也欢迎大家继续支持本站获取更多技术内容。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









