mirror of https://github.com/python/cpython
Updated information on logging contextual information.
This commit is contained in:
parent
9a0cb6a8d0
commit
957a47cd6f
|
@ -1335,6 +1335,10 @@ level of granularity you want to use in logging an application, it could
|
|||
be hard to manage if the number of :class:`Logger` instances becomes
|
||||
effectively unbounded.
|
||||
|
||||
|
||||
Using LoggerAdapters to impart contextual information
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
An easy way in which you can pass contextual information to be output along
|
||||
with logging event information is to use the :class:`LoggerAdapter` class.
|
||||
This class is designed to look like a :class:`Logger`, so that you can call
|
||||
|
@ -1442,6 +1446,78 @@ When this script is run, the output should look something like this::
|
|||
|
||||
The :class:`LoggerAdapter` class was not present in previous versions.
|
||||
|
||||
Using Filters to impart contextual information
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can also add contextual information to log output using a user-defined
|
||||
:class:`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 :class:`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
|
||||
(:class:`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::
|
||||
|
||||
import logging
|
||||
from random import choice
|
||||
|
||||
class ContextFilter(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)
|
||||
a1 = logging.LoggerAdapter(logging.getLogger("a.b.c"),
|
||||
{ "ip" : "123.231.231.123", "user" : "sheila" })
|
||||
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")
|
||||
|
||||
which, when run, produces something like::
|
||||
|
||||
2010-09-06 22:38:15,292 a.b.c DEBUG IP: 123.231.231.123 User: fred 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
|
||||
2010-09-06 22:38:15,300 d.e.f ERROR IP: 123.231.231.123 User: fred A message at ERROR level with 2 parameters
|
||||
2010-09-06 22:38:15,300 d.e.f CRITICAL IP: 192.168.0.1 User: jim A message at CRITICAL level with 2 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 DEBUG IP: 192.168.0.1 User: jim A message at DEBUG level with 2 parameters
|
||||
2010-09-06 22:38:15,301 d.e.f ERROR IP: 127.0.0.1 User: sheila A message at ERROR level with 2 parameters
|
||||
2010-09-06 22:38:15,301 d.e.f DEBUG IP: 123.231.231.123 User: fred A message at DEBUG level with 2 parameters
|
||||
2010-09-06 22:38:15,301 d.e.f INFO IP: 123.231.231.123 User: fred A message at INFO level with 2 parameters
|
||||
|
||||
|
||||
.. _multiple-processes:
|
||||
|
||||
Logging to a single file from multiple processes
|
||||
|
|
Loading…
Reference in New Issue