8.2 Using Filters to impart contextual information You can also add contextual information to log output using a user-defined$_{Filter}$ .$_{Filter}$ instances are allowed to modify the$_{LogRecords}$ passed to them, including adding additional attributes which can then be output using a suitable format string, or if needed a custom Formatter . For example in a web application, the request being processed (or at least, the interesting parts of it) can be stored in a threadlocal ( threading.local ) variable, and then accessed from a Filter to add, say, information from the request - say, the remote IP address and remote user’s username - to the LogRecord , using the attribute names ‘ip’ and ‘user’ as in the LoggerAdapter example above. In that case, the same format string can be used to get similar output to that shown above. Here’s an example script: which, when run, produces something like: (continues on next page) 12 import logging from random import choice classContextFilter (logging .Filter): """ This is a filter which injects contextual information into the log. Rather than use actual contextual information, we just use random data in this demo. """ USERS =['jim','fred','sheila'] IPS =['123.231.231.123 ','127.0.0.1 ','192.168.0.1 '] def filter(self, record): record.ip =choice(ContextFilter.IPS) record.user =choice(ContextFilter.USERS) return True if __name__ =='__main__ ': levels=(logging .DEBUG, logging .INFO, logging.WARNING, logging .ERROR, logging . ↪ → CRITICAL) logging.basicConfig(level =logging.DEBUG, format=' %(asctime)-15s %(name)-5s %(levelname)-8s IP: ↪ → %(ip)-15s User: %(user)-8s %(message)s ') a1=logging.getLogger('a.b.c ') a2=logging.getLogger('d.e.f ') f =ContextFilter() a1.addFilter(f) a2.addFilter(f) a1.debug( 'A debug message') a1.info('An info message with %s ','some parameters') for x in range(10 ): lvl=choice(levels) lvlname=logging.getLevelName(lvl) a2.log(lvl, 'A message at %s level with %d%s ', lvlname, 2,'parameters') 2010-09-06 22:38:15,292 a.b.c DEBUG IP: 123.231.231.123 A debug␣ ↪ → message 2010-09-06 22:38:15,300 a.b.c INFO IP: 192.168.0.1 User: sheila An info␣ ↪ → message with some parameters 2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 127.0.0.1 User: sheila A␣ ↪ → message at CRITICAL level with 2 parameters 2010-09-06 22:38:15,300 d.e.f ERROR IP: 127.0.0.1 User: jim A␣ ↪ → message at ERROR level with 2 parameters 2010-09-06 22:38:15,300 d.e.f DEBUG IP: 127.0.0.1 User: sheila A␣ ↪ → message at DEBUG level with 2 parameters