Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a92fbe6

Browse files
committed
Issue #18541: simplified LoggerAdapter example.
1 parent 7d28b6b commit a92fbe6

1 file changed

Lines changed: 19 additions & 57 deletions

File tree

Doc/howto/logging-cookbook.rst

Lines changed: 19 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -524,69 +524,31 @@ customized strings with your :class:`Formatter` instances which know about
524524
the keys of the dict-like object. If you need a different method, e.g. if you
525525
want to prepend or append the contextual information to the message string,
526526
you 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

Comments
 (0)