Added cookbook entry on logging filter configuration using dictConfig().

This commit is contained in:
Vinay Sajip 2014-02-03 11:51:45 +00:00
parent 57839a6349
commit 554f22ff1d
1 changed files with 87 additions and 0 deletions

View File

@ -1694,6 +1694,9 @@ When the above script is run, it prints::
Note that the order of items might be different according to the version of
Python used.
.. _custom-handlers:
.. currentmodule:: logging.config
Customizing handlers with :func:`dictConfig`
@ -1948,3 +1951,87 @@ handler. So the only slightly unusual thing which might trip you up is that the
parentheses go around the format string and the arguments, not just the format
string. Thats because the __ notation is just syntax sugar for a constructor
call to one of the ``XXXMessage`` classes shown above.
.. _filters-dictconfig:
.. currentmodule:: logging.config
Configuring filters with :func:`dictConfig`
-------------------------------------------
You *can* configure filters using :func:`~logging.config.dictConfig`, though it
might not be obvious at first glance how to do it (hence this recipe). Since
:class:`~logging.Filter` is the only filter class included in the standard
library, and it is unlikely to cater to many requirements (it's only there as a
base class), you will typically need to define your own :class:`~logging.Filter`
subclass with an overridden :meth:`~logging.Filter.filter` method. To do this,
specify the ``()`` key in the configuration dictionary for the filter,
specifying a callable which will be used to create the filter (a class is the
most obvious, but you can provide any callable which returns a
:class:`~logging.Filter` instance). Here is a complete example::
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__':
logging.config.dictConfig(LOGGING)
logging.debug('hello')
logging.debug('hello - noshow')
This example shows how you can pass configuration data to the callable which
constructs the instance, in the form of keyword parameters. When run, the above
script will print::
changed: hello
which shows that the filter is working as configured.
A couple of extra points to note:
* If you can't refer to the callable directly in the configuration (e.g. if it
lives in a different module, and you can't import it directly where the
configuration dictionary is), you can use the form ``ext://...`` as described
in :ref:`logging-config-dict-externalobj`. For example, you could have used
the text ``'ext://__main__.MyFilter'`` instead of ``MyFilter`` in the above
example.
* As well as for filters, this technique can also be used to configure custom
handlers and formatters. See :ref:`logging-config-dict-userdef` for more
information on how logging supports using user-defined objects in its
configuration, and see the other cookbook recipe :ref:`custom-handlers` above.