| # 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) |