| \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 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", |
| 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}. |