Issue #18759: Improved cross-references in logging documentation.
This commit is contained in:
parent
88b174c977
commit
10b513098a
|
@ -97,11 +97,11 @@ The output looks like this::
|
|||
Multiple handlers and formatters
|
||||
--------------------------------
|
||||
|
||||
Loggers are plain Python objects. The :func:`addHandler` method has no minimum
|
||||
or maximum quota for the number of handlers you may add. Sometimes it will be
|
||||
beneficial for an application to log all messages of all severities to a text
|
||||
file while simultaneously logging errors or above to the console. To set this
|
||||
up, simply configure the appropriate handlers. The logging calls in the
|
||||
Loggers are plain Python objects. The :meth:`~Logger.addHandler` method has no
|
||||
minimum or maximum quota for the number of handlers you may add. Sometimes it
|
||||
will be beneficial for an application to log all messages of all severities to a
|
||||
text file while simultaneously logging errors or above to the console. To set
|
||||
this up, simply configure the appropriate handlers. The logging calls in the
|
||||
application code will remain unchanged. Here is a slight modification to the
|
||||
previous simple module-based configuration example::
|
||||
|
||||
|
@ -395,8 +395,9 @@ printed on the console; on the server side, you should see something like::
|
|||
|
||||
Note that there are some security issues with pickle in some scenarios. If
|
||||
these affect you, you can use an alternative serialization scheme by overriding
|
||||
the :meth:`makePickle` method and implementing your alternative there, as
|
||||
well as adapting the above script to use your alternative serialization.
|
||||
the :meth:`~handlers.SocketHandler.makePickle` method and implementing your
|
||||
alternative there, as well as adapting the above script to use your alternative
|
||||
serialization.
|
||||
|
||||
|
||||
.. _context-info:
|
||||
|
@ -404,6 +405,8 @@ well as adapting the above script to use your alternative serialization.
|
|||
Adding contextual information to your logging output
|
||||
----------------------------------------------------
|
||||
|
||||
.. currentmodule:: logging
|
||||
|
||||
Sometimes you want logging output to contain contextual information in
|
||||
addition to the parameters passed to the logging call. For example, in a
|
||||
networked application, it may be desirable to log client-specific information
|
||||
|
@ -445,9 +448,9 @@ information in the delegated call. Here's a snippet from the code of
|
|||
msg, kwargs = self.process(msg, kwargs)
|
||||
self.logger.debug(msg, *args, **kwargs)
|
||||
|
||||
The :meth:`process` method of :class:`LoggerAdapter` is where the contextual
|
||||
information is added to the logging output. It's passed the message and
|
||||
keyword arguments of the logging call, and it passes back (potentially)
|
||||
The :meth:`~LoggerAdapter.process` method of :class:`LoggerAdapter` is where the
|
||||
contextual information is added to the logging output. It's passed the message
|
||||
and keyword arguments of the logging call, and it passes back (potentially)
|
||||
modified versions of these to use in the call to the underlying logger. The
|
||||
default implementation of this method leaves the message alone, but inserts
|
||||
an 'extra' key in the keyword argument whose value is the dict-like object
|
||||
|
@ -459,8 +462,8 @@ merged into the :class:`LogRecord` instance's __dict__, allowing you to use
|
|||
customized strings with your :class:`Formatter` instances which know about
|
||||
the keys of the dict-like object. If you need a different method, e.g. if you
|
||||
want to prepend or append the contextual information to the message string,
|
||||
you just need to subclass :class:`LoggerAdapter` and override :meth:`process`
|
||||
to do what you need. Here is a simple example::
|
||||
you just need to subclass :class:`LoggerAdapter` and override
|
||||
:meth:`~LoggerAdapter.process` to do what you need. Here is a simple example::
|
||||
|
||||
class CustomAdapter(logging.LoggerAdapter):
|
||||
"""
|
||||
|
@ -569,25 +572,23 @@ threads in a single process *is* supported, logging to a single file from
|
|||
*multiple processes* is *not* supported, because there is no standard way to
|
||||
serialize access to a single file across multiple processes in Python. If you
|
||||
need to log to a single file from multiple processes, one way of doing this is
|
||||
to have all the processes log to a :class:`SocketHandler`, and have a separate
|
||||
process which implements a socket server which reads from the socket and logs
|
||||
to file. (If you prefer, you can dedicate one thread in one of the existing
|
||||
processes to perform this function.) :ref:`This section <network-logging>`
|
||||
documents this approach in more detail and includes a working socket receiver
|
||||
which can be used as a starting point for you to adapt in your own
|
||||
applications.
|
||||
to have all the processes log to a :class:`~handlers.SocketHandler`, and have a
|
||||
separate process which implements a socket server which reads from the socket
|
||||
and logs to file. (If you prefer, you can dedicate one thread in one of the
|
||||
existing processes to perform this function.)
|
||||
:ref:`This section <network-logging>` documents this approach in more detail and
|
||||
includes a working socket receiver which can be used as a starting point for you
|
||||
to adapt in your own applications.
|
||||
|
||||
If you are using a recent version of Python which includes the
|
||||
:mod:`multiprocessing` module, you could write your own handler which uses the
|
||||
:class:`Lock` class from this module to serialize access to the file from
|
||||
your processes. The existing :class:`FileHandler` and subclasses do not make
|
||||
use of :mod:`multiprocessing` at present, though they may do so in the future.
|
||||
Note that at present, the :mod:`multiprocessing` module does not provide
|
||||
:class:`~multiprocessing.Lock` class from this module to serialize access to the
|
||||
file from your processes. The existing :class:`FileHandler` and subclasses do
|
||||
not make use of :mod:`multiprocessing` at present, though they may do so in the
|
||||
future. Note that at present, the :mod:`multiprocessing` module does not provide
|
||||
working lock functionality on all platforms (see
|
||||
http://bugs.python.org/issue3770).
|
||||
|
||||
.. currentmodule:: logging.handlers
|
||||
|
||||
|
||||
Using file rotation
|
||||
-------------------
|
||||
|
@ -599,7 +600,7 @@ Sometimes you want to let a log file grow to a certain size, then open a new
|
|||
file and log to that. You may want to keep a certain number of these files, and
|
||||
when that many files have been created, rotate the files so that the number of
|
||||
files and the size of the files both remain bounded. For this usage pattern, the
|
||||
logging package provides a :class:`RotatingFileHandler`::
|
||||
logging package provides a :class:`~handlers.RotatingFileHandler`::
|
||||
|
||||
import glob
|
||||
import logging
|
||||
|
@ -650,7 +651,7 @@ An example dictionary-based configuration
|
|||
|
||||
Below is an example of a logging configuration dictionary - it's taken from
|
||||
the `documentation on the Django project <https://docs.djangoproject.com/en/1.3/topics/logging/#configuring-logging>`_.
|
||||
This dictionary is passed to :func:`~logging.config.dictConfig` to put the configuration into effect::
|
||||
This dictionary is passed to :func:`~config.dictConfig` to put the configuration into effect::
|
||||
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
|
|
|
@ -469,12 +469,13 @@ Handlers
|
|||
|
||||
:class:`~logging.Handler` objects are responsible for dispatching the
|
||||
appropriate log messages (based on the log messages' severity) to the handler's
|
||||
specified destination. Logger objects can add zero or more handler objects to
|
||||
themselves with an :func:`addHandler` method. As an example scenario, an
|
||||
application may want to send all log messages to a log file, all log messages
|
||||
of error or higher to stdout, and all messages of critical to an email address.
|
||||
This scenario requires three individual handlers where each handler is
|
||||
responsible for sending messages of a specific severity to a specific location.
|
||||
specified destination. :class:`Logger` objects can add zero or more handler
|
||||
objects to themselves with an :meth:`~Logger.addHandler` method. As an example
|
||||
scenario, an application may want to send all log messages to a log file, all
|
||||
log messages of error or higher to stdout, and all messages of critical to an
|
||||
email address. This scenario requires three individual handlers where each
|
||||
handler is responsible for sending messages of a specific severity to a specific
|
||||
location.
|
||||
|
||||
The standard library includes quite a few handler types (see
|
||||
:ref:`useful-handlers`); the tutorials use mainly :class:`StreamHandler` and
|
||||
|
@ -485,16 +486,17 @@ themselves with. The only handler methods that seem relevant for application
|
|||
developers who are using the built-in handler objects (that is, not creating
|
||||
custom handlers) are the following configuration methods:
|
||||
|
||||
* The :meth:`Handler.setLevel` method, just as in logger objects, specifies the
|
||||
* The :meth:`~Handler.setLevel` method, just as in logger objects, specifies the
|
||||
lowest severity that will be dispatched to the appropriate destination. Why
|
||||
are there two :func:`setLevel` methods? The level set in the logger
|
||||
determines which severity of messages it will pass to its handlers. The level
|
||||
set in each handler determines which messages that handler will send on.
|
||||
|
||||
* :func:`setFormatter` selects a Formatter object for this handler to use.
|
||||
* :meth:`~Handler.setFormatter` selects a Formatter object for this handler to
|
||||
use.
|
||||
|
||||
* :func:`addFilter` and :func:`removeFilter` respectively configure and
|
||||
deconfigure filter objects on handlers.
|
||||
* :meth:`~Handler.addFilter` and :meth:`~Handler.removeFilter` respectively
|
||||
configure and deconfigure filter objects on handlers.
|
||||
|
||||
Application code should not directly instantiate and use instances of
|
||||
:class:`Handler`. Instead, the :class:`Handler` class is a base class that
|
||||
|
@ -918,16 +920,16 @@ Logged messages are formatted for presentation through instances of the
|
|||
use with the % operator and a dictionary.
|
||||
|
||||
For formatting multiple messages in a batch, instances of
|
||||
:class:`BufferingFormatter` can be used. In addition to the format string (which
|
||||
is applied to each message in the batch), there is provision for header and
|
||||
trailer format strings.
|
||||
:class:`~handlers.BufferingFormatter` can be used. In addition to the format
|
||||
string (which is applied to each message in the batch), there is provision for
|
||||
header and trailer format strings.
|
||||
|
||||
When filtering based on logger level and/or handler level is not enough,
|
||||
instances of :class:`Filter` can be added to both :class:`Logger` and
|
||||
:class:`Handler` instances (through their :meth:`addFilter` method). Before
|
||||
deciding to process a message further, both loggers and handlers consult all
|
||||
their filters for permission. If any filter returns a false value, the message
|
||||
is not processed further.
|
||||
:class:`Handler` instances (through their :meth:`~Handler.addFilter` method).
|
||||
Before deciding to process a message further, both loggers and handlers consult
|
||||
all their filters for permission. If any filter returns a false value, the
|
||||
message is not processed further.
|
||||
|
||||
The basic :class:`Filter` functionality allows filtering by specific logger
|
||||
name. If this feature is used, messages sent to the named logger and its
|
||||
|
@ -945,19 +947,20 @@ in production. This is so that errors which occur while handling logging events
|
|||
cause the application using logging to terminate prematurely.
|
||||
|
||||
:class:`SystemExit` and :class:`KeyboardInterrupt` exceptions are never
|
||||
swallowed. Other exceptions which occur during the :meth:`emit` method of a
|
||||
:class:`Handler` subclass are passed to its :meth:`handleError` method.
|
||||
swallowed. Other exceptions which occur during the :meth:`~Handler.emit` method
|
||||
of a :class:`Handler` subclass are passed to its :meth:`~Handler.handleError`
|
||||
method.
|
||||
|
||||
The default implementation of :meth:`handleError` in :class:`Handler` checks
|
||||
to see if a module-level variable, :data:`raiseExceptions`, is set. If set, a
|
||||
traceback is printed to :data:`sys.stderr`. If not set, the exception is swallowed.
|
||||
The default implementation of :meth:`~Handler.handleError` in :class:`Handler`
|
||||
checks to see if a module-level variable, :data:`raiseExceptions`, is set. If
|
||||
set, a traceback is printed to :data:`sys.stderr`. If not set, the exception is
|
||||
swallowed.
|
||||
|
||||
.. note:: The default value of :data:`raiseExceptions` is ``True``. This is
|
||||
because during development, you typically want to be notified of any
|
||||
exceptions that occur. It's advised that you set :data:`raiseExceptions` to
|
||||
``False`` for production usage.
|
||||
|
||||
.. currentmodule:: logging
|
||||
|
||||
.. _arbitrary-object-messages:
|
||||
|
||||
|
@ -967,11 +970,11 @@ Using arbitrary objects as messages
|
|||
In the preceding sections and examples, it has been assumed that the message
|
||||
passed when logging the event is a string. However, this is not the only
|
||||
possibility. You can pass an arbitrary object as a message, and its
|
||||
:meth:`__str__` method will be called when the logging system needs to convert
|
||||
it to a string representation. In fact, if you want to, you can avoid
|
||||
:meth:`~object.__str__` method will be called when the logging system needs to
|
||||
convert it to a string representation. In fact, if you want to, you can avoid
|
||||
computing a string representation altogether - for example, the
|
||||
:class:`SocketHandler` emits an event by pickling it and sending it over the
|
||||
wire.
|
||||
:class:`~handlers.SocketHandler` emits an event by pickling it and sending it
|
||||
over the wire.
|
||||
|
||||
|
||||
Optimization
|
||||
|
@ -980,9 +983,10 @@ Optimization
|
|||
Formatting of message arguments is deferred until it cannot be avoided.
|
||||
However, computing the arguments passed to the logging method can also be
|
||||
expensive, and you may want to avoid doing it if the logger will just throw
|
||||
away your event. To decide what to do, you can call the :meth:`isEnabledFor`
|
||||
method which takes a level argument and returns true if the event would be
|
||||
created by the Logger for that level of call. You can write code like this::
|
||||
away your event. To decide what to do, you can call the
|
||||
:meth:`~Logger.isEnabledFor` method which takes a level argument and returns
|
||||
true if the event would be created by the Logger for that level of call.
|
||||
You can write code like this::
|
||||
|
||||
if logger.isEnabledFor(logging.DEBUG):
|
||||
logger.debug('Message with %s, %s', expensive_func1(),
|
||||
|
|
|
@ -104,8 +104,9 @@ in :mod:`logging` itself) and defining handlers which are declared either in
|
|||
configurations. If no port is specified, the module's default
|
||||
:const:`DEFAULT_LOGGING_CONFIG_PORT` is used. Logging configurations will be
|
||||
sent as a file suitable for processing by :func:`fileConfig`. Returns a
|
||||
:class:`Thread` instance on which you can call :meth:`start` to start the
|
||||
server, and which you can :meth:`join` when appropriate. To stop the server,
|
||||
:class:`~threading.Thread` instance on which you can call
|
||||
:meth:`~threading.Thread.start` to start the server, and which you can
|
||||
:meth:`~threading.Thread.join` when appropriate. To stop the server,
|
||||
call :func:`stopListening`.
|
||||
|
||||
To send a configuration to the socket, read in the configuration file and
|
||||
|
@ -169,11 +170,11 @@ otherwise, the context is used to determine what to instantiate.
|
|||
|
||||
* *formatters* - the corresponding value will be a dict in which each
|
||||
key is a formatter id and each value is a dict describing how to
|
||||
configure the corresponding Formatter instance.
|
||||
configure the corresponding :class:`~logging.Formatter` instance.
|
||||
|
||||
The configuring dict is searched for keys ``format`` and ``datefmt``
|
||||
(with defaults of ``None``) and these are used to construct a
|
||||
:class:`logging.Formatter` instance.
|
||||
:class:`~logging.Formatter` instance.
|
||||
|
||||
* *filters* - the corresponding value will be a dict in which each key
|
||||
is a filter id and each value is a dict describing how to configure
|
||||
|
@ -711,8 +712,9 @@ format string, with a comma separator. An example time in ISO8601 format is
|
|||
|
||||
The ``class`` entry is optional. It indicates the name of the formatter's class
|
||||
(as a dotted module and class name.) This option is useful for instantiating a
|
||||
:class:`Formatter` subclass. Subclasses of :class:`Formatter` can present
|
||||
exception tracebacks in an expanded or condensed format.
|
||||
:class:`~logging.Formatter` subclass. Subclasses of
|
||||
:class:`~logging.Formatter` can present exception tracebacks in an expanded or
|
||||
condensed format.
|
||||
|
||||
.. note:: Due to the use of :func:`eval` as described above, there are
|
||||
potential security risks which result from using the :func:`listen` to send
|
||||
|
|
|
@ -53,8 +53,8 @@ and :meth:`flush` methods).
|
|||
.. method:: flush()
|
||||
|
||||
Flushes the stream by calling its :meth:`flush` method. Note that the
|
||||
:meth:`close` method is inherited from :class:`Handler` and so does
|
||||
no output, so an explicit :meth:`flush` call may be needed at times.
|
||||
:meth:`close` method is inherited from :class:`~logging.Handler` and so
|
||||
does no output, so an explicit :meth:`flush` call may be needed at times.
|
||||
|
||||
.. _file-handler:
|
||||
|
||||
|
@ -142,8 +142,8 @@ new stream.
|
|||
This handler is not appropriate for use under Windows, because under Windows
|
||||
open log files cannot be moved or renamed - logging opens the files with
|
||||
exclusive locks - and so there is no need for such a handler. Furthermore,
|
||||
*ST_INO* is not supported under Windows; :func:`stat` always returns zero for
|
||||
this value.
|
||||
*ST_INO* is not supported under Windows; :func:`~os.stat` always returns zero
|
||||
for this value.
|
||||
|
||||
|
||||
.. class:: WatchedFileHandler(filename[,mode[, encoding[, delay]]])
|
||||
|
@ -305,7 +305,8 @@ sends logging output to a network socket. The base class uses a TCP socket.
|
|||
binary format. If there is an error with the socket, silently drops the
|
||||
packet. If the connection was previously lost, re-establishes the
|
||||
connection. To unpickle the record at the receiving end into a
|
||||
:class:`LogRecord`, use the :func:`makeLogRecord` function.
|
||||
:class:`~logging.LogRecord`, use the :func:`~logging.makeLogRecord`
|
||||
function.
|
||||
|
||||
|
||||
.. method:: handleError()
|
||||
|
@ -383,7 +384,8 @@ over UDP sockets.
|
|||
Pickles the record's attribute dictionary and writes it to the socket in
|
||||
binary format. If there is an error with the socket, silently drops the
|
||||
packet. To unpickle the record at the receiving end into a
|
||||
:class:`LogRecord`, use the :func:`makeLogRecord` function.
|
||||
:class:`~logging.LogRecord`, use the :func:`~logging.makeLogRecord`
|
||||
function.
|
||||
|
||||
|
||||
.. method:: makeSocket()
|
||||
|
|
Loading…
Reference in New Issue