83 lines
2.6 KiB
Python
83 lines
2.6 KiB
Python
|
# Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
||
|
# Use of this source code is governed by a BSD-style license that can be
|
||
|
# found in the LICENSE file.
|
||
|
|
||
|
''' Utility functions and objects for logging.
|
||
|
'''
|
||
|
|
||
|
import logging
|
||
|
import sys
|
||
|
|
||
|
class StdoutStderrHandler(logging.Handler):
|
||
|
''' Subclass of logging.Handler which outputs to either stdout or stderr
|
||
|
based on a threshold level.
|
||
|
'''
|
||
|
|
||
|
def __init__(self, threshold=logging.WARNING, err=sys.stderr, out=sys.stdout):
|
||
|
''' Args:
|
||
|
threshold: below this logging level messages are sent to stdout,
|
||
|
otherwise they are sent to stderr
|
||
|
err: a stream object that error messages are sent to, defaults to
|
||
|
sys.stderr
|
||
|
out: a stream object that non-error messages are sent to, defaults to
|
||
|
sys.stdout
|
||
|
'''
|
||
|
logging.Handler.__init__(self)
|
||
|
self._err = logging.StreamHandler(err)
|
||
|
self._out = logging.StreamHandler(out)
|
||
|
self._threshold = threshold
|
||
|
self._last_was_err = False
|
||
|
|
||
|
def setLevel(self, lvl):
|
||
|
logging.Handler.setLevel(self, lvl)
|
||
|
self._err.setLevel(lvl)
|
||
|
self._out.setLevel(lvl)
|
||
|
|
||
|
def setFormatter(self, formatter):
|
||
|
logging.Handler.setFormatter(self, formatter)
|
||
|
self._err.setFormatter(formatter)
|
||
|
self._out.setFormatter(formatter)
|
||
|
|
||
|
def emit(self, record):
|
||
|
if record.levelno < self._threshold:
|
||
|
self._out.emit(record)
|
||
|
self._last_was_err = False
|
||
|
else:
|
||
|
self._err.emit(record)
|
||
|
self._last_was_err = False
|
||
|
|
||
|
def flush(self):
|
||
|
# preserve order on the flushing, the stalest stream gets flushed first
|
||
|
if self._last_was_err:
|
||
|
self._out.flush()
|
||
|
self._err.flush()
|
||
|
else:
|
||
|
self._err.flush()
|
||
|
self._out.flush()
|
||
|
|
||
|
|
||
|
FORMAT = "%(asctime)s %(filename)s [%(levelname)s] %(message)s"
|
||
|
DATEFMT = "%H:%M:%S"
|
||
|
|
||
|
def config_root(level=logging.INFO, threshold=logging.WARNING, format=FORMAT,
|
||
|
datefmt=DATEFMT):
|
||
|
''' Configure the root logger to use a StdoutStderrHandler and some default
|
||
|
formatting.
|
||
|
Args:
|
||
|
level: messages below this level are ignored
|
||
|
threshold: below this logging level messages are sent to stdout,
|
||
|
otherwise they are sent to stderr
|
||
|
format: format for log messages, see logger.Format
|
||
|
datefmt: format for date in log messages
|
||
|
|
||
|
'''
|
||
|
# to set the handler of the root logging object, we need to do setup
|
||
|
# manually rather than using basicConfig
|
||
|
root = logging.getLogger()
|
||
|
root.setLevel(level)
|
||
|
formatter = logging.Formatter(format, datefmt)
|
||
|
handler = StdoutStderrHandler(threshold=threshold)
|
||
|
handler.setLevel(level)
|
||
|
handler.setFormatter(formatter)
|
||
|
root.addHandler(handler)
|