web-dev-qa-db-ja.com

dictConfigを使用してpython)のログレベルにフィルターをインストールします

dictConfig()構文を使用してロギングハンドラーにフィルターをインストールできません。 LoggingErrorFilter.filter()は単に無視され、何も起こりません。

エラーメッセージを除外して、ログ出力に2回表示されないようにします。そこで、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)

私はここで何が間違っているのですか?フィルタが無視されるのはなぜですか?

26
Pavlo Dyban

実際、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
_

これは、candictConfig()を使用してフィルターを構成することを示しています。

30
Vinay Sajip

クラス名を指定することはできますが、それは奇妙な名前の()キーで行われ、モジュール名を含める必要があります。例えば。:

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

ドキュメントの 16.7.2.4。ユーザー定義オブジェクト を参照してください。

7
Daniel Darabos