简体   繁体   English

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

[英]Python logging - filter log messages for all loggers

I have a project where the underlying tools are logging, and I'm also logging (with different logger instances).我有一个底层工具正在记录的项目,我也在记录(使用不同的记录器实例)。

However, sometimes the logger I don't have access to exposes information which I'd like to strip out of the log (or replace with a placeholder).但是,有时我无权访问的记录器会公开我想从日志中删除的信息(或用占位符替换)。

Is there a way I can use a filter to do that for all python loggers in a project?有没有办法可以使用过滤器为项目中的所有python 记录器执行此操作?

Here is my logging configuration in Django:这是我在 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)

Really, my end goal is just to prevent certain things from popping up in logs by replacing them – if there's some other way to do that, feel free to share it.真的,我的最终目标只是通过替换它们来防止某些东西出现在日志中——如果有其他方法可以做到这一点,请随时分享。

Thanks!谢谢!

If your main goal is to filter sensitive data, read Hiding Sensitive Data from Logs with Python .如果您的主要目标是过滤敏感数据,请阅读使用 Python 从日志中隐藏敏感数据 You can either implement a logging.Filter to prevent logging some records or implement a loggingFormatter to reduct only specific records' parts with a regex.您可以实现logging.Filter以防止记录某些记录,也可以实现loggingFormatter以仅使用正则表达式减少特定记录的部分。

To apply the filters and formatters classes to all loggers define them in the dict config and add to all the handlers you have.要将过滤器和格式化程序类应用于所有记录器,请在 dict 配置中定义它们并添加到您拥有的所有处理程序中。 Also, consider removing any undescribed handlers by setting disable_existing_loggers': True .此外,请考虑通过设置disable_existing_loggers': True删除任何未描述的处理程序。 See examples of custom formatters and filters in the Django logging docs .Django logging docs 中查看自定义格式化程序和过滤器的示例。

Believe it or not, you do have access to those underlying projects' loggers!信不信由你,您确实可以访问那些底层项目的记录器! Because you are in django, Your settings can be loaded, and logging can be initialized, before those underlying projects' loggers are instantiated.因为您在 django 中,所以可以在实例化那些底层项目的记录器之前加载您的设置,并初始化日志记录。

This is a two-step process.这是一个两步过程。 The first step is to identify the logger that is the source of the message you'd like to suppress.第一步是确定作为您要禁止显示的消息来源的记录器。 To do this, add name to my_formatter :为此,请将name添加到my_formatter

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

Once we've found the name, we can define our filter.找到名称后,我们可以定义过滤器。

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

And now since you know the name of the logger that is producing the bad message, we can attach our AwesomeFilter to the logger:现在既然你知道产生坏消息的记录器的名称,我们可以将我们的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)

We use the trick of finding the name of the logger to control the output of logging for third-party libraries quite frequently.我们经常使用查找记录器名称的技巧来控制第三方库的日志记录输出。 Good luck!祝你好运!

If you want to propagate the same logging config to all workers in your project I suggest making a logger file in your utils and then import it everywhere to use it instead of import logging如果您想将相同的日志配置传播给项目中的所有工作人员,我建议在您的 utils 中创建一个记录器文件,然后将其导入到任何地方以使用它而不是import logging

If you want to make sure your config is not in conflict with other handlers you can do as follows如果您想确保您的配置不与其他处理程序冲突,您可以执行以下操作

file utils/log.py文件 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()

Then simply import this logger in all your workers instead of logging library然后只需在所有工作人员中导入此记录器,而不是记录库

from utils.log import logger

logger.info("Hello world")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM