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