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