【问题标题】:Python logging - filter log messages for all loggersPython logging - 过滤所有记录器的日志消息
【发布时间】:2020-05-02 00:33:36
【问题描述】:

我有一个项目,其中底层工具正在记录,我也在记录(使用不同的记录器实例)。

但是,有时我无权访问的记录器会暴露我想从日志中删除的信息(或用占位符替换)。

我是否可以使用过滤器为项目中的所有 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)

真的,我的最终目标只是通过替换它们来防止某些内容在日志中弹出 - 如果有其他方法可以做到这一点,请随时分享。

谢谢!

【问题讨论】:

  • 如何初始化/配置日志记录?
  • 那么,你的问题是“如何过滤日志事件”,对吧?

标签: python logging


【解决方案1】:

如果您的主要目标是过滤敏感数据,请阅读Hiding Sensitive Data from Logs with Python。您可以实现logging.Filter 以防止记录某些记录,也可以实现loggingFormatter 以使用正则表达式仅减少特定记录的部分。

要将过滤器和格式化程序类应用于所有记录器,请在 dict 配置中定义它们并添加到您拥有的所有处理程序中。此外,请考虑通过设置disable_existing_loggers': True 删除任何未描述的处理程序。请参阅Django logging docs 中的自定义格式化程序和过滤器示例。

【讨论】:

    【解决方案2】:

    信不信由你,您确实可以访问那些底层项目的记录器!因为您在 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)
    

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

    【讨论】:

      【解决方案3】:

      如果您想将相同的日志记录配置传播给项目中的所有工作人员,我建议在您的 utils 中创建一个记录器文件,然后将其导入任何地方以使用它而不是 import logging

      如果您想确保您的配置与other handlers 不冲突,您可以执行以下操作

      文件 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")
      

      【讨论】:

        猜你喜欢
        • 2015-05-21
        • 2019-10-10
        • 2016-02-20
        • 1970-01-01
        • 2014-10-21
        • 1970-01-01
        • 2020-06-26
        • 2011-10-07
        • 2016-05-21
        相关资源
        最近更新 更多