mirror of https://github.com/python/cpython
1505 lines
59 KiB
TeX
1505 lines
59 KiB
TeX
\section{\module{logging} ---
|
|
Logging facility for Python}
|
|
|
|
\declaremodule{standard}{logging}
|
|
|
|
% These apply to all modules, and may be given more than once:
|
|
|
|
\moduleauthor{Vinay Sajip}{vinay_sajip@red-dove.com}
|
|
\sectionauthor{Vinay Sajip}{vinay_sajip@red-dove.com}
|
|
|
|
\modulesynopsis{Logging module for Python based on \pep{282}.}
|
|
|
|
\indexii{Errors}{logging}
|
|
|
|
\versionadded{2.3}
|
|
This module defines functions and classes which implement a flexible
|
|
error logging system for applications.
|
|
|
|
Logging is performed by calling methods on instances of the
|
|
\class{Logger} class (hereafter called \dfn{loggers}). Each instance has a
|
|
name, and they are conceptually arranged in a name space hierarchy
|
|
using dots (periods) as separators. For example, a logger named
|
|
"scan" is the parent of loggers "scan.text", "scan.html" and "scan.pdf".
|
|
Logger names can be anything you want, and indicate the area of an
|
|
application in which a logged message originates.
|
|
|
|
Logged messages also have levels of importance associated with them.
|
|
The default levels provided are \constant{DEBUG}, \constant{INFO},
|
|
\constant{WARNING}, \constant{ERROR} and \constant{CRITICAL}. As a
|
|
convenience, you indicate the importance of a logged message by calling
|
|
an appropriate method of \class{Logger}. The methods are
|
|
\method{debug()}, \method{info()}, \method{warning()}, \method{error()} and
|
|
\method{critical()}, which mirror the default levels. You are not
|
|
constrained to use these levels: you can specify your own and use a
|
|
more general \class{Logger} method, \method{log()}, which takes an
|
|
explicit level argument.
|
|
|
|
Levels can also be associated with loggers, being set either by the
|
|
developer or through loading a saved logging configuration. When a
|
|
logging method is called on a logger, the logger compares its own
|
|
level with the level associated with the method call. If the logger's
|
|
level is higher than the method call's, no logging message is actually
|
|
generated. This is the basic mechanism controlling the verbosity of
|
|
logging output.
|
|
|
|
Logging messages are encoded as instances of the \class{LogRecord} class.
|
|
When a logger decides to actually log an event, an \class{LogRecord}
|
|
instance is created from the logging message.
|
|
|
|
Logging messages are subjected to a dispatch mechanism through the
|
|
use of \dfn{handlers}, which are instances of subclasses of the
|
|
\class{Handler} class. Handlers are responsible for ensuring that a logged
|
|
message (in the form of a \class{LogRecord}) ends up in a particular
|
|
location (or set of locations) which is useful for the target audience for
|
|
that message (such as end users, support desk staff, system administrators,
|
|
developers). Handlers are passed \class{LogRecord} instances intended for
|
|
particular destinations. Each logger can have zero, one or more handlers
|
|
associated with it (via the \method{addHandler()} method of \class{Logger}).
|
|
In addition to any handlers directly associated with a logger,
|
|
\emph{all handlers associated with all ancestors of the logger} are
|
|
called to dispatch the message.
|
|
|
|
Just as for loggers, handlers can have levels associated with them.
|
|
A handler's level acts as a filter in the same way as a logger's level does.
|
|
If a handler decides to actually dispatch an event, the \method{emit()} method
|
|
is used to send the message to its destination. Most user-defined subclasses
|
|
of \class{Handler} will need to override this \method{emit()}.
|
|
|
|
In addition to the base \class{Handler} class, many useful subclasses
|
|
are provided:
|
|
|
|
\begin{enumerate}
|
|
|
|
\item \class{StreamHandler} instances send error messages to
|
|
streams (file-like objects).
|
|
|
|
\item \class{FileHandler} instances send error messages to disk
|
|
files.
|
|
|
|
\item \class{RotatingFileHandler} instances send error messages to disk
|
|
files, with support for maximum log file sizes and log file rotation.
|
|
|
|
\item \class{SocketHandler} instances send error messages to
|
|
TCP/IP sockets.
|
|
|
|
\item \class{DatagramHandler} instances send error messages to UDP
|
|
sockets.
|
|
|
|
\item \class{SMTPHandler} instances send error messages to a
|
|
designated email address.
|
|
|
|
\item \class{SysLogHandler} instances send error messages to a
|
|
\UNIX{} syslog daemon, possibly on a remote machine.
|
|
|
|
\item \class{NTEventLogHandler} instances send error messages to a
|
|
Windows NT/2000/XP event log.
|
|
|
|
\item \class{MemoryHandler} instances send error messages to a
|
|
buffer in memory, which is flushed whenever specific criteria are
|
|
met.
|
|
|
|
\item \class{HTTPHandler} instances send error messages to an
|
|
HTTP server using either \samp{GET} or \samp{POST} semantics.
|
|
|
|
\end{enumerate}
|
|
|
|
The \class{StreamHandler} and \class{FileHandler} classes are defined
|
|
in the core logging package. The other handlers are defined in a sub-
|
|
module, \module{logging.handlers}. (There is also another sub-module,
|
|
\module{logging.config}, for configuration functionality.)
|
|
|
|
Logged messages are formatted for presentation through instances of the
|
|
\class{Formatter} class. They are initialized with a format string
|
|
suitable for 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.
|
|
|
|
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 \method{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
|
|
children are allowed through the filter, and all others dropped.
|
|
|
|
In addition to the classes described above, there are a number of module-
|
|
level functions.
|
|
|
|
\begin{funcdesc}{getLogger}{\optional{name}}
|
|
Return a logger with the specified name or, if no name is specified, return
|
|
a logger which is the root logger of the hierarchy. If specified, the name
|
|
is typically a dot-separated hierarchical name like \var{"a"}, \var{"a.b"}
|
|
or \var{"a.b.c.d"}. Choice of these names is entirely up to the developer
|
|
who is using logging.
|
|
|
|
All calls to this function with a given name return the same logger instance.
|
|
This means that logger instances never need to be passed between different
|
|
parts of an application.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{getLoggerClass}{}
|
|
Return either the standard \class{Logger} class, or the last class passed to
|
|
\function{setLoggerClass()}. This function may be called from within a new
|
|
class definition, to ensure that installing a customised \class{Logger} class
|
|
will not undo customisations already applied by other code. For example:
|
|
|
|
\begin{verbatim}
|
|
class MyLogger(logging.getLoggerClass()):
|
|
# ... override behaviour here
|
|
\end{verbatim}
|
|
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{debug}{msg\optional{, *args\optional{, **kwargs}}}
|
|
Logs a message with level \constant{DEBUG} on the root logger.
|
|
The \var{msg} is the message format string, and the \var{args} are the
|
|
arguments which are merged into \var{msg}. The only keyword argument in
|
|
\var{kwargs} which is inspected is \var{exc_info} which, if it does not
|
|
evaluate as false, causes exception information to be added to the logging
|
|
message. If an exception tuple (in the format returned by
|
|
\function{sys.exc_info()}) is provided, it is used; otherwise,
|
|
\function{sys.exc_info()} is called to get the exception information.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{info}{msg\optional{, *args\optional{, **kwargs}}}
|
|
Logs a message with level \constant{INFO} on the root logger.
|
|
The arguments are interpreted as for \function{debug()}.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{warning}{msg\optional{, *args\optional{, **kwargs}}}
|
|
Logs a message with level \constant{WARNING} on the root logger.
|
|
The arguments are interpreted as for \function{debug()}.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{error}{msg\optional{, *args\optional{, **kwargs}}}
|
|
Logs a message with level \constant{ERROR} on the root logger.
|
|
The arguments are interpreted as for \function{debug()}.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{critical}{msg\optional{, *args\optional{, **kwargs}}}
|
|
Logs a message with level \constant{CRITICAL} on the root logger.
|
|
The arguments are interpreted as for \function{debug()}.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{exception}{msg\optional{, *args}}
|
|
Logs a message with level \constant{ERROR} on the root logger.
|
|
The arguments are interpreted as for \function{debug()}. Exception info
|
|
is added to the logging message. This function should only be called
|
|
from an exception handler.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{log}{level, msg\optional{, *args\optional{, **kwargs}}}
|
|
Logs a message with level \var{level} on the root logger.
|
|
The other arguments are interpreted as for \function{debug()}.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{disable}{lvl}
|
|
Provides an overriding level \var{lvl} for all loggers which takes
|
|
precedence over the logger's own level. When the need arises to
|
|
temporarily throttle logging output down across the whole application,
|
|
this function can be useful.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{addLevelName}{lvl, levelName}
|
|
Associates level \var{lvl} with text \var{levelName} in an internal
|
|
dictionary, which is used to map numeric levels to a textual
|
|
representation, for example when a \class{Formatter} formats a message.
|
|
This function can also be used to define your own levels. The only
|
|
constraints are that all levels used must be registered using this
|
|
function, levels should be positive integers and they should increase
|
|
in increasing order of severity.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{getLevelName}{lvl}
|
|
Returns the textual representation of logging level \var{lvl}. If the
|
|
level is one of the predefined levels \constant{CRITICAL},
|
|
\constant{ERROR}, \constant{WARNING}, \constant{INFO} or \constant{DEBUG}
|
|
then you get the corresponding string. If you have associated levels
|
|
with names using \function{addLevelName()} then the name you have associated
|
|
with \var{lvl} is returned. If a numeric value corresponding to one of the
|
|
defined levels is passed in, the corresponding string representation is
|
|
returned. Otherwise, the string "Level \%s" \% lvl is returned.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{makeLogRecord}{attrdict}
|
|
Creates and returns a new \class{LogRecord} instance whose attributes are
|
|
defined by \var{attrdict}. This function is useful for taking a pickled
|
|
\class{LogRecord} attribute dictionary, sent over a socket, and reconstituting
|
|
it as a \class{LogRecord} instance at the receiving end.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{basicConfig}{}
|
|
Does basic configuration for the logging system by creating a
|
|
\class{StreamHandler} with a default \class{Formatter} and adding it to
|
|
the root logger. The functions \function{debug()}, \function{info()},
|
|
\function{warning()}, \function{error()} and \function{critical()} will call
|
|
\function{basicConfig()} automatically if no handlers are defined for the
|
|
root logger.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{shutdown}{}
|
|
Informs the logging system to perform an orderly shutdown by flushing and
|
|
closing all handlers.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{setLoggerClass}{klass}
|
|
Tells the logging system to use the class \var{klass} when instantiating a
|
|
logger. The class should define \method{__init__()} such that only a name
|
|
argument is required, and the \method{__init__()} should call
|
|
\method{Logger.__init__()}. This function is typically called before any
|
|
loggers are instantiated by applications which need to use custom logger
|
|
behavior.
|
|
\end{funcdesc}
|
|
|
|
|
|
\begin{seealso}
|
|
\seepep{282}{A Logging System}
|
|
{The proposal which described this feature for inclusion in
|
|
the Python standard library.}
|
|
\seelink{http://www.red-dove.com/python_logging.html}
|
|
{Original Python \module{logging} package}
|
|
{This is the original source for the \module{logging}
|
|
package. The version of the package available from this
|
|
site is suitable for use with Python 1.5.2, 2.1.x and 2.2.x,
|
|
which do not include the \module{logging} package in the standard
|
|
library.}
|
|
\end{seealso}
|
|
|
|
|
|
\subsection{Logger Objects}
|
|
|
|
Loggers have the following attributes and methods. Note that Loggers are
|
|
never instantiated directly, but always through the module-level function
|
|
\function{logging.getLogger(name)}.
|
|
|
|
\begin{datadesc}{propagate}
|
|
If this evaluates to false, logging messages are not passed by this
|
|
logger or by child loggers to higher level (ancestor) loggers. The
|
|
constructor sets this attribute to 1.
|
|
\end{datadesc}
|
|
|
|
\begin{methoddesc}{setLevel}{lvl}
|
|
Sets the threshold for this logger to \var{lvl}. Logging messages
|
|
which are less severe than \var{lvl} will be ignored. When a logger is
|
|
created, the level is set to \constant{NOTSET} (which causes all messages
|
|
to be processed in the root logger, or delegation to the parent in non-root
|
|
loggers).
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{isEnabledFor}{lvl}
|
|
Indicates if a message of severity \var{lvl} would be processed by
|
|
this logger. This method checks first the module-level level set by
|
|
\function{logging.disable(lvl)} and then the logger's effective level as
|
|
determined by \method{getEffectiveLevel()}.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{getEffectiveLevel}{}
|
|
Indicates the effective level for this logger. If a value other than
|
|
\constant{NOTSET} has been set using \method{setLevel()}, it is returned.
|
|
Otherwise, the hierarchy is traversed towards the root until a value
|
|
other than \constant{NOTSET} is found, and that value is returned.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{debug}{msg\optional{, *args\optional{, **kwargs}}}
|
|
Logs a message with level \constant{DEBUG} on this logger.
|
|
The \var{msg} is the message format string, and the \var{args} are the
|
|
arguments which are merged into \var{msg}. The only keyword argument in
|
|
\var{kwargs} which is inspected is \var{exc_info} which, if it does not
|
|
evaluate as false, causes exception information to be added to the logging
|
|
message. If an exception tuple (as provided by \function{sys.exc_info()})
|
|
is provided, it is used; otherwise, \function{sys.exc_info()} is called
|
|
to get the exception information.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{info}{msg\optional{, *args\optional{, **kwargs}}}
|
|
Logs a message with level \constant{INFO} on this logger.
|
|
The arguments are interpreted as for \method{debug()}.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{warning}{msg\optional{, *args\optional{, **kwargs}}}
|
|
Logs a message with level \constant{WARNING} on this logger.
|
|
The arguments are interpreted as for \method{debug()}.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{error}{msg\optional{, *args\optional{, **kwargs}}}
|
|
Logs a message with level \constant{ERROR} on this logger.
|
|
The arguments are interpreted as for \method{debug()}.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{critical}{msg\optional{, *args\optional{, **kwargs}}}
|
|
Logs a message with level \constant{CRITICAL} on this logger.
|
|
The arguments are interpreted as for \method{debug()}.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{log}{lvl, msg\optional{, *args\optional{, **kwargs}}}
|
|
Logs a message with integer level \var{lvl} on this logger.
|
|
The other arguments are interpreted as for \method{debug()}.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{exception}{msg\optional{, *args}}
|
|
Logs a message with level \constant{ERROR} on this logger.
|
|
The arguments are interpreted as for \method{debug()}. Exception info
|
|
is added to the logging message. This method should only be called
|
|
from an exception handler.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{addFilter}{filt}
|
|
Adds the specified filter \var{filt} to this logger.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{removeFilter}{filt}
|
|
Removes the specified filter \var{filt} from this logger.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{filter}{record}
|
|
Applies this logger's filters to the record and returns a true value if
|
|
the record is to be processed.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{addHandler}{hdlr}
|
|
Adds the specified handler \var{hdlr} to this logger.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{removeHandler}{hdlr}
|
|
Removes the specified handler \var{hdlr} from this logger.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{findCaller}{}
|
|
Finds the caller's source filename and line number. Returns the filename
|
|
and line number as a 2-element tuple.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{handle}{record}
|
|
Handles a record by passing it to all handlers associated with this logger
|
|
and its ancestors (until a false value of \var{propagate} is found).
|
|
This method is used for unpickled records received from a socket, as well
|
|
as those created locally. Logger-level filtering is applied using
|
|
\method{filter()}.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{makeRecord}{name, lvl, fn, lno, msg, args, exc_info}
|
|
This is a factory method which can be overridden in subclasses to create
|
|
specialized \class{LogRecord} instances.
|
|
\end{methoddesc}
|
|
|
|
\subsection{Basic example \label{minimal-example}}
|
|
|
|
The \module{logging} package provides a lot of flexibility, and its
|
|
configuration can appear daunting. This section demonstrates that simple
|
|
use of the logging package is possible.
|
|
|
|
The simplest example shows logging to the console:
|
|
|
|
\begin{verbatim}
|
|
import logging
|
|
|
|
logging.debug('A debug message')
|
|
logging.info('Some information')
|
|
logging.warning('A shot across the bows')
|
|
\end{verbatim}
|
|
|
|
If you run the above script, you'll see this:
|
|
\begin{verbatim}
|
|
WARNING:root:A shot across the bows
|
|
\end{verbatim}
|
|
|
|
Because no particular logger was specified, the system used the root logger.
|
|
The debug and info messages didn't appear because by default, the root
|
|
logger is configured to only handle messages with a severity of WARNING
|
|
or above. The message format is also a configuration default, as is the output
|
|
destination of the messages - \code{sys.stderr}. The severity level,
|
|
the message format and destination can be easily changed, as shown in
|
|
the example below:
|
|
|
|
\begin{verbatim}
|
|
import logging
|
|
|
|
logging.basicConfig(level=logging.DEBUG,
|
|
format='%(asctime)s %(levelname)s %(message)s',
|
|
filename='/tmp/myapp.log',
|
|
filemode='w')
|
|
logging.debug('A debug message')
|
|
logging.info('Some information')
|
|
logging.warning('A shot across the bows')
|
|
\end{verbatim}
|
|
|
|
The \method{basicConfig()} method is used to change the configuration
|
|
defaults, which results in output (written to \code{/tmp/myapp.log})
|
|
which should look something like the following:
|
|
|
|
\begin{verbatim}
|
|
2004-07-02 13:00:08,743 DEBUG A debug message
|
|
2004-07-02 13:00:08,743 INFO Some information
|
|
2004-07-02 13:00:08,743 WARNING A shot across the bows
|
|
\end{verbatim}
|
|
|
|
This time, all messages with a severity of DEBUG or above were handled,
|
|
and the format of the messages was also changed, and output went to the
|
|
specified file rather than the console.
|
|
|
|
Formatting uses standard Python string formatting - see section
|
|
\ref{typesseq-strings}. The format string takes the following
|
|
common specifiers. For a complete list of specifiers, consult the
|
|
\class{Formatter} documentation.
|
|
|
|
\begin{tableii}{l|l}{code}{Format}{Description}
|
|
\lineii{\%(name)s} {Name of the logger (logging channel).}
|
|
\lineii{\%(levelname)s}{Text logging level for the message
|
|
(\code{'DEBUG'}, \code{'INFO'},
|
|
\code{'WARNING'}, \code{'ERROR'},
|
|
\code{'CRITICAL'}).}
|
|
\lineii{\%(asctime)s} {Human-readable time when the \class{LogRecord}
|
|
was created. By default this is of the form
|
|
``2003-07-08 16:49:45,896'' (the numbers after the
|
|
comma are millisecond portion of the time).}
|
|
\lineii{\%(message)s} {The logged message.}
|
|
\end{tableii}
|
|
|
|
To change the date/time format, you can pass an additional keyword parameter,
|
|
\var{datefmt}, as in the following:
|
|
|
|
\begin{verbatim}
|
|
import logging
|
|
|
|
logging.basicConfig(level=logging.DEBUG,
|
|
format='%(asctime)s %(levelname)-8s %(message)s',
|
|
datefmt='%a, %d %b %Y %H:%M:%S',
|
|
filename='/temp/myapp.log',
|
|
filemode='w')
|
|
logging.debug('A debug message')
|
|
logging.info('Some information')
|
|
logging.warning('A shot across the bows')
|
|
\end{verbatim}
|
|
|
|
which would result in output like
|
|
|
|
\begin{verbatim}
|
|
Fri, 02 Jul 2004 13:06:18 DEBUG A debug message
|
|
Fri, 02 Jul 2004 13:06:18 INFO Some information
|
|
Fri, 02 Jul 2004 13:06:18 WARNING A shot across the bows
|
|
\end{verbatim}
|
|
|
|
The date format string follows the requirements of \function{strftime()} -
|
|
see the documentation for the \refmodule{time} module.
|
|
|
|
If, instead of sending logging output to the console or a file, you'd rather
|
|
use a file-like object which you have created separately, you can pass it
|
|
to \function{basicConfig()} using the \var{stream} keyword argument. Note
|
|
that if both \var{stream} and \var{filename} keyword arguments are passed,
|
|
the \var{stream} argument is ignored.
|
|
|
|
Of course, you can put variable information in your output. To do this,
|
|
simply have the message be a format string and pass in additional arguments
|
|
containing the variable information, as in the following example:
|
|
|
|
\begin{verbatim}
|
|
import logging
|
|
|
|
logging.basicConfig(level=logging.DEBUG,
|
|
format='%(asctime)s %(levelname)-8s %(message)s',
|
|
datefmt='%a, %d %b %Y %H:%M:%S',
|
|
filename='/temp/myapp.log',
|
|
filemode='w')
|
|
logging.error('Pack my box with %d dozen %s', 5, 'liquor jugs')
|
|
\end{verbatim}
|
|
|
|
which would result in
|
|
|
|
\begin{verbatim}
|
|
Wed, 21 Jul 2004 15:35:16 ERROR Pack my box with 5 dozen liquor jugs
|
|
\end{verbatim}
|
|
|
|
\subsection{Logging to multiple destinations \label{multiple-destinations}}
|
|
|
|
Let's say you want to log to console and file with different message formats
|
|
and in differing circumstances. Say you want to log messages with levels
|
|
of DEBUG and higher to file, and those messages at level INFO and higher to
|
|
the console. Let's also assume that the file should contain timestamps, but
|
|
the console messages should not. Here's how you can achieve this:
|
|
|
|
\begin{verbatim}
|
|
import logging
|
|
|
|
#set up logging to file - see previous section for more details
|
|
logging.basicConfig(level=logging.DEBUG,
|
|
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
|
|
datefmt='%m-%d %H:%M',
|
|
filename='/temp/myapp.log',
|
|
filemode='w')
|
|
#define a Handler which writes INFO messages or higher to the sys.stderr
|
|
console = logging.StreamHandler()
|
|
console.setLevel(logging.INFO)
|
|
#set a format which is simpler for console use
|
|
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
|
|
#tell the handler to use this format
|
|
console.setFormatter(formatter)
|
|
#add the handler to the root logger
|
|
logging.getLogger('').addHandler(console)
|
|
|
|
#Now, we can log to the root logger, or any other logger. First the root...
|
|
logging.info('Jackdaws love my big sphinx of quartz.')
|
|
|
|
#Now, define a couple of other loggers which might represent areas in your
|
|
#application:
|
|
|
|
logger1 = logging.getLogger('myapp.area1')
|
|
logger2 = logging.getLogger('myapp.area2')
|
|
|
|
logger1.debug('Quick zephyrs blow, vexing daft Jim.')
|
|
logger1.info('How quickly daft jumping zebras vex.')
|
|
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
|
|
logger2.error('The five boxing wizards jump quickly.')
|
|
\end{verbatim}
|
|
|
|
When you run this, on the console you will see
|
|
|
|
\begin{verbatim}
|
|
root : INFO Jackdaws love my big sphinx of quartz.
|
|
myapp.area1 : INFO How quickly daft jumping zebras vex.
|
|
myapp.area2 : WARNING Jail zesty vixen who grabbed pay from quack.
|
|
myapp.area2 : ERROR The five boxing wizards jump quickly.
|
|
\end{verbatim}
|
|
|
|
and in the file you will see something like
|
|
|
|
\begin{verbatim}
|
|
10-22 22:19 root INFO Jackdaws love my big sphinx of quartz.
|
|
10-22 22:19 myapp.area1 DEBUG Quick zephyrs blow, vexing daft Jim.
|
|
10-22 22:19 myapp.area1 INFO How quickly daft jumping zebras vex.
|
|
10-22 22:19 myapp.area2 WARNING Jail zesty vixen who grabbed pay from quack.
|
|
10-22 22:19 myapp.area2 ERROR The five boxing wizards jump quickly.
|
|
\end{verbatim}
|
|
|
|
As you can see, the DEBUG message only shows up in the file. The other
|
|
messages are sent to both destinations.
|
|
|
|
This example uses console and file handlers, but you can use any number and
|
|
combination of handlers you choose.
|
|
|
|
\subsection{Sending and receiving logging events across a network
|
|
\label{network-logging}}
|
|
|
|
Let's say you want to send logging events across a network, and handle them
|
|
at the receiving end. A simple way of doing this is attaching a
|
|
\class{SocketHandler} instance to the root logger at the sending end:
|
|
|
|
\begin{verbatim}
|
|
import logging, logging.handlers
|
|
|
|
rootLogger = logging.getLogger('')
|
|
rootLogger.setLevel(logging.DEBUG)
|
|
socketHandler = logging.handlers.SocketHandler('localhost',
|
|
logging.handlers.DEFAULT_TCP_LOGGING_PORT)
|
|
# don't bother with a formatter, since a socket handler sends the event as
|
|
# an unformatted pickle
|
|
rootLogger.addHandler(socketHandler)
|
|
|
|
#Now, we can log to the root logger, or any other logger. First the root...
|
|
logging.info('Jackdaws love my big sphinx of quartz.')
|
|
|
|
#Now, define a couple of other loggers which might represent areas in your
|
|
#application:
|
|
|
|
logger1 = logging.getLogger('myapp.area1')
|
|
logger2 = logging.getLogger('myapp.area2')
|
|
|
|
logger1.debug('Quick zephyrs blow, vexing daft Jim.')
|
|
logger1.info('How quickly daft jumping zebras vex.')
|
|
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
|
|
logger2.error('The five boxing wizards jump quickly.')
|
|
\end{verbatim}
|
|
|
|
At the receiving end, you can set up a receiver using the
|
|
\module{SocketServer} module. Here is a basic working example:
|
|
|
|
\begin{verbatim}
|
|
import struct, cPickle, logging, logging.handlers
|
|
|
|
from SocketServer import ThreadingTCPServer, StreamRequestHandler
|
|
|
|
class LogRecordStreamHandler(StreamRequestHandler):
|
|
"""
|
|
Handler for a streaming logging request. It basically logs the record
|
|
using whatever logging policy is configured locally.
|
|
"""
|
|
|
|
def handle(self):
|
|
"""
|
|
Handle multiple requests - each expected to be a 4-byte length,
|
|
followed by the LogRecord in pickle format. Logs the record
|
|
according to whatever policy is configured locally.
|
|
"""
|
|
while 1:
|
|
chunk = self.connection.recv(4)
|
|
if len(chunk) < 4:
|
|
break
|
|
slen = struct.unpack(">L", chunk)[0]
|
|
chunk = self.connection.recv(slen)
|
|
while len(chunk) < slen:
|
|
chunk = chunk + self.connection.recv(slen - len(chunk))
|
|
obj = self.unPickle(chunk)
|
|
record = logging.makeLogRecord(obj)
|
|
self.handleLogRecord(record)
|
|
|
|
def unPickle(self, data):
|
|
return cPickle.loads(data)
|
|
|
|
def handleLogRecord(self, record):
|
|
#if a name is specified, we use the named logger rather than the one
|
|
#implied by the record.
|
|
if self.server.logname is not None:
|
|
name = self.server.logname
|
|
else:
|
|
name = record.name
|
|
logger = logging.getLogger(name)
|
|
#N.B. EVERY record gets logged. This is because Logger.handle
|
|
#is normally called AFTER logger-level filtering. If you want
|
|
#to do filtering, do it at the client end to save wasting
|
|
#cycles and network bandwidth!
|
|
logger.handle(record)
|
|
|
|
class LogRecordSocketReceiver(ThreadingTCPServer):
|
|
"""
|
|
A simple-minded TCP socket-based logging receiver suitable for test
|
|
purposes.
|
|
"""
|
|
|
|
allow_reuse_address = 1
|
|
|
|
def __init__(self, host='localhost',
|
|
port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
|
|
handler=LogRecordStreamHandler):
|
|
ThreadingTCPServer.__init__(self, (host, port), handler)
|
|
self.abort = 0
|
|
self.timeout = 1
|
|
self.logname = None
|
|
|
|
def serve_until_stopped(self):
|
|
import select
|
|
abort = 0
|
|
while not abort:
|
|
rd, wr, ex = select.select([self.socket.fileno()],
|
|
[], [],
|
|
self.timeout)
|
|
if rd:
|
|
self.handle_request()
|
|
abort = self.abort
|
|
|
|
def main():
|
|
logging.basicConfig(
|
|
format="%(relativeCreated)5d %(name)-15s %(levelname)-8s %(message)s",
|
|
datefmt="%H:%M:%S")
|
|
tcpserver = LogRecordSocketReceiver()
|
|
print "About to start TCP server..."
|
|
tcpserver.serve_until_stopped()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
\end{verbatim}
|
|
|
|
If you first run the server, and then the client. On the client side, nothing
|
|
is printed on the client console; on the server side, you should see something
|
|
like this:
|
|
|
|
\begin{verbatim}
|
|
About to start TCP server...
|
|
59 root INFO Jackdaws love my big sphinx of quartz.
|
|
59 myapp.area1 DEBUG Quick zephyrs blow, vexing daft Jim.
|
|
69 myapp.area1 INFO How quickly daft jumping zebras vex.
|
|
69 myapp.area2 WARNING Jail zesty vixen who grabbed pay from quack.
|
|
69 myapp.area2 ERROR The five boxing wizards jump quickly.
|
|
\end{verbatim}
|
|
|
|
\subsection{Handler Objects}
|
|
|
|
Handlers have the following attributes and methods. Note that
|
|
\class{Handler} is never instantiated directly; this class acts as a
|
|
base for more useful subclasses. However, the \method{__init__()}
|
|
method in subclasses needs to call \method{Handler.__init__()}.
|
|
|
|
\begin{methoddesc}{__init__}{level=\constant{NOTSET}}
|
|
Initializes the \class{Handler} instance by setting its level, setting
|
|
the list of filters to the empty list and creating a lock (using
|
|
\method{createLock()}) for serializing access to an I/O mechanism.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{createLock}{}
|
|
Initializes a thread lock which can be used to serialize access to
|
|
underlying I/O functionality which may not be threadsafe.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{acquire}{}
|
|
Acquires the thread lock created with \method{createLock()}.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{release}{}
|
|
Releases the thread lock acquired with \method{acquire()}.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{setLevel}{lvl}
|
|
Sets the threshold for this handler to \var{lvl}. Logging messages which are
|
|
less severe than \var{lvl} will be ignored. When a handler is created, the
|
|
level is set to \constant{NOTSET} (which causes all messages to be processed).
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{setFormatter}{form}
|
|
Sets the \class{Formatter} for this handler to \var{form}.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{addFilter}{filt}
|
|
Adds the specified filter \var{filt} to this handler.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{removeFilter}{filt}
|
|
Removes the specified filter \var{filt} from this handler.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{filter}{record}
|
|
Applies this handler's filters to the record and returns a true value if
|
|
the record is to be processed.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{flush}{}
|
|
Ensure all logging output has been flushed. This version does
|
|
nothing and is intended to be implemented by subclasses.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{close}{}
|
|
Tidy up any resources used by the handler. This version does
|
|
nothing and is intended to be implemented by subclasses.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{handle}{record}
|
|
Conditionally emits the specified logging record, depending on
|
|
filters which may have been added to the handler. Wraps the actual
|
|
emission of the record with acquisition/release of the I/O thread
|
|
lock.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{handleError}{record}
|
|
This method should be called from handlers when an exception is
|
|
encountered during an \method{emit()} call. By default it does nothing,
|
|
which means that exceptions get silently ignored. This is what is
|
|
mostly wanted for a logging system - most users will not care
|
|
about errors in the logging system, they are more interested in
|
|
application errors. You could, however, replace this with a custom
|
|
handler if you wish. The specified record is the one which was being
|
|
processed when the exception occurred.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{format}{record}
|
|
Do formatting for a record - if a formatter is set, use it.
|
|
Otherwise, use the default formatter for the module.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{emit}{record}
|
|
Do whatever it takes to actually log the specified logging record.
|
|
This version is intended to be implemented by subclasses and so
|
|
raises a \exception{NotImplementedError}.
|
|
\end{methoddesc}
|
|
|
|
\subsubsection{StreamHandler}
|
|
|
|
The \class{StreamHandler} class sends logging output to streams such as
|
|
\var{sys.stdout}, \var{sys.stderr} or any file-like object (or, more
|
|
precisely, any object which supports \method{write()} and \method{flush()}
|
|
methods).
|
|
|
|
\begin{classdesc}{StreamHandler}{\optional{strm}}
|
|
Returns a new instance of the \class{StreamHandler} class. If \var{strm} is
|
|
specified, the instance will use it for logging output; otherwise,
|
|
\var{sys.stderr} will be used.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{emit}{record}
|
|
If a formatter is specified, it is used to format the record.
|
|
The record is then written to the stream with a trailing newline.
|
|
If exception information is present, it is formatted using
|
|
\function{traceback.print_exception()} and appended to the stream.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{flush}{}
|
|
Flushes the stream by calling its \method{flush()} method. Note that
|
|
the \method{close()} method is inherited from \class{Handler} and
|
|
so does nothing, so an explicit \method{flush()} call may be needed
|
|
at times.
|
|
\end{methoddesc}
|
|
|
|
\subsubsection{FileHandler}
|
|
|
|
The \class{FileHandler} class sends logging output to a disk file.
|
|
It inherits the output functionality from \class{StreamHandler}.
|
|
|
|
\begin{classdesc}{FileHandler}{filename\optional{, mode}}
|
|
Returns a new instance of the \class{FileHandler} class. The specified
|
|
file is opened and used as the stream for logging. If \var{mode} is
|
|
not specified, \constant{'a'} is used. By default, the file grows
|
|
indefinitely.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{close}{}
|
|
Closes the file.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{emit}{record}
|
|
Outputs the record to the file.
|
|
\end{methoddesc}
|
|
|
|
\subsubsection{RotatingFileHandler}
|
|
|
|
The \class{RotatingFileHandler} class supports rotation of disk log files.
|
|
|
|
\begin{classdesc}{RotatingFileHandler}{filename\optional{, mode\optional{,
|
|
maxBytes\optional{, backupCount}}}}
|
|
Returns a new instance of the \class{RotatingFileHandler} class. The
|
|
specified file is opened and used as the stream for logging. If
|
|
\var{mode} is not specified, \code{'a'} is used. By default, the
|
|
file grows indefinitely.
|
|
|
|
You can use the \var{maxBytes} and
|
|
\var{backupCount} values to allow the file to \dfn{rollover} at a
|
|
predetermined size. When the size is about to be exceeded, the file is
|
|
closed and a new file is silently opened for output. Rollover occurs
|
|
whenever the current log file is nearly \var{maxBytes} in length; if
|
|
\var{maxBytes} is zero, rollover never occurs. If \var{backupCount}
|
|
is non-zero, the system will save old log files by appending the
|
|
extensions ".1", ".2" etc., to the filename. For example, with
|
|
a \var{backupCount} of 5 and a base file name of
|
|
\file{app.log}, you would get \file{app.log},
|
|
\file{app.log.1}, \file{app.log.2}, up to \file{app.log.5}. The file being
|
|
written to is always \file{app.log}. When this file is filled, it is
|
|
closed and renamed to \file{app.log.1}, and if files \file{app.log.1},
|
|
\file{app.log.2}, etc. exist, then they are renamed to \file{app.log.2},
|
|
\file{app.log.3} etc. respectively.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{doRollover}{}
|
|
Does a rollover, as described above.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{emit}{record}
|
|
Outputs the record to the file, catering for rollover as described
|
|
in \method{setRollover()}.
|
|
\end{methoddesc}
|
|
|
|
\subsubsection{SocketHandler}
|
|
|
|
The \class{SocketHandler} class sends logging output to a network
|
|
socket. The base class uses a TCP socket.
|
|
|
|
\begin{classdesc}{SocketHandler}{host, port}
|
|
Returns a new instance of the \class{SocketHandler} class intended to
|
|
communicate with a remote machine whose address is given by \var{host}
|
|
and \var{port}.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{close}{}
|
|
Closes the socket.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{handleError}{}
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{emit}{}
|
|
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. If the connection was previously lost, re-establishes the connection.
|
|
To unpickle the record at the receiving end into a \class{LogRecord}, use the
|
|
\function{makeLogRecord()} function.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{handleError}{}
|
|
Handles an error which has occurred during \method{emit()}. The
|
|
most likely cause is a lost connection. Closes the socket so that
|
|
we can retry on the next event.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{makeSocket}{}
|
|
This is a factory method which allows subclasses to define the precise
|
|
type of socket they want. The default implementation creates a TCP
|
|
socket (\constant{socket.SOCK_STREAM}).
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{makePickle}{record}
|
|
Pickles the record's attribute dictionary in binary format with a length
|
|
prefix, and returns it ready for transmission across the socket.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{send}{packet}
|
|
Send a pickled string \var{packet} to the socket. This function allows
|
|
for partial sends which can happen when the network is busy.
|
|
\end{methoddesc}
|
|
|
|
\subsubsection{DatagramHandler}
|
|
|
|
The \class{DatagramHandler} class inherits from \class{SocketHandler}
|
|
to support sending logging messages over UDP sockets.
|
|
|
|
\begin{classdesc}{DatagramHandler}{host, port}
|
|
Returns a new instance of the \class{DatagramHandler} class intended to
|
|
communicate with a remote machine whose address is given by \var{host}
|
|
and \var{port}.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{emit}{}
|
|
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
|
|
\function{makeLogRecord()} function.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{makeSocket}{}
|
|
The factory method of \class{SocketHandler} is here overridden to create
|
|
a UDP socket (\constant{socket.SOCK_DGRAM}).
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{send}{s}
|
|
Send a pickled string to a socket.
|
|
\end{methoddesc}
|
|
|
|
\subsubsection{SysLogHandler}
|
|
|
|
The \class{SysLogHandler} class supports sending logging messages to a
|
|
remote or local \UNIX{} syslog.
|
|
|
|
\begin{classdesc}{SysLogHandler}{\optional{address\optional{, facility}}}
|
|
Returns a new instance of the \class{SysLogHandler} class intended to
|
|
communicate with a remote \UNIX{} machine whose address is given by
|
|
\var{address} in the form of a \code{(\var{host}, \var{port})}
|
|
tuple. If \var{address} is not specified, \code{('localhost', 514)} is
|
|
used. The address is used to open a UDP socket. If \var{facility} is
|
|
not specified, \constant{LOG_USER} is used.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{close}{}
|
|
Closes the socket to the remote host.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{emit}{record}
|
|
The record is formatted, and then sent to the syslog server. If
|
|
exception information is present, it is \emph{not} sent to the server.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{encodePriority}{facility, priority}
|
|
Encodes the facility and priority into an integer. You can pass in strings
|
|
or integers - if strings are passed, internal mapping dictionaries are used
|
|
to convert them to integers.
|
|
\end{methoddesc}
|
|
|
|
\subsubsection{NTEventLogHandler}
|
|
|
|
The \class{NTEventLogHandler} class supports sending logging messages
|
|
to a local Windows NT, Windows 2000 or Windows XP event log. Before
|
|
you can use it, you need Mark Hammond's Win32 extensions for Python
|
|
installed.
|
|
|
|
\begin{classdesc}{NTEventLogHandler}{appname\optional{,
|
|
dllname\optional{, logtype}}}
|
|
Returns a new instance of the \class{NTEventLogHandler} class. The
|
|
\var{appname} is used to define the application name as it appears in the
|
|
event log. An appropriate registry entry is created using this name.
|
|
The \var{dllname} should give the fully qualified pathname of a .dll or .exe
|
|
which contains message definitions to hold in the log (if not specified,
|
|
\code{'win32service.pyd'} is used - this is installed with the Win32
|
|
extensions and contains some basic placeholder message definitions.
|
|
Note that use of these placeholders will make your event logs big, as the
|
|
entire message source is held in the log. If you want slimmer logs, you have
|
|
to pass in the name of your own .dll or .exe which contains the message
|
|
definitions you want to use in the event log). The \var{logtype} is one of
|
|
\code{'Application'}, \code{'System'} or \code{'Security'}, and
|
|
defaults to \code{'Application'}.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{close}{}
|
|
At this point, you can remove the application name from the registry as a
|
|
source of event log entries. However, if you do this, you will not be able
|
|
to see the events as you intended in the Event Log Viewer - it needs to be
|
|
able to access the registry to get the .dll name. The current version does
|
|
not do this (in fact it doesn't do anything).
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{emit}{record}
|
|
Determines the message ID, event category and event type, and then logs the
|
|
message in the NT event log.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{getEventCategory}{record}
|
|
Returns the event category for the record. Override this if you
|
|
want to specify your own categories. This version returns 0.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{getEventType}{record}
|
|
Returns the event type for the record. Override this if you want
|
|
to specify your own types. This version does a mapping using the
|
|
handler's typemap attribute, which is set up in \method{__init__()}
|
|
to a dictionary which contains mappings for \constant{DEBUG},
|
|
\constant{INFO}, \constant{WARNING}, \constant{ERROR} and
|
|
\constant{CRITICAL}. If you are using your own levels, you will either need
|
|
to override this method or place a suitable dictionary in the
|
|
handler's \var{typemap} attribute.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{getMessageID}{record}
|
|
Returns the message ID for the record. If you are using your
|
|
own messages, you could do this by having the \var{msg} passed to the
|
|
logger being an ID rather than a format string. Then, in here,
|
|
you could use a dictionary lookup to get the message ID. This
|
|
version returns 1, which is the base message ID in
|
|
\file{win32service.pyd}.
|
|
\end{methoddesc}
|
|
|
|
\subsubsection{SMTPHandler}
|
|
|
|
The \class{SMTPHandler} class supports sending logging messages to an email
|
|
address via SMTP.
|
|
|
|
\begin{classdesc}{SMTPHandler}{mailhost, fromaddr, toaddrs, subject}
|
|
Returns a new instance of the \class{SMTPHandler} class. The
|
|
instance is initialized with the from and to addresses and subject
|
|
line of the email. The \var{toaddrs} should be a list of strings without
|
|
domain names (That's what the \var{mailhost} is for). To specify a
|
|
non-standard SMTP port, use the (host, port) tuple format for the
|
|
\var{mailhost} argument. If you use a string, the standard SMTP port
|
|
is used.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{emit}{record}
|
|
Formats the record and sends it to the specified addressees.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{getSubject}{record}
|
|
If you want to specify a subject line which is record-dependent,
|
|
override this method.
|
|
\end{methoddesc}
|
|
|
|
\subsubsection{MemoryHandler}
|
|
|
|
The \class{MemoryHandler} supports buffering of logging records in memory,
|
|
periodically flushing them to a \dfn{target} handler. Flushing occurs
|
|
whenever the buffer is full, or when an event of a certain severity or
|
|
greater is seen.
|
|
|
|
\class{MemoryHandler} is a subclass of the more general
|
|
\class{BufferingHandler}, which is an abstract class. This buffers logging
|
|
records in memory. Whenever each record is added to the buffer, a
|
|
check is made by calling \method{shouldFlush()} to see if the buffer
|
|
should be flushed. If it should, then \method{flush()} is expected to
|
|
do the needful.
|
|
|
|
\begin{classdesc}{BufferingHandler}{capacity}
|
|
Initializes the handler with a buffer of the specified capacity.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{emit}{record}
|
|
Appends the record to the buffer. If \method{shouldFlush()} returns true,
|
|
calls \method{flush()} to process the buffer.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{flush}{}
|
|
You can override this to implement custom flushing behavior. This version
|
|
just zaps the buffer to empty.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{shouldFlush}{record}
|
|
Returns true if the buffer is up to capacity. This method can be
|
|
overridden to implement custom flushing strategies.
|
|
\end{methoddesc}
|
|
|
|
\begin{classdesc}{MemoryHandler}{capacity\optional{, flushLevel
|
|
\optional{, target}}}
|
|
Returns a new instance of the \class{MemoryHandler} class. The
|
|
instance is initialized with a buffer size of \var{capacity}. If
|
|
\var{flushLevel} is not specified, \constant{ERROR} is used. If no
|
|
\var{target} is specified, the target will need to be set using
|
|
\method{setTarget()} before this handler does anything useful.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{close}{}
|
|
Calls \method{flush()}, sets the target to \constant{None} and
|
|
clears the buffer.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{flush}{}
|
|
For a \class{MemoryHandler}, flushing means just sending the buffered
|
|
records to the target, if there is one. Override if you want
|
|
different behavior.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{setTarget}{target}
|
|
Sets the target handler for this handler.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{shouldFlush}{record}
|
|
Checks for buffer full or a record at the \var{flushLevel} or higher.
|
|
\end{methoddesc}
|
|
|
|
\subsubsection{HTTPHandler}
|
|
|
|
The \class{HTTPHandler} class supports sending logging messages to a
|
|
Web server, using either \samp{GET} or \samp{POST} semantics.
|
|
|
|
\begin{classdesc}{HTTPHandler}{host, url\optional{, method}}
|
|
Returns a new instance of the \class{HTTPHandler} class. The
|
|
instance is initialized with a host address, url and HTTP method.
|
|
If no \var{method} is specified, \samp{GET} is used.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{emit}{record}
|
|
Sends the record to the Web server as an URL-encoded dictionary.
|
|
\end{methoddesc}
|
|
|
|
\subsection{Formatter Objects}
|
|
|
|
\class{Formatter}s have the following attributes and methods. They are
|
|
responsible for converting a \class{LogRecord} to (usually) a string
|
|
which can be interpreted by either a human or an external system. The
|
|
base
|
|
\class{Formatter} allows a formatting string to be specified. If none is
|
|
supplied, the default value of \code{'\%(message)s'} is used.
|
|
|
|
A Formatter can be initialized with a format string which makes use of
|
|
knowledge of the \class{LogRecord} attributes - such as the default value
|
|
mentioned above making use of the fact that the user's message and
|
|
arguments are pre-formatted into a \class{LogRecord}'s \var{message}
|
|
attribute. This format string contains standard python \%-style
|
|
mapping keys. See section \ref{typesseq-strings}, ``String Formatting
|
|
Operations,'' for more information on string formatting.
|
|
|
|
Currently, the useful mapping keys in a \class{LogRecord} are:
|
|
|
|
\begin{tableii}{l|l}{code}{Format}{Description}
|
|
\lineii{\%(name)s} {Name of the logger (logging channel).}
|
|
\lineii{\%(levelno)s} {Numeric logging level for the message
|
|
(\constant{DEBUG}, \constant{INFO},
|
|
\constant{WARNING}, \constant{ERROR},
|
|
\constant{CRITICAL}).}
|
|
\lineii{\%(levelname)s}{Text logging level for the message
|
|
(\code{'DEBUG'}, \code{'INFO'},
|
|
\code{'WARNING'}, \code{'ERROR'},
|
|
\code{'CRITICAL'}).}
|
|
\lineii{\%(pathname)s} {Full pathname of the source file where the logging
|
|
call was issued (if available).}
|
|
\lineii{\%(filename)s} {Filename portion of pathname.}
|
|
\lineii{\%(module)s} {Module (name portion of filename).}
|
|
\lineii{\%(lineno)d} {Source line number where the logging call was issued
|
|
(if available).}
|
|
\lineii{\%(created)f} {Time when the \class{LogRecord} was created (as
|
|
returned by \function{time.time()}).}
|
|
\lineii{\%(asctime)s} {Human-readable time when the \class{LogRecord}
|
|
was created. By default this is of the form
|
|
``2003-07-08 16:49:45,896'' (the numbers after the
|
|
comma are millisecond portion of the time).}
|
|
\lineii{\%(msecs)d} {Millisecond portion of the time when the
|
|
\class{LogRecord} was created.}
|
|
\lineii{\%(thread)d} {Thread ID (if available).}
|
|
\lineii{\%(process)d} {Process ID (if available).}
|
|
\lineii{\%(message)s} {The logged message, computed as \code{msg \% args}.}
|
|
\end{tableii}
|
|
|
|
\begin{classdesc}{Formatter}{\optional{fmt\optional{, datefmt}}}
|
|
Returns a new instance of the \class{Formatter} class. The
|
|
instance is initialized with a format string for the message as a whole,
|
|
as well as a format string for the date/time portion of a message. If
|
|
no \var{fmt} is specified, \code{'\%(message)s'} is used. If no \var{datefmt}
|
|
is specified, the ISO8601 date format is used.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{format}{record}
|
|
The record's attribute dictionary is used as the operand to a
|
|
string formatting operation. Returns the resulting string.
|
|
Before formatting the dictionary, a couple of preparatory steps
|
|
are carried out. The \var{message} attribute of the record is computed
|
|
using \var{msg} \% \var{args}. If the formatting string contains
|
|
\code{'(asctime)'}, \method{formatTime()} is called to format the
|
|
event time. If there is exception information, it is formatted using
|
|
\method{formatException()} and appended to the message.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{formatTime}{record\optional{, datefmt}}
|
|
This method should be called from \method{format()} by a formatter which
|
|
wants to make use of a formatted time. This method can be overridden
|
|
in formatters to provide for any specific requirement, but the
|
|
basic behavior is as follows: if \var{datefmt} (a string) is specified,
|
|
it is used with \function{time.strftime()} to format the creation time of the
|
|
record. Otherwise, the ISO8601 format is used. The resulting
|
|
string is returned.
|
|
\end{methoddesc}
|
|
|
|
\begin{methoddesc}{formatException}{exc_info}
|
|
Formats the specified exception information (a standard exception tuple
|
|
as returned by \function{sys.exc_info()}) as a string. This default
|
|
implementation just uses \function{traceback.print_exception()}.
|
|
The resulting string is returned.
|
|
\end{methoddesc}
|
|
|
|
\subsection{Filter Objects}
|
|
|
|
\class{Filter}s can be used by \class{Handler}s and \class{Logger}s for
|
|
more sophisticated filtering than is provided by levels. The base filter
|
|
class only allows events which are below a certain point in the logger
|
|
hierarchy. For example, a filter initialized with "A.B" will allow events
|
|
logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB",
|
|
"B.A.B" etc. If initialized with the empty string, all events are passed.
|
|
|
|
\begin{classdesc}{Filter}{\optional{name}}
|
|
Returns an instance of the \class{Filter} class. If \var{name} is specified,
|
|
it names a logger which, together with its children, will have its events
|
|
allowed through the filter. If no name is specified, allows every event.
|
|
\end{classdesc}
|
|
|
|
\begin{methoddesc}{filter}{record}
|
|
Is the specified record to be logged? Returns zero for no, nonzero for
|
|
yes. If deemed appropriate, the record may be modified in-place by this
|
|
method.
|
|
\end{methoddesc}
|
|
|
|
\subsection{LogRecord Objects}
|
|
|
|
\class{LogRecord} instances are created every time something is logged. They
|
|
contain all the information pertinent to the event being logged. The
|
|
main information passed in is in msg and args, which are combined
|
|
using msg \% args to create the message field of the record. The record
|
|
also includes information such as when the record was created, the
|
|
source line where the logging call was made, and any exception
|
|
information to be logged.
|
|
|
|
\class{LogRecord} has no methods; it's just a repository for
|
|
information about the logging event. The only reason it's a class
|
|
rather than a dictionary is to facilitate extension.
|
|
|
|
\begin{classdesc}{LogRecord}{name, lvl, pathname, lineno, msg, args,
|
|
exc_info}
|
|
Returns an instance of \class{LogRecord} initialized with interesting
|
|
information. The \var{name} is the logger name; \var{lvl} is the
|
|
numeric level; \var{pathname} is the absolute pathname of the source
|
|
file in which the logging call was made; \var{lineno} is the line
|
|
number in that file where the logging call is found; \var{msg} is the
|
|
user-supplied message (a format string); \var{args} is the tuple
|
|
which, together with \var{msg}, makes up the user message; and
|
|
\var{exc_info} is the exception tuple obtained by calling
|
|
\function{sys.exc_info() }(or \constant{None}, if no exception information
|
|
is available).
|
|
\end{classdesc}
|
|
|
|
\subsection{Thread Safety}
|
|
|
|
The logging module is intended to be thread-safe without any special work
|
|
needing to be done by its clients. It achieves this though using threading
|
|
locks; there is one lock to serialize access to the module's shared data,
|
|
and each handler also creates a lock to serialize access to its underlying
|
|
I/O.
|
|
|
|
\subsection{Configuration}
|
|
|
|
|
|
\subsubsection{Configuration functions%
|
|
\label{logging-config-api}}
|
|
|
|
The following functions allow the logging module to be
|
|
configured. Before they can be used, you must import
|
|
\module{logging.config}. Their use is optional --- you can configure
|
|
the logging module entirely by making calls to the main API (defined
|
|
in \module{logging} itself) and defining handlers which are declared
|
|
either in \module{logging} or \module{logging.handlers}.
|
|
|
|
\begin{funcdesc}{fileConfig}{fname\optional{, defaults}}
|
|
Reads the logging configuration from a ConfigParser-format file named
|
|
\var{fname}. This function can be called several times from an application,
|
|
allowing an end user the ability to select from various pre-canned
|
|
configurations (if the developer provides a mechanism to present the
|
|
choices and load the chosen configuration). Defaults to be passed to
|
|
ConfigParser can be specified in the \var{defaults} argument.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{listen}{\optional{port}}
|
|
Starts up a socket server on the specified port, and listens for new
|
|
configurations. If no port is specified, the module's default
|
|
\constant{DEFAULT_LOGGING_CONFIG_PORT} is used. Logging configurations
|
|
will be sent as a file suitable for processing by \function{fileConfig()}.
|
|
Returns a \class{Thread} instance on which you can call \method{start()}
|
|
to start the server, and which you can \method{join()} when appropriate.
|
|
To stop the server, call \function{stopListening()}.
|
|
\end{funcdesc}
|
|
|
|
\begin{funcdesc}{stopListening}{}
|
|
Stops the listening server which was created with a call to
|
|
\function{listen()}. This is typically called before calling \method{join()}
|
|
on the return value from \function{listen()}.
|
|
\end{funcdesc}
|
|
|
|
\subsubsection{Configuration file format%
|
|
\label{logging-config-fileformat}}
|
|
|
|
The configuration file format understood by \function{fileConfig()} is
|
|
based on ConfigParser functionality. The file must contain sections
|
|
called \code{[loggers]}, \code{[handlers]} and \code{[formatters]}
|
|
which identify by name the entities of each type which are defined in
|
|
the file. For each such entity, there is a separate section which
|
|
identified how that entity is configured. Thus, for a logger named
|
|
\code{log01} in the \code{[loggers]} section, the relevant
|
|
configuration details are held in a section
|
|
\code{[logger_log01]}. Similarly, a handler called \code{hand01} in
|
|
the \code{[handlers]} section will have its configuration held in a
|
|
section called \code{[handler_hand01]}, while a formatter called
|
|
\code{form01} in the \code{[formatters]} section will have its
|
|
configuration specified in a section called
|
|
\code{[formatter_form01]}. The root logger configuration must be
|
|
specified in a section called \code{[logger_root]}.
|
|
|
|
Examples of these sections in the file are given below.
|
|
|
|
\begin{verbatim}
|
|
[loggers]
|
|
keys=root,log02,log03,log04,log05,log06,log07
|
|
|
|
[handlers]
|
|
keys=hand01,hand02,hand03,hand04,hand05,hand06,hand07,hand08,hand09
|
|
|
|
[formatters]
|
|
keys=form01,form02,form03,form04,form05,form06,form07,form08,form09
|
|
\end{verbatim}
|
|
|
|
The root logger must specify a level and a list of handlers. An
|
|
example of a root logger section is given below.
|
|
|
|
\begin{verbatim}
|
|
[logger_root]
|
|
level=NOTSET
|
|
handlers=hand01
|
|
\end{verbatim}
|
|
|
|
The \code{level} entry can be one of \code{DEBUG, INFO, WARNING,
|
|
ERROR, CRITICAL} or \code{NOTSET}. For the root logger only,
|
|
\code{NOTSET} means that all messages will be logged. Level values are
|
|
\function{eval()}uated in the context of the \code{logging} package's
|
|
namespace.
|
|
|
|
The \code{handlers} entry is a comma-separated list of handler names,
|
|
which must appear in the \code{[handlers]} section. These names must
|
|
appear in the \code{[handlers]} section and have corresponding
|
|
sections in the configuration file.
|
|
|
|
For loggers other than the root logger, some additional information is
|
|
required. This is illustrated by the following example.
|
|
|
|
\begin{verbatim}
|
|
[logger_parser]
|
|
level=DEBUG
|
|
handlers=hand01
|
|
propagate=1
|
|
qualname=compiler.parser
|
|
\end{verbatim}
|
|
|
|
The \code{level} and \code{handlers} entries are interpreted as for
|
|
the root logger, except that if a non-root logger's level is specified
|
|
as \code{NOTSET}, the system consults loggers higher up the hierarchy
|
|
to determine the effective level of the logger. The \code{propagate}
|
|
entry is set to 1 to indicate that messages must propagate to handlers
|
|
higher up the logger hierarchy from this logger, or 0 to indicate that
|
|
messages are \strong{not} propagated to handlers up the hierarchy. The
|
|
\code{qualname} entry is the hierarchical channel name of the logger,
|
|
that is to say the name used by the application to get the logger.
|
|
|
|
Sections which specify handler configuration are exemplified by the
|
|
following.
|
|
|
|
\begin{verbatim}
|
|
[handler_hand01]
|
|
class=StreamHandler
|
|
level=NOTSET
|
|
formatter=form01
|
|
args=(sys.stdout,)
|
|
\end{verbatim}
|
|
|
|
The \code{class} entry indicates the handler's class (as determined by
|
|
\function{eval()} in the \code{logging} package's namespace). The
|
|
\code{level} is interpreted as for loggers, and \code{NOTSET} is taken
|
|
to mean "log everything".
|
|
|
|
The \code{formatter} entry indicates the key name of the formatter for
|
|
this handler. If blank, a default formatter
|
|
(\code{logging._defaultFormatter}) is used. If a name is specified, it
|
|
must appear in the \code{[formatters]} section and have a
|
|
corresponding section in the configuration file.
|
|
|
|
The \code{args} entry, when \function{eval()}uated in the context of
|
|
the \code{logging} package's namespace, is the list of arguments to
|
|
the constructor for the handler class. Refer to the constructors for
|
|
the relevant handlers, or to the examples below, to see how typical
|
|
entries are constructed.
|
|
|
|
\begin{verbatim}
|
|
[handler_hand02]
|
|
class=FileHandler
|
|
level=DEBUG
|
|
formatter=form02
|
|
args=('python.log', 'w')
|
|
|
|
[handler_hand03]
|
|
class=handlers.SocketHandler
|
|
level=INFO
|
|
formatter=form03
|
|
args=('localhost', handlers.DEFAULT_TCP_LOGGING_PORT)
|
|
|
|
[handler_hand04]
|
|
class=handlers.DatagramHandler
|
|
level=WARN
|
|
formatter=form04
|
|
args=('localhost', handlers.DEFAULT_UDP_LOGGING_PORT)
|
|
|
|
[handler_hand05]
|
|
class=handlers.SysLogHandler
|
|
level=ERROR
|
|
formatter=form05
|
|
args=(('localhost', handlers.SYSLOG_UDP_PORT), handlers.SysLogHandler.LOG_USER)
|
|
|
|
[handler_hand06]
|
|
class=handlers.NTEventLogHandler
|
|
level=CRITICAL
|
|
formatter=form06
|
|
args=('Python Application', '', 'Application')
|
|
|
|
[handler_hand07]
|
|
class=handlers.SMTPHandler
|
|
level=WARN
|
|
formatter=form07
|
|
args=('localhost', 'from@abc', ['user1@abc', 'user2@xyz'], 'Logger Subject')
|
|
|
|
[handler_hand08]
|
|
class=handlers.MemoryHandler
|
|
level=NOTSET
|
|
formatter=form08
|
|
target=
|
|
args=(10, ERROR)
|
|
|
|
[handler_hand09]
|
|
class=handlers.HTTPHandler
|
|
level=NOTSET
|
|
formatter=form09
|
|
args=('localhost:9022', '/log', 'GET')
|
|
\end{verbatim}
|
|
|
|
Sections which specify formatter configuration are typified by the following.
|
|
|
|
\begin{verbatim}
|
|
[formatter_form01]
|
|
format=F1 %(asctime)s %(levelname)s %(message)s
|
|
datefmt=
|
|
\end{verbatim}
|
|
|
|
The \code{format} entry is the overall format string, and the
|
|
\code{datefmt} entry is the \function{strftime()}-compatible date/time format
|
|
string. If empty, the package substitutes ISO8601 format date/times, which
|
|
is almost equivalent to specifying the date format string "%Y-%m-%d %H:%M:%S".
|
|
The ISO8601 format also specifies milliseconds, which are appended to the
|
|
result of using the above format string, with a comma separator. An example
|
|
time in ISO8601 format is \code{2003-01-23 00:29:50,411}.
|