diff options
Diffstat (limited to 'Doc/lib/liblogging.tex')
-rw-r--r-- | Doc/lib/liblogging.tex | 1768 |
1 files changed, 0 insertions, 1768 deletions
diff --git a/Doc/lib/liblogging.tex b/Doc/lib/liblogging.tex deleted file mode 100644 index c5c3e4e..0000000 --- a/Doc/lib/liblogging.tex +++ /dev/null @@ -1,1768 +0,0 @@ -\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. - -The numeric values of logging levels are given in the following table. These -are primarily of interest if you want to define your own levels, and need -them to have specific values relative to the predefined levels. If you -define a level with the same numeric value, it overwrites the predefined -value; the predefined name is lost. - -\begin{tableii}{l|l}{code}{Level}{Numeric value} - \lineii{CRITICAL}{50} - \lineii{ERROR}{40} - \lineii{WARNING}{30} - \lineii{INFO}{20} - \lineii{DEBUG}{10} - \lineii{NOTSET}{0} -\end{tableii} - -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, a \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{BaseRotatingHandler} is the base class for handlers that -rotate log files at a certain point. It is not meant to be instantiated -directly. Instead, use \class{RotatingFileHandler} or -\class{TimedRotatingFileHandler}. - -\item \class{RotatingFileHandler} instances send error messages to disk -files, with support for maximum log file sizes and log file rotation. - -\item \class{TimedRotatingFileHandler} instances send error messages to -disk files rotating the log file at certain timed intervals. - -\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} using the string formatting -operator. (Note that this means that you can use keywords in the -format string, together with a single dictionary argument.) - -There are two keyword arguments in \var{kwargs} which are inspected: -\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. - -The other optional keyword argument is \var{extra} which can be used to pass -a dictionary which is used to populate the __dict__ of the LogRecord created -for the logging event with user-defined attributes. These custom attributes -can then be used as you like. For example, they could be incorporated into -logged messages. For example: - -\begin{verbatim} - FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s" - logging.basicConfig(format=FORMAT) - d = {'clientip': '192.168.0.1', 'user': 'fbloggs'} - logging.warning("Protocol problem: %s", "connection reset", extra=d) -\end{verbatim} - -would print something like -\begin{verbatim} -2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset -\end{verbatim} - -The keys in the dictionary passed in \var{extra} should not clash with the keys -used by the logging system. (See the \class{Formatter} documentation for more -information on which keys are used by the logging system.) - -If you choose to use these attributes in logged messages, you need to exercise -some care. In the above example, for instance, the \class{Formatter} has been -set up with a format string which expects 'clientip' and 'user' in the -attribute dictionary of the LogRecord. If these are missing, the message will -not be logged because a string formatting exception will occur. So in this -case, you always need to pass the \var{extra} dictionary with these keys. - -While this might be annoying, this feature is intended for use in specialized -circumstances, such as multi-threaded servers where the same code executes -in many contexts, and interesting conditions which arise are dependent on this -context (such as remote client IP address and authenticated user name, in the -above example). In such circumstances, it is likely that specialized -\class{Formatter}s would be used with particular \class{Handler}s. - -\versionchanged[\var{extra} was added]{2.5} - -\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}{\optional{**kwargs}} -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. - -\versionchanged[Formerly, \function{basicConfig} did not take any keyword -arguments]{2.4} - -The following keyword arguments are supported. - -\begin{tableii}{l|l}{code}{Format}{Description} -\lineii{filename}{Specifies that a FileHandler be created, using the -specified filename, rather than a StreamHandler.} -\lineii{filemode}{Specifies the mode to open the file, if filename is -specified (if filemode is unspecified, it defaults to 'a').} -\lineii{format}{Use the specified format string for the handler.} -\lineii{datefmt}{Use the specified date/time format.} -\lineii{level}{Set the root logger level to the specified level.} -\lineii{stream}{Use the specified stream to initialize the StreamHandler. -Note that this argument is incompatible with 'filename' - if both -are present, 'stream' is ignored.} -\end{tableii} - -\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{memberdesc}[Logger]{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{memberdesc} - -\begin{methoddesc}[Logger]{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 when the logger is the root logger, or delegation to the -parent when the logger is a non-root logger). Note that the root logger -is created with level \constant{WARNING}. - -The term "delegation to the parent" means that if a logger has a level -of NOTSET, its chain of ancestor loggers is traversed until either an -ancestor with a level other than NOTSET is found, or the root is -reached. - -If an ancestor is found with a level other than NOTSET, then that -ancestor's level is treated as the effective level of the logger where -the ancestor search began, and is used to determine how a logging -event is handled. - -If the root is reached, and it has a level of NOTSET, then all -messages will be processed. Otherwise, the root's level will be used -as the effective level. -\end{methoddesc} - -\begin{methoddesc}[Logger]{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}[Logger]{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}[Logger]{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} using the string formatting -operator. (Note that this means that you can use keywords in the -format string, together with a single dictionary argument.) - -There are two keyword arguments in \var{kwargs} which are inspected: -\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. - -The other optional keyword argument is \var{extra} which can be used to pass -a dictionary which is used to populate the __dict__ of the LogRecord created -for the logging event with user-defined attributes. These custom attributes -can then be used as you like. For example, they could be incorporated into -logged messages. For example: - -\begin{verbatim} - FORMAT = "%(asctime)-15s %(clientip)s %(user)-8s %(message)s" - logging.basicConfig(format=FORMAT) - dict = { 'clientip' : '192.168.0.1', 'user' : 'fbloggs' } - logger = logging.getLogger("tcpserver") - logger.warning("Protocol problem: %s", "connection reset", extra=d) -\end{verbatim} - -would print something like -\begin{verbatim} -2006-02-08 22:20:02,165 192.168.0.1 fbloggs Protocol problem: connection reset -\end{verbatim} - -The keys in the dictionary passed in \var{extra} should not clash with the keys -used by the logging system. (See the \class{Formatter} documentation for more -information on which keys are used by the logging system.) - -If you choose to use these attributes in logged messages, you need to exercise -some care. In the above example, for instance, the \class{Formatter} has been -set up with a format string which expects 'clientip' and 'user' in the -attribute dictionary of the LogRecord. If these are missing, the message will -not be logged because a string formatting exception will occur. So in this -case, you always need to pass the \var{extra} dictionary with these keys. - -While this might be annoying, this feature is intended for use in specialized -circumstances, such as multi-threaded servers where the same code executes -in many contexts, and interesting conditions which arise are dependent on this -context (such as remote client IP address and authenticated user name, in the -above example). In such circumstances, it is likely that specialized -\class{Formatter}s would be used with particular \class{Handler}s. - -\versionchanged[\var{extra} was added]{2.5} - -\end{methoddesc} - -\begin{methoddesc}[Logger]{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}[Logger]{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}[Logger]{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}[Logger]{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}[Logger]{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}[Logger]{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}[Logger]{addFilter}{filt} -Adds the specified filter \var{filt} to this logger. -\end{methoddesc} - -\begin{methoddesc}[Logger]{removeFilter}{filt} -Removes the specified filter \var{filt} from this logger. -\end{methoddesc} - -\begin{methoddesc}[Logger]{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}[Logger]{addHandler}{hdlr} -Adds the specified handler \var{hdlr} to this logger. -\end{methoddesc} - -\begin{methoddesc}[Logger]{removeHandler}{hdlr} -Removes the specified handler \var{hdlr} from this logger. -\end{methoddesc} - -\begin{methoddesc}[Logger]{findCaller}{} -Finds the caller's source filename and line number. Returns the filename, -line number and function name as a 3-element tuple. -\versionchanged[The function name was added. In earlier versions, the -filename and line number were returned as a 2-element tuple.]{2.5} -\end{methoddesc} - -\begin{methoddesc}[Logger]{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}[Logger]{makeRecord}{name, lvl, fn, lno, msg, args, exc_info - \optional{, func, extra}} -This is a factory method which can be overridden in subclasses to create -specialized \class{LogRecord} instances. -\versionchanged[\var{func} and \var{extra} were added]{2.5} -\end{methoddesc} - -\subsection{Basic example \label{minimal-example}} - -\versionchanged[formerly \function{basicConfig} did not take any keyword -arguments]{2.4} - -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 cPickle -import logging -import logging.handlers -import SocketServer -import struct - - -class LogRecordStreamHandler(SocketServer.StreamRequestHandler): - """Handler for a streaming logging request. - - This 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(SocketServer.ThreadingTCPServer): - """simple TCP socket-based logging receiver suitable for testing. - """ - - allow_reuse_address = 1 - - def __init__(self, host='localhost', - port=logging.handlers.DEFAULT_TCP_LOGGING_PORT, - handler=LogRecordStreamHandler): - SocketServer.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") - tcpserver = LogRecordSocketReceiver() - print "About to start TCP server..." - tcpserver.serve_until_stopped() - -if __name__ == "__main__": - main() -\end{verbatim} - -First run the server, and then the client. On the client side, nothing is -printed on the console; on the server side, you should see something like: - -\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}[Handler]{__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}[Handler]{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}[Handler]{acquire}{} -Acquires the thread lock created with \method{createLock()}. -\end{methoddesc} - -\begin{methoddesc}[Handler]{release}{} -Releases the thread lock acquired with \method{acquire()}. -\end{methoddesc} - -\begin{methoddesc}[Handler]{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}[Handler]{setFormatter}{form} -Sets the \class{Formatter} for this handler to \var{form}. -\end{methoddesc} - -\begin{methoddesc}[Handler]{addFilter}{filt} -Adds the specified filter \var{filt} to this handler. -\end{methoddesc} - -\begin{methoddesc}[Handler]{removeFilter}{filt} -Removes the specified filter \var{filt} from this handler. -\end{methoddesc} - -\begin{methoddesc}[Handler]{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}[Handler]{flush}{} -Ensure all logging output has been flushed. This version does -nothing and is intended to be implemented by subclasses. -\end{methoddesc} - -\begin{methoddesc}[Handler]{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}[Handler]{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}[Handler]{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}[Handler]{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}[Handler]{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, located in the core \module{logging} -package, 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, located in the core \module{logging} -package, sends logging output to a disk file. It inherits the output -functionality from \class{StreamHandler}. - -\begin{classdesc}{FileHandler}{filename\optional{, mode\optional{, encoding}}} -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. If \var{encoding} is not \var{None}, -it is used to open the file with that encoding. 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{WatchedFileHandler} - -\versionadded{2.6} -The \class{WatchedFileHandler} class, located in the \module{logging.handlers} -module, is a \class{FileHandler} which watches the file it is logging to. -If the file changes, it is closed and reopened using the file name. - -A file change can happen because of usage of programs such as \var{newsyslog} -and \var{logrotate} which perform log file rotation. This handler, intended -for use under Unix/Linux, watches the file to see if it has changed since the -last emit. (A file is deemed to have changed if its device or inode have -changed.) If the file has changed, the old file stream is closed, and the file -opened to get a 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, -\var{ST_INO} is not supported under Windows; \function{stat()} always returns -zero for this value. - -\begin{classdesc}{WatchedFileHandler}{filename\optional{,mode\optional{, - encoding}}} -Returns a new instance of the \class{WatchedFileHandler} class. The specified -file is opened and used as the stream for logging. If \var{mode} is -not specified, \constant{'a'} is used. If \var{encoding} is not \var{None}, -it is used to open the file with that encoding. By default, the file grows -indefinitely. -\end{classdesc} - -\begin{methoddesc}{emit}{record} -Outputs the record to the file, but first checks to see if the file has -changed. If it has, the existing stream is flushed and closed and the file -opened again, before outputting the record to the file. -\end{methoddesc} - -\subsubsection{RotatingFileHandler} - -The \class{RotatingFileHandler} class, located in the \module{logging.handlers} -module, 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 previously. -\end{methoddesc} - -\subsubsection{TimedRotatingFileHandler} - -The \class{TimedRotatingFileHandler} class, located in the -\module{logging.handlers} module, supports rotation of disk log files -at certain timed intervals. - -\begin{classdesc}{TimedRotatingFileHandler}{filename - \optional{,when - \optional{,interval - \optional{,backupCount}}}} - -Returns a new instance of the \class{TimedRotatingFileHandler} class. The -specified file is opened and used as the stream for logging. On rotating -it also sets the filename suffix. Rotating happens based on the product -of \var{when} and \var{interval}. - -You can use the \var{when} to specify the type of \var{interval}. The -list of possible values is, note that they are not case sensitive: - -\begin{tableii}{l|l}{}{Value}{Type of interval} - \lineii{S}{Seconds} - \lineii{M}{Minutes} - \lineii{H}{Hours} - \lineii{D}{Days} - \lineii{W}{Week day (0=Monday)} - \lineii{midnight}{Roll over at midnight} -\end{tableii} - -If \var{backupCount} is non-zero, the system will save old log files by -appending extensions to the filename. The extensions are date-and-time -based, using the strftime format \code{\%Y-\%m-\%d_\%H-\%M-\%S} or a leading -portion thereof, depending on the rollover interval. At most \var{backupCount} -files will be kept, and if more would be created when rollover occurs, the -oldest one is deleted. -\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 -above. -\end{methoddesc} - -\subsubsection{SocketHandler} - -The \class{SocketHandler} class, located in the -\module{logging.handlers} module, 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}{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, located in the -\module{logging.handlers} module, 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, located in the -\module{logging.handlers} module, 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. An alternative to providing -a \code{(\var{host}, \var{port})} tuple is providing an address as a string, -for example "/dev/log". In this case, a Unix domain socket is used to send -the message to the syslog. 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, located in the -\module{logging.handlers} module, 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, located in the -\module{logging.handlers} module, supports sending logging messages to -an email address via SMTP. - -\begin{classdesc}{SMTPHandler}{mailhost, fromaddr, toaddrs, subject\optional{, - credentials}} -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. 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. If your SMTP server requires authentication, you can specify a -(username, password) tuple for the \var{credentials} argument. -\versionchanged[\var{credentials} was added]{2.6} -\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} class, located in the -\module{logging.handlers} module, 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, located in the -\module{logging.handlers} module, 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. -The \var{host} can be of the form \code{host:port}, should you need to -use a specific port number. 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{\%(funcName)s} {Name of function containing the logging call.} -\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{\%(relativeCreated)d} {Time in milliseconds when the LogRecord was - created, relative to the time the logging module was - loaded.} -\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{\%(threadName)s} {Thread name (if available).} -\lineii{\%(process)d} {Process ID (if available).} -\lineii{\%(message)s} {The logged message, computed as \code{msg \% args}.} -\end{tableii} - -\versionchanged[\var{funcName} was added]{2.5} - -\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. - -\begin{classdesc}{LogRecord}{name, lvl, pathname, lineno, msg, args, - exc_info \optional{, func}} -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). The \var{func} is the name of the function from which the -logging call was made. If not specified, it defaults to \code{None}. -\versionchanged[\var{func} was added]{2.5} -\end{classdesc} - -\begin{methoddesc}{getMessage}{} -Returns the message for this \class{LogRecord} instance after merging any -user-supplied arguments with the message. -\end{methoddesc} - -\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 configure the logging module. They are located in the -\module{logging.config} module. Their use is optional --- you can configure -the logging module using these functions or 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()}. To send a configuration -to the socket, read in the configuration file and send it to the socket -as a string of bytes preceded by a four-byte length packed in binary using -struct.\code{pack('>L', n)}. -\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= -class=logging.Formatter -\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}. - -The \code{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. |