@@ -524,69 +524,31 @@ customized strings with your :class:`Formatter` instances which know about
524524the keys of the dict-like object. If you need a different method, e.g. if you
525525want to prepend or append the contextual information to the message string,
526526you just need to subclass :class: `LoggerAdapter ` and override :meth: `process `
527- to do what you need. Here's an example script which uses this class, which
528- also illustrates what dict-like behaviour is needed from an arbitrary
529- 'dict-like' object for use in the constructor::
527+ to do what you need. Here is a simple example::
530528
531- import logging
529+ class CustomAdapter(logging.LoggerAdapter):
530+ """
531+ This example adapter expects the passed in dict-like object to have a
532+ 'connid' key, whose value in brackets is prepended to the log message.
533+ """
534+ def process(self, msg, kwargs):
535+ return '[%s] %s' % (self.extra['connid'], msg), kwargs
532536
533- class ConnInfo:
534- """
535- An example class which shows how an arbitrary class can be used as
536- the 'extra' context information repository passed to a LoggerAdapter.
537- """
537+ which you can use like this::
538538
539- def __getitem__(self, name):
540- """
541- To allow this instance to look like a dict.
542- """
543- from random import choice
544- if name == 'ip':
545- result = choice(['127.0.0.1', '192.168.0.1'])
546- elif name == 'user':
547- result = choice(['jim', 'fred', 'sheila'])
548- else:
549- result = self.__dict__.get(name, '?')
550- return result
539+ logger = logging.getLogger(__name__)
540+ adapter = CustomAdapter(logger, {'connid': some_conn_id})
551541
552- def __iter__(self):
553- """
554- To allow iteration over keys, which will be merged into
555- the LogRecord dict before formatting and output.
556- """
557- keys = ['ip', 'user']
558- keys.extend(self.__dict__.keys())
559- return keys.__iter__()
542+ Then any events that you log to the adapter will have the value of
543+ ``some_conn_id `` prepended to the log messages.
560544
561- if __name__ == '__main__':
562- from random import choice
563- levels = (logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL)
564- a1 = logging.LoggerAdapter(logging.getLogger('a.b.c'),
565- { 'ip' : '123.231.231.123', 'user' : 'sheila' })
566- logging.basicConfig(level=logging.DEBUG,
567- format='%(asctime)-15s %(name)-5s %(levelname)-8s IP: %(ip)-15s User: %(user)-8s %(message)s')
568- a1.debug('A debug message')
569- a1.info('An info message with %s', 'some parameters')
570- a2 = logging.LoggerAdapter(logging.getLogger('d.e.f'), ConnInfo())
571- for x in range(10):
572- lvl = choice(levels)
573- lvlname = logging.getLevelName(lvl)
574- a2.log(lvl, 'A message at %s level with %d %s', lvlname, 2, 'parameters')
545+ Using objects other than dicts to pass contextual information
546+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
575547
576- When this script is run, the output should look something like this::
577-
578- 2008-01-18 14:49:54,023 a.b.c DEBUG IP: 123.231.231.123 User: sheila A debug message
579- 2008-01-18 14:49:54,023 a.b.c INFO IP: 123.231.231.123 User: sheila An info message with some parameters
580- 2008-01-18 14:49:54,023 d.e.f CRITICAL IP: 192.168.0.1 User: jim A message at CRITICAL level with 2 parameters
581- 2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: jim A message at INFO level with 2 parameters
582- 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters
583- 2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: fred A message at ERROR level with 2 parameters
584- 2008-01-18 14:49:54,033 d.e.f ERROR IP: 127.0.0.1 User: sheila A message at ERROR level with 2 parameters
585- 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters
586- 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: jim A message at WARNING level with 2 parameters
587- 2008-01-18 14:49:54,033 d.e.f INFO IP: 192.168.0.1 User: fred A message at INFO level with 2 parameters
588- 2008-01-18 14:49:54,033 d.e.f WARNING IP: 192.168.0.1 User: sheila A message at WARNING level with 2 parameters
589- 2008-01-18 14:49:54,033 d.e.f WARNING IP: 127.0.0.1 User: jim A message at WARNING level with 2 parameters
548+ You don't need to pass an actual dict to a :class: `LoggerAdapter ` - you could
549+ pass an instance of a class which implements ``__getitem__ `` and ``__iter__ `` so
550+ that it looks like a dict to logging. This would be useful if you want to
551+ generate values dynamically (whereas the values in a dict would be constant).
590552
591553
592554.. _filters-contextual :
0 commit comments