mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	Added cookbook entry on logging filter configuration using dictConfig().
This commit is contained in:
		
							parent
							
								
									57839a6349
								
							
						
					
					
						commit
						554f22ff1d
					
				
					 1 changed files with 87 additions and 0 deletions
				
			
		| 
						 | 
					@ -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
 | 
					Note that the order of items might be different according to the version of
 | 
				
			||||||
Python used.
 | 
					Python used.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. _custom-handlers:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. currentmodule:: logging.config
 | 
					.. currentmodule:: logging.config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Customizing handlers with :func:`dictConfig`
 | 
					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
 | 
					parentheses go around the format string and the arguments, not just the format
 | 
				
			||||||
string. That’s because the __ notation is just syntax sugar for a constructor
 | 
					string. That’s because the __ notation is just syntax sugar for a constructor
 | 
				
			||||||
call to one of the ``XXXMessage`` classes shown above.
 | 
					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.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue