【问题标题】:install filter on logging level in python using dictConfig使用 dictConfig 在 python 的日志记录级别上安装过滤器
【发布时间】:2014-01-30 11:41:26
【问题描述】:

我无法使用dictConfig() 语法在日志处理程序上安装过滤器。 LoggingErrorFilter.filter() 被忽略,没有任何反应。

我想过滤掉错误消息,这样它们就不会在日志输出中出现两次。所以我写了LoggingErrorFilter 类并覆盖了filter()

我的配置:

class LoggingErrorFilter(logging.Filter):
  def filter(self, record):
    print 'filter!'
    return record.levelno == logging.ERROR or record.levelno == logging.CRITICAL

config = {
      'version': 1,
      'disable_existing_loggers' : False,
      'formatters' : {
        'standard' : {
          'format' : '%(asctime)s %(levelname)s %(name)s::%(message)s',
        },
      },
      'handlers' : {
        'console': {
          'class' : 'logging.StreamHandler',
          'level' : level,
          'formatter' : 'standard',
          'stream' : 'ext://sys.stdout',
        },
        'errorconsole': {
          'class' : 'logging.StreamHandler',
          'level' : 'ERROR',
          'formatter' : 'standard',
          'stream' : 'ext://sys.stderr',
          'filters'  :['errorfilter',],
        },
      },
      'filters': {
        'errorfilter': {
          'class' : 'LoggingErrorFilter',
        }
      },
      'loggers' : {
        '' : {
          'handlers' : ['errorconsole','console',],
          'level' : level,
          'propagate' : True,
        },
        name : {
          'handlers' : ['errorconsole','console',],
          'level' : level,
          'propagate' : False,
        },
      },
  }
  logging.config.dictConfig(config)

我在这里做错了什么?为什么我的过滤器被忽略了?

【问题讨论】:

    标签: python python-2.7 logging


    【解决方案1】:

    其实Tupteq的回答一般来说是不正确的。以下脚本:

    import logging
    import logging.config
    import sys
    
    class MyFilter(logging.Filter):
        def __init__(self, param=None):
            self.param = param
    
        def filter(self, record):
            if self.param is None:
                allow = True
            else:
                allow = self.param not in record.msg
            if allow:
                record.msg = 'changed: ' + record.msg
            return allow
    
    LOGGING = {
        'version': 1,
        'filters': {
            'myfilter': {
                '()': MyFilter,
                'param': 'noshow',
            }
        },
        'handlers': {
            'console': {
                'class': 'logging.StreamHandler',
                'filters': ['myfilter']
            }
        },
        'root': {
            'level': 'DEBUG',
            'handlers': ['console']
        },
    }
    
    if __name__ == '__main__':
        print(sys.version)
        logging.config.dictConfig(LOGGING)
        logging.debug('hello')
        logging.debug('hello - noshow')
    

    运行时,产生以下输出:

    $ python filtcfg.py 
    2.7.5+ (default, Sep 19 2013, 13:48:49) 
    [GCC 4.8.1]
    changed: hello
    

    这表明您可以使用dictConfig() 配置过滤器。

    【讨论】:

    • 我的错误是我在类名周围使用了引号。配置字典预期的对象类型,而不是类型的名称。谢谢!
    • 它是否适用于 yml 配置?我正在尝试,但没有运气
    • 我不得不使用小型工厂方法:def new_instance(): return MyLoggingFilter()'()': 'MyLoggingFilter.new_instance'
    【解决方案2】:

    你可以指定一个类名,但它是用奇怪的() 键完成的,它必须包含模块名。例如:

     'filters': {
        'errorfilter': {
          '()' : '__main__.LoggingErrorFilter',
        }
      },
    

    请参阅文档中的16.7.2.4. User-defined objects

    【讨论】:

    • 我不记得我是怎么想出来的。但是特殊的() 键记录在docs.python.org/3/library/… 中。我现在也在答案中添加了链接。谢谢!
    【解决方案3】:

    如果想从 json 文件加载。应该是这样的

    {
      "version": 1,
      "grey": "/x1b[38;21m",
      "yellow": "/x1b[33;21m",
      "red": "/x1b[31;21m",
      "bold_red": "/x1b[31;1m",
      "reset": "/x1b[0m",
      "filters": {
        "audit_filter": {
          "()": "app.logs.AuditFilter.AuditFilter",
          "param": "audit"
        },
        "ignore_audit_filter": {
          "()": "app.logs.AuditFilter.IgnoreAuditFilter",
          "param": "audit"
        }
      },
      "formatters": {
        "package_formatter": {
          "format": "[%(asctime)s] - [%(levelname)s] - [%(name)s] : %(message)s"
        }
      },
      "handlers": {
        "console": {
          "class": "logging.StreamHandler",
          "level": "DEBUG",
          "formatter": "package_formatter"
        },
        "development_file_handler": {
          "class": "logging.FileHandler",
          "filename": "../debug.log",
          "level": "DEBUG",
          "formatter": "package_formatter",
          "filters": [
            "ignore_audit_filter"
          ]
        },
        "audit_file_handler": {
          "class": "logging.FileHandler",
          "filename": "../audit.log",
          "level": "DEBUG",
          "formatter": "package_formatter",
          "filters": [
            "audit_filter"
          ]
        }
      },
      "loggers": {
        "audit": {
          "handlers": [
    
            "audit_file_handler"
          ],
          "level": "INFO"
        }
      },
      "root": {
        "level": "INFO",
        "handlers": [
          "console",
          "development_file_handler"
        ]
      }
    }
    

    初始化然后附加记录器并运行记录器 使用app.logger = logging.getlogger("audit")

    运行应用程序

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      • 1970-01-01
      • 2017-06-04
      • 2016-08-15
      • 1970-01-01
      • 1970-01-01
      • 2018-04-26
      相关资源
      最近更新 更多