Home | History | Annotate | Download | only in google
      1 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 ''' Utility functions and objects for logging.
      6 '''
      7 
      8 import logging
      9 import sys
     10 
     11 class StdoutStderrHandler(logging.Handler):
     12   ''' Subclass of logging.Handler which outputs to either stdout or stderr
     13   based on a threshold level.
     14   '''
     15 
     16   def __init__(self, threshold=logging.WARNING, err=sys.stderr, out=sys.stdout):
     17     ''' Args:
     18           threshold: below this logging level messages are sent to stdout,
     19             otherwise they are sent to stderr
     20           err: a stream object that error messages are sent to, defaults to
     21             sys.stderr
     22           out: a stream object that non-error messages are sent to, defaults to
     23             sys.stdout
     24     '''
     25     logging.Handler.__init__(self)
     26     self._err = logging.StreamHandler(err)
     27     self._out = logging.StreamHandler(out)
     28     self._threshold = threshold
     29     self._last_was_err = False
     30 
     31   def setLevel(self, lvl):
     32     logging.Handler.setLevel(self, lvl)
     33     self._err.setLevel(lvl)
     34     self._out.setLevel(lvl)
     35 
     36   def setFormatter(self, formatter):
     37     logging.Handler.setFormatter(self, formatter)
     38     self._err.setFormatter(formatter)
     39     self._out.setFormatter(formatter)
     40 
     41   def emit(self, record):
     42     if record.levelno < self._threshold:
     43       self._out.emit(record)
     44       self._last_was_err = False
     45     else:
     46       self._err.emit(record)
     47       self._last_was_err = False
     48 
     49   def flush(self):
     50     # preserve order on the flushing, the stalest stream gets flushed first
     51     if self._last_was_err:
     52       self._out.flush()
     53       self._err.flush()
     54     else:
     55       self._err.flush()
     56       self._out.flush()
     57 
     58 
     59 FORMAT = "%(asctime)s %(filename)s [%(levelname)s] %(message)s"
     60 DATEFMT = "%H:%M:%S"
     61 
     62 def config_root(level=logging.INFO, threshold=logging.WARNING, format=FORMAT,
     63          datefmt=DATEFMT):
     64   ''' Configure the root logger to use a StdoutStderrHandler and some default
     65   formatting.
     66     Args:
     67       level: messages below this level are ignored
     68       threshold: below this logging level messages are sent to stdout,
     69         otherwise they are sent to stderr
     70       format: format for log messages, see logger.Format
     71       datefmt: format for date in log messages
     72 
     73   '''
     74   # to set the handler of the root logging object, we need to do setup
     75   # manually rather than using basicConfig
     76   root = logging.getLogger()
     77   root.setLevel(level)
     78   formatter = logging.Formatter(format, datefmt)
     79   handler = StdoutStderrHandler(threshold=threshold)
     80   handler.setLevel(level)
     81   handler.setFormatter(formatter)
     82   root.addHandler(handler)
     83