Welcome, guest | Sign In | My Account | Store | Cart

Creation of log message handler for the logging module is often a multi-step process, involving creation of the handler object, configuration of the message levels and formats, installation of any filters and then actual connection of the handler to the relevant logger object.

This helper function allows all of these things to be specified up front in a single function call, which then takes care of configuring the handler object appropriately.

Python, 51 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from logging import Formatter, FileHandler, StreamHandler, getLogger
def addHandler(*, handler=None, stream=None, filename=None, filemode='a',
                  format=None, datefmt=None, style='{',
                  level=None, max_level=None, filters=(),
                  logger=None):
    """stream, filename, filemode, format, datefmt: as per logging.basicConfig

       handler: use a precreated handler instead of creating a new one
       logger: logger to add the handler to (uses root logger if none specified)
       filters: an iterable of filters to add to the handler
       level: only messages of this level and above will be processed
       max_level: only messages of this level and below will be processed
       style: as per logging.basicConfig, but defaults to '{' (i.e. str.format)
    """
    # Create the handler if one hasn't been passed in
    if handler is None:
        if filename is not None:
            handler = FileHandler(filename, filemode)
        else:
            handler = StreamHandler(stream)
    # Set up the formatting of the log messages
    # New API, so it can default to str.format instead of %-formatting
    formatter = Formatter(format, datefmt, style)
    handler.setFormatter(formatter)
    # Set up filtering of which messages to handle
    if level is not None:
        handler.setLevel(level)
    if max_level is not None:
        def level_ok(record):
            return record.levelno <= max_level
        handler.addFilter(level_ok)
    for filter in filters:
        handler.addFilter(filter)
    # Add the fully configured handler to the specified logger
    if logger is None:
        logger = getLogger()
    logger.addHandler(handler)
    return handler

# Example of setting up the logging module to direct raw output to
# sys.stdout and sys.stderr as appropriate
import sys, logging
# Let root logger handlers see all messages
logging.getLogger().setLevel(logging.NOTSET)
# Send WARNING and above to stderr
addHandler(stream=sys.stderr, level=logging.WARNING)
# Send INFO to stdout
addHandler(stream=sys.stdout, level=logging.INFO, max_level=logging.INFO)

logging.info("Hello world!") # only displayed once
logging.warn("Hello world!") # only displayed once

The basic API was inspired by logging.basicConfig as part of a python-dev discussion on getting the logging module to emit info() messages on sys.stdout and warning() or higher messages on sys.stderr.

This version of the recipe is for Python 3.2. For a Python 2.7 compatible version, see http://code.activestate.com/recipes/577731-simple-creation-configuration-and-installation-of-/