# 8 PEP 282: The logging Package

A standard package for writing logs, `logging`, has been added to Python 2.3. It provides a powerful and flexible mechanism for generating logging output which can then be filtered and processed in various ways. A configuration file written in a standard format can be used to control the logging behavior of a program. Python includes handlers that will write log records to standard error or to a file or socket, send them to the system log, or even e-mail them to a particular address; of course, it's also possible to write your own handler classes.

The `Logger` class is the primary class. Most application code will deal with one or more `Logger` objects, each one used by a particular subsystem of the application. Each `Logger` is identified by a name, and names are organized into a hierarchy using "`.`" as the component separator. For example, you might have `Logger` instances named "`server`", "`server.auth`" and "`server.network`". The latter two instances are below "`server`" in the hierarchy. This means that if you turn up the verbosity for "`server`" or direct "`server`"messages to a different handler, the changes will also apply to records logged to "`server.auth`" and "`server.network`". There's also a root `Logger` that's the parent of all other loggers.

For simple uses, the `logging` package contains some convenience functions that always use the root log:

    import logging

    logging.debug('Debugging information')
    logging.info('Informational message')
    logging.warning('Warning:config file %s not found', 'server.conf')
    logging.error('Error occurred')
    logging.critical('Critical error -- shutting down')

This produces the following output:

    WARNING:root:Warning:config file server.conf not found
    ERROR:root:Error occurred
    CRITICAL:root:Critical error -- shutting down

In the default configuration, informational and debugging messages are suppressed and the output is sent to standard error. You can enable the display of informational and debugging messages by calling the `setLevel()` method on the root logger.

Notice the `warning()` call's use of string formatting operators; all of the functions for logging messages take the arguments `(msg, arg1, arg2, ...)` and log the string resulting from `msg % (arg1, arg2, ...)`.

There's also an `exception()` function that records the most recent traceback. Any of the other functions will also record the traceback if you specify a true value for the keyword argument exc_info.

    def f():
        try:    1/0
        except: logging.exception('Problem recorded')

    f()

This produces the following output:

    ERROR:root:Problem recorded
    Traceback (most recent call last):
      File "t.py", line 6, in f
        1/0
    ZeroDivisionError: integer division or modulo by zero

Slightly more advanced programs will use a logger other than the root logger. The `getLogger(name)` function is used to get a particular log, creating it if it doesn't exist yet. `getLogger(None)` returns the root logger.

    log = logging.getLogger('server')
     ...
    log.info('Listening on port %i', port)
     ...
    log.critical('Disk full')
     ...

Log records are usually propagated up the hierarchy, so a message logged to "`server.auth`" is also seen by "`server`" and "`root`", but a `Logger` can prevent this by setting its `propagate` attribute to `False`.

There are more classes provided by the `logging` package that can be customized. When a `Logger` instance is told to log a message, it creates a `LogRecord` instance that is sent to any number of different `Handler` instances. Loggers and handlers can also have an attached list of filters, and each filter can cause the `LogRecord` to be ignored or can modify the record before passing it along. When they're finally output, `LogRecord` instances are converted to text by a `Formatter` class. All of these classes can be replaced by your own specially-written classes.

With all of these features the `logging` package should provide enough flexibility for even the most complicated applications. This is only an incomplete overview of its features, so please see the package's reference documentation for all of the details. Reading PEP 282 will also be helpful.

See Also:

PEP 282, A Logging System
  Written by Vinay Sajip and Trent Mick; implemented by Vinay Sajip.