I cannot install a filter on a logging handler using dictConfig()
syntax. LoggingErrorFilter.filter()
is simply ignored, nothing happens.
I want to filter out error messages so that they do not appear twice in the log output. So I wrote LoggingErrorFilter
class and overrode filter()
.
My configuration:
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)
What am I doing wrong here? Why is my filter ignored?
dictConfig (config) Takes the logging configuration from a dictionary. The contents of this dictionary are described in Configuration dictionary schema below.
Logging in PythonYou can configure logging using the module and class functions or by creating a config file or a dictionary and loading it using fileConfig() or dictConfig() respectively. These are useful in case you want to change your logging configuration in a running application.
A filter provides an optional, secondary control over what is logged, beyond the control that is provided by setting the level. Applications can apply a filter mechanism to control logging output through the logging APIs. An example of filter usage is to suppress all the events with a particular message key.
Actually, Tupteq
's answer is not correct in general. The following script:
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')
When run, produces the following output:
$ python filtcfg.py 2.7.5+ (default, Sep 19 2013, 13:48:49) [GCC 4.8.1] changed: hello
which shows that you can configure filters using dictConfig()
.
You can specify a class name, but it is done with the strangely named ()
key, and it has to include the module name. E.g.:
'filters': { 'errorfilter': { '()' : '__main__.LoggingErrorFilter', } },
See 16.7.2.4. User-defined objects in the documentation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With