Python日志记录 - 过滤所有记录器的日志消息

11

我的项目中使用了日志记录工具,并且我也在记录日志(使用不同的记录器实例)。

然而,有时我无法访问某些记录器,它们会暴露一些我想要从日志中剥离出来(或用占位符替换)的信息。

是否有办法使用过滤器为项目中所有的Python记录器完成这个操作?

以下是我在Django中的日志配置:

LOGGING_CONFIG = None
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "my_formatter": {
            "format": "[%(asctime)s] %(message)s",
            "datefmt": "%d/%b/%Y %H:%M:%S",
        },
    },
    "handlers": {
        "console": {
            "level": "DEBUG",
            "class": "logging.StreamHandler",
            "formatter": "my_formatter",
        },
    },
    "loggers": {
        "my_logger": {
            "handlers": ["console"],
            "level": "DEBUG"
        },
    },
}

logging.config.dictConfig(LOGGING)

实际上,我的最终目标只是通过替换来防止某些事情在日志中弹出 - 如果有其他方法,请随意分享。

谢谢!


你如何初始化/配置日志记录? - Klaus D.
所以,你的问题是“如何过滤日志事件”,对吗? - pbacterio
3个回答

5

如果您的主要目标是过滤敏感数据,请阅读使用Python隐藏日志中的敏感数据。您可以实现一个logging.Filter来防止记录某些内容,或者实现loggingFormatter以使用正则表达式仅减少特定记录的部分。

要将过滤器和格式化程序应用于所有记录器,请在字典配置中定义它们,并添加到您拥有的所有处理程序。此外,请考虑通过设置disable_existing_loggers': True来删除任何未描述的处理程序。在Django日志文档中查看自定义格式化程序和过滤器的示例。


3

信不信由你,你确实可以访问那些底层项目的日志记录器!因为你在django中,可以在这些底层项目的记录器实例化之前加载你的设置并初始化日志记录。

这是一个两步骤的过程。第一步是识别出你想要抑制的消息源头的记录器。为此,请将name添加到my_formatter中:

    "formatters": {
        "my_formatter": {
            "format": "[%(asctime)s] [%(name)s] %(message)s",
            "datefmt": "%d/%b/%Y %H:%M:%S",
        },
    },

当我们找到名称后,就可以定义过滤器。

import logging


class AwesomeFilter(logging.Filter):
    def filter(self, rec):
        if 'sensitive' in rec.msg:
            return 0
        # you may need to filter based on `getMessage()` if
        # you can't find the information in the pre-formatted msg field
        return 1

现在你知道产生错误信息的记录器的名称,我们可以将 AwesomeFilter 附加到记录器上:

LOGGING_CONFIG = None
LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "my_formatter": {
            "format": "[%(asctime)s] [%(name)s] %(message)s",
            "datefmt": "%d/%b/%Y %H:%M:%S",
        },
    },
    "handlers": {
        "console": {
            "level": "DEBUG",
            "class": "logging.StreamHandler",
            "formatter": "my_formatter",
        },
    },
    "loggers": {
        "my_logger": {
            "handlers": ["console"],
            "level": "DEBUG"
        },
        "name_of_logger_producing_bad_messages": {
            "filters": [ "app.filters.AwesomeFilter", ],
        },
    },
}

logging.config.dictConfig(LOGGING)

我们经常使用查找记录器名称的技巧来控制第三方库的日志输出。祝你好运!

1
如果您想将相同的日志配置传播到项目中的所有工作进程,我建议在您的工具中创建一个记录器文件,然后在各处导入它以代替import logging
如果您想确保您的配置不会与其他处理程序冲突,可以按以下方式操作。
文件utils/log.py
import logging
import os

root = logging.getLogger()
if root.handlers:
    for handler in root.handlers:
        root.removeHandler(handler)]
LOGGING_CONFIG=[your config]
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger()

然后,只需在所有的工作进程中导入此记录器,而不是日志库。
from utils.log import logger

logger.info("Hello world")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接