Skip to content

Commit 554f22f

Browse files
committed
Added cookbook entry on logging filter configuration using dictConfig().
1 parent 57839a6 commit 554f22f

File tree

1 file changed

+87
-0
lines changed

1 file changed

+87
-0
lines changed

Doc/howto/logging-cookbook.rst

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,6 +1694,9 @@ When the above script is run, it prints::
16941694
Note that the order of items might be different according to the version of
16951695
Python used.
16961696

1697+
1698+
.. _custom-handlers:
1699+
16971700
.. currentmodule:: logging.config
16981701

16991702
Customizing handlers with :func:`dictConfig`
@@ -1948,3 +1951,87 @@ handler. So the only slightly unusual thing which might trip you up is that the
19481951
parentheses go around the format string and the arguments, not just the format
19491952
string. That’s because the __ notation is just syntax sugar for a constructor
19501953
call to one of the ``XXXMessage`` classes shown above.
1954+
1955+
1956+
.. _filters-dictconfig:
1957+
1958+
.. currentmodule:: logging.config
1959+
1960+
Configuring filters with :func:`dictConfig`
1961+
-------------------------------------------
1962+
1963+
You *can* configure filters using :func:`~logging.config.dictConfig`, though it
1964+
might not be obvious at first glance how to do it (hence this recipe). Since
1965+
:class:`~logging.Filter` is the only filter class included in the standard
1966+
library, and it is unlikely to cater to many requirements (it's only there as a
1967+
base class), you will typically need to define your own :class:`~logging.Filter`
1968+
subclass with an overridden :meth:`~logging.Filter.filter` method. To do this,
1969+
specify the ``()`` key in the configuration dictionary for the filter,
1970+
specifying a callable which will be used to create the filter (a class is the
1971+
most obvious, but you can provide any callable which returns a
1972+
:class:`~logging.Filter` instance). Here is a complete example::
1973+
1974+
import logging
1975+
import logging.config
1976+
import sys
1977+
1978+
class MyFilter(logging.Filter):
1979+
def __init__(self, param=None):
1980+
self.param = param
1981+
1982+
def filter(self, record):
1983+
if self.param is None:
1984+
allow = True
1985+
else:
1986+
allow = self.param not in record.msg
1987+
if allow:
1988+
record.msg = 'changed: ' + record.msg
1989+
return allow
1990+
1991+
LOGGING = {
1992+
'version': 1,
1993+
'filters': {
1994+
'myfilter': {
1995+
'()': MyFilter,
1996+
'param': 'noshow',
1997+
}
1998+
},
1999+
'handlers': {
2000+
'console': {
2001+
'class': 'logging.StreamHandler',
2002+
'filters': ['myfilter']
2003+
}
2004+
},
2005+
'root': {
2006+
'level': 'DEBUG',
2007+
'handlers': ['console']
2008+
},
2009+
}
2010+
2011+
if __name__ == '__main__':
2012+
logging.config.dictConfig(LOGGING)
2013+
logging.debug('hello')
2014+
logging.debug('hello - noshow')
2015+
2016+
This example shows how you can pass configuration data to the callable which
2017+
constructs the instance, in the form of keyword parameters. When run, the above
2018+
script will print::
2019+
2020+
changed: hello
2021+
2022+
which shows that the filter is working as configured.
2023+
2024+
A couple of extra points to note:
2025+
2026+
* If you can't refer to the callable directly in the configuration (e.g. if it
2027+
lives in a different module, and you can't import it directly where the
2028+
configuration dictionary is), you can use the form ``ext://...`` as described
2029+
in :ref:`logging-config-dict-externalobj`. For example, you could have used
2030+
the text ``'ext://__main__.MyFilter'`` instead of ``MyFilter`` in the above
2031+
example.
2032+
2033+
* As well as for filters, this technique can also be used to configure custom
2034+
handlers and formatters. See :ref:`logging-config-dict-userdef` for more
2035+
information on how logging supports using user-defined objects in its
2036+
configuration, and see the other cookbook recipe :ref:`custom-handlers` above.
2037+

0 commit comments

Comments
 (0)