10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Copyright 2001-2012 by Vinay Sajip. All Rights Reserved.
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Permission to use, copy, modify, and distribute this software and its
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# documentation for any purpose and without fee is hereby granted,
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# provided that the above copyright notice appear in all copies and that
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# both that copyright notice and this permission notice appear in
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# supporting documentation, and that the name of Vinay Sajip
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# not be used in advertising or publicity pertaining to distribution
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# of the software without specific, written prior permission.
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""
180a8c90248264a8b26970b4473770bcc3df8515fJosh GaoLogging package for Python. Based on PEP 282 and comments thereto in
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gaocomp.lang.python.
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
210a8c90248264a8b26970b4473770bcc3df8515fJosh GaoCopyright (C) 2001-2012 Vinay Sajip. All Rights Reserved.
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
230a8c90248264a8b26970b4473770bcc3df8515fJosh GaoTo use, simply 'import logging' and log away!
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys, os, time, cStringIO, traceback, warnings, weakref
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao           'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO',
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao           'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler',
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao           'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig',
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao           'captureWarnings', 'critical', 'debug', 'disable', 'error',
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao           'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass',
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao           'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning']
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry:
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    import codecs
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept ImportError:
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    codecs = None
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry:
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    import thread
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    import threading
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept ImportError:
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    thread = None
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__author__  = "Vinay Sajip <vinay_sajip@red-dove.com>"
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__status__  = "production"
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__version__ = "0.5.1.2"
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__date__    = "07 February 2010"
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   Miscellaneous module data
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gaotry:
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    unicode
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _unicode = True
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoexcept NameError:
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _unicode = False
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# _srcfile is used when walking the stack to check when we've got the first
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# caller stack frame.
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif hasattr(sys, 'frozen'): #support for py2exe
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoelif __file__[-4:].lower() in ['.pyc', '.pyo']:
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _srcfile = __file__[:-4] + '.py'
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoelse:
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _srcfile = __file__
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_srcfile = os.path.normcase(_srcfile)
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# next bit filched from 1.5.2's inspect.py
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef currentframe():
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """Return the frame object for the caller's stack frame."""
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise Exception
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    except:
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return sys.exc_info()[2].tb_frame.f_back
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# done filching
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# _srcfile is only used in conjunction with sys._getframe().
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# To provide compatibility with older versions of Python, set _srcfile
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# to None if _getframe() is not available; this value will prevent
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# findCaller() from being called.
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#if not hasattr(sys, "_getframe"):
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#    _srcfile = None
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#_startTime is used as the base when calculating the relative time of events
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_startTime = time.time()
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#raiseExceptions is used to see if exceptions during handling should be
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#propagated
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
1000a8c90248264a8b26970b4473770bcc3df8515fJosh GaoraiseExceptions = 1
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# If you don't want threading information in the log, set this to zero
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
1050a8c90248264a8b26970b4473770bcc3df8515fJosh GaologThreads = 1
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# If you don't want multiprocessing information in the log, set this to zero
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
1100a8c90248264a8b26970b4473770bcc3df8515fJosh GaologMultiprocessing = 1
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# If you don't want process information in the log, set this to zero
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
1150a8c90248264a8b26970b4473770bcc3df8515fJosh GaologProcesses = 1
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   Level related stuff
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Default levels and level names, these can be replaced with any positive set
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# of values having corresponding names. There is a pseudo-level, NOTSET, which
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# is only really there as a lower limit for user-defined levels. Handlers and
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# loggers are initialized with NOTSET so that they will log all messages, even
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# at user-defined levels.
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1280a8c90248264a8b26970b4473770bcc3df8515fJosh GaoCRITICAL = 50
1290a8c90248264a8b26970b4473770bcc3df8515fJosh GaoFATAL = CRITICAL
1300a8c90248264a8b26970b4473770bcc3df8515fJosh GaoERROR = 40
1310a8c90248264a8b26970b4473770bcc3df8515fJosh GaoWARNING = 30
1320a8c90248264a8b26970b4473770bcc3df8515fJosh GaoWARN = WARNING
1330a8c90248264a8b26970b4473770bcc3df8515fJosh GaoINFO = 20
1340a8c90248264a8b26970b4473770bcc3df8515fJosh GaoDEBUG = 10
1350a8c90248264a8b26970b4473770bcc3df8515fJosh GaoNOTSET = 0
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_levelNames = {
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    CRITICAL : 'CRITICAL',
1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    ERROR : 'ERROR',
1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    WARNING : 'WARNING',
1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    INFO : 'INFO',
1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    DEBUG : 'DEBUG',
1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    NOTSET : 'NOTSET',
1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    'CRITICAL' : CRITICAL,
1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    'ERROR' : ERROR,
1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    'WARN' : WARNING,
1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    'WARNING' : WARNING,
1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    'INFO' : INFO,
1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    'DEBUG' : DEBUG,
1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    'NOTSET' : NOTSET,
1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao}
1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getLevelName(level):
1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Return the textual representation of logging level 'level'.
1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    INFO, DEBUG) then you get the corresponding string. If you have
1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    associated levels with names using addLevelName then the name you have
1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    associated with 'level' is returned.
1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    If a numeric value corresponding to one of the defined levels is passed
1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    in, the corresponding string representation is returned.
1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Otherwise, the string "Level %s" % level is returned.
1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return _levelNames.get(level, ("Level %s" % level))
1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef addLevelName(level, levelName):
1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Associate 'levelName' with 'level'.
1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    This is used when converting levels to text during message formatting.
1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _acquireLock()
1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:    #unlikely to cause an exception, but you never know...
1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _levelNames[level] = levelName
1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _levelNames[levelName] = level
1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    finally:
1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _releaseLock()
1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef _checkLevel(level):
1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if isinstance(level, (int, long)):
1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rv = level
1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    elif str(level) == level:
1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if level not in _levelNames:
1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise ValueError("Unknown level: %r" % level)
1880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rv = _levelNames[level]
1890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
1900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise TypeError("Level not an integer or a valid string: %r" % level)
1910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return rv
1920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
1940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   Thread-related stuff
1950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
1960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
1980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#_lock is used to serialize access to shared data structures in this module.
1990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#This needs to be an RLock because fileConfig() creates and configures
2000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#Handlers, and so might arbitrary user threads. Since Handler code updates the
2010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#shared dictionary _handlers, it needs to acquire the lock. But if configuring,
2020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#the lock would already have been acquired - so we need an RLock.
2030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#The same argument applies to Loggers and Manager.loggerDict.
2040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
2050a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif thread:
2060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _lock = threading.RLock()
2070a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoelse:
2080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _lock = None
2090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef _acquireLock():
2110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
2120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Acquire the module-level lock for serializing access to shared data.
2130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    This should be released with _releaseLock().
2150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
2160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if _lock:
2170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _lock.acquire()
2180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2190a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef _releaseLock():
2200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
2210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Release the module-level lock acquired by calling _acquireLock().
2220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
2230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if _lock:
2240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _lock.release()
2250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
2270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   The logging record
2280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
2290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2300a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass LogRecord(object):
2310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
2320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    A LogRecord instance represents an event being logged.
2330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
2340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    LogRecord instances are created every time something is logged. They
2350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    contain all the information pertinent to the event being logged. The
2360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    main information passed in is in msg and args, which are combined
2370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    using str(msg) % args to create the message field of the record. The
2380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    record also includes information such as when the record was created,
2390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    the source line where the logging call was made, and any exception
2400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    information to be logged.
2410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
2420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, name, level, pathname, lineno,
2430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                 msg, args, exc_info, func=None):
2440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
2450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initialize a logging record with interesting information.
2460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
2470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ct = time.time()
2480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.name = name
2490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.msg = msg
2500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #
2510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # The following statement allows passing of a dictionary as a sole
2520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # argument, so that you can do something like
2530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #  logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
2540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Suggested by Stefan Behnel.
2550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Note that without the test for args[0], we get a problem because
2560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # during formatting, we test to see if the arg is present using
2570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
2580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # and if the passed arg fails 'if self.args:' then no formatting
2590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # is done. For example, logger.warn('Value is %d', 0) would log
2600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # 'Value is %d' instead of 'Value is 0'.
2610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # For the use case of passing a dictionary, this should not be a
2620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # problem.
2630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if args and len(args) == 1 and isinstance(args[0], dict) and args[0]:
2640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            args = args[0]
2650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.args = args
2660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.levelname = getLevelName(level)
2670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.levelno = level
2680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.pathname = pathname
2690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
2700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.filename = os.path.basename(pathname)
2710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.module = os.path.splitext(self.filename)[0]
2720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except (TypeError, ValueError, AttributeError):
2730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.filename = pathname
2740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.module = "Unknown module"
2750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.exc_info = exc_info
2760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.exc_text = None      # used to cache the traceback text
2770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.lineno = lineno
2780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.funcName = func
2790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.created = ct
2800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.msecs = (ct - long(ct)) * 1000
2810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.relativeCreated = (self.created - _startTime) * 1000
2820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if logThreads and thread:
2830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.thread = thread.get_ident()
2840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.threadName = threading.current_thread().name
2850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
2860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.thread = None
2870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.threadName = None
2880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not logMultiprocessing:
2890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.processName = None
2900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
2910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.processName = 'MainProcess'
2920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            mp = sys.modules.get('multiprocessing')
2930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if mp is not None:
2940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Errors may occur if multiprocessing has not finished loading
2950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # yet - e.g. if a custom import hook causes third-party code
2960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # to run when multiprocessing calls import. See issue 8200
2970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # for an example
2980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                try:
2990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.processName = mp.current_process().name
3000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                except StandardError:
3010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    pass
3020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if logProcesses and hasattr(os, 'getpid'):
3030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.process = os.getpid()
3040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
3050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.process = None
3060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __str__(self):
3080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
3090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.pathname, self.lineno, self.msg)
3100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def getMessage(self):
3120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
3130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Return the message for this LogRecord.
3140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Return the message for this LogRecord after merging any user-supplied
3160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        arguments with the message.
3170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
3180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not _unicode: #if no unicode support...
3190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            msg = str(self.msg)
3200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
3210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            msg = self.msg
3220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not isinstance(msg, basestring):
3230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                try:
3240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    msg = str(self.msg)
3250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                except UnicodeError:
3260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    msg = self.msg      #Defer encoding till later
3270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.args:
3280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            msg = msg % self.args
3290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return msg
3300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3310a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef makeLogRecord(dict):
3320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
3330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Make a LogRecord whose attributes are defined by the specified dictionary,
3340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    This function is useful for converting a logging event received over
3350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    a socket connection (which is sent as a dictionary) into a LogRecord
3360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    instance.
3370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
3380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    rv = LogRecord(None, None, "", 0, "", (), None, None)
3390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    rv.__dict__.update(dict)
3400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return rv
3410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
3430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   Formatter classes and functions
3440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
3450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3460a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass Formatter(object):
3470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
3480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Formatter instances are used to convert a LogRecord to text.
3490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Formatters need to know how a LogRecord is constructed. They are
3510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    responsible for converting a LogRecord to (usually) a string which can
3520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    be interpreted by either a human or an external system. The base Formatter
3530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    allows a formatting string to be specified. If none is supplied, the
3540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    default value of "%s(message)\\n" is used.
3550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    The Formatter can be initialized with a format string which makes use of
3570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    knowledge of the LogRecord attributes - e.g. the default value mentioned
3580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    above makes use of the fact that the user's message and arguments are pre-
3590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    formatted into a LogRecord's message attribute. Currently, the useful
3600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    attributes in a LogRecord are described by:
3610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(name)s            Name of the logger (logging channel)
3630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(levelno)s         Numeric logging level for the message (DEBUG, INFO,
3640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        WARNING, ERROR, CRITICAL)
3650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(levelname)s       Text logging level for the message ("DEBUG", "INFO",
3660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        "WARNING", "ERROR", "CRITICAL")
3670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(pathname)s        Full pathname of the source file where the logging
3680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        call was issued (if available)
3690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(filename)s        Filename portion of pathname
3700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(module)s          Module (name portion of filename)
3710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(lineno)d          Source line number where the logging call was issued
3720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        (if available)
3730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(funcName)s        Function name
3740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(created)f         Time when the LogRecord was created (time.time()
3750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        return value)
3760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(asctime)s         Textual time when the LogRecord was created
3770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(msecs)d           Millisecond portion of the creation time
3780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(relativeCreated)d Time in milliseconds when the LogRecord was created,
3790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        relative to the time the logging module was loaded
3800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        (typically at application startup time)
3810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(thread)d          Thread ID (if available)
3820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(threadName)s      Thread name (if available)
3830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(process)d         Process ID (if available)
3840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    %(message)s         The result of record.getMessage(), computed just as
3850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        the record is emitted
3860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
3870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    converter = time.localtime
3890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, fmt=None, datefmt=None):
3910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
3920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initialize the formatter with specified format strings.
3930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
3940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initialize the formatter either with the specified format string, or a
3950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        default as described above. Allow for specialized date formatting with
3960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        the optional datefmt argument (if omitted, you get the ISO8601 format).
3970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
3980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if fmt:
3990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self._fmt = fmt
4000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
4010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self._fmt = "%(message)s"
4020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.datefmt = datefmt
4030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def formatTime(self, record, datefmt=None):
4050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
4060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Return the creation time of the specified LogRecord as formatted text.
4070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        This method should be called from format() by a formatter which
4090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        wants to make use of a formatted time. This method can be overridden
4100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        in formatters to provide for any specific requirement, but the
4110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        basic behaviour is as follows: if datefmt (a string) is specified,
4120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        it is used with time.strftime() to format the creation time of the
4130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        record. Otherwise, the ISO8601 format is used. The resulting
4140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        string is returned. This function uses a user-configurable function
4150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        to convert the creation time to a tuple. By default, time.localtime()
4160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        is used; to change this for a particular formatter instance, set the
4170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        'converter' attribute to a function with the same signature as
4180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        time.localtime() or time.gmtime(). To change it for all formatters,
4190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for example if you want all logging times to be shown in GMT,
4200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        set the 'converter' attribute in the Formatter class.
4210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
4220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        ct = self.converter(record.created)
4230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if datefmt:
4240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            s = time.strftime(datefmt, ct)
4250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
4260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
4270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            s = "%s,%03d" % (t, record.msecs)
4280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return s
4290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def formatException(self, ei):
4310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
4320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Format and return the specified exception information as a string.
4330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        This default implementation just uses
4350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        traceback.print_exception()
4360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
4370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sio = cStringIO.StringIO()
4380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
4390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        s = sio.getvalue()
4400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        sio.close()
4410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if s[-1:] == "\n":
4420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            s = s[:-1]
4430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return s
4440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def usesTime(self):
4460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
4470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Check if the format uses the creation time of the record.
4480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
4490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self._fmt.find("%(asctime)") >= 0
4500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def format(self, record):
4520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
4530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Format the specified record as text.
4540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        The record's attribute dictionary is used as the operand to a
4560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        string formatting operation which yields the returned string.
4570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Before formatting the dictionary, a couple of preparatory steps
4580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        are carried out. The message attribute of the record is computed
4590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        using LogRecord.getMessage(). If the formatting string uses the
4600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        time (as determined by a call to usesTime(), formatTime() is
4610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        called to format the event time. If there is exception information,
4620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        it is formatted using formatException() and appended to the message.
4630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
4640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        record.message = record.getMessage()
4650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.usesTime():
4660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            record.asctime = self.formatTime(record, self.datefmt)
4670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        s = self._fmt % record.__dict__
4680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if record.exc_info:
4690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Cache the traceback text to avoid converting it multiple times
4700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # (it's constant anyway)
4710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not record.exc_text:
4720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                record.exc_text = self.formatException(record.exc_info)
4730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if record.exc_text:
4740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if s[-1:] != "\n":
4750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                s = s + "\n"
4760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
4770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                s = s + record.exc_text
4780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except UnicodeError:
4790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Sometimes filenames have non-ASCII chars, which can lead
4800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # to errors when s is Unicode and record.exc_text is str
4810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # See issue 8924.
4820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # We also use replace for when there are multiple
4830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # encodings, e.g. UTF-8 for the filesystem and latin-1
4840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # for a script. See issue 13232.
4850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                s = s + record.exc_text.decode(sys.getfilesystemencoding(),
4860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                               'replace')
4870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return s
4880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
4900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   The default formatter to use when no other is specified
4910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
4920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_defaultFormatter = Formatter()
4930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
4940a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass BufferingFormatter(object):
4950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
4960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    A formatter suitable for formatting a number of records.
4970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
4980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, linefmt=None):
4990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Optionally specify a formatter which will be used to format each
5010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        individual record.
5020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if linefmt:
5040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.linefmt = linefmt
5050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
5060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.linefmt = _defaultFormatter
5070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def formatHeader(self, records):
5090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Return the header string for the specified records.
5110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return ""
5130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def formatFooter(self, records):
5150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Return the footer string for the specified records.
5170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return ""
5190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def format(self, records):
5210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Format the specified records and return the result as a string.
5230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rv = ""
5250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if len(records) > 0:
5260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            rv = rv + self.formatHeader(records)
5270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for record in records:
5280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                rv = rv + self.linefmt.format(record)
5290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            rv = rv + self.formatFooter(records)
5300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return rv
5310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
5330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   Filter classes and functions
5340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
5350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5360a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass Filter(object):
5370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
5380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Filter instances are used to perform arbitrary filtering of LogRecords.
5390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Loggers and Handlers can optionally use Filter instances to filter
5410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    records as desired. The base filter class only allows events which are
5420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    below a certain point in the logger hierarchy. For example, a filter
5430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    initialized with "A.B" will allow events logged by loggers "A.B",
5440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
5450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    initialized with the empty string, all events are passed.
5460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
5470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, name=''):
5480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initialize a filter.
5500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initialize with the name of the logger which, together with its
5520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        children, will have its events allowed through the filter. If no
5530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        name is specified, allow every event.
5540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.name = name
5560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.nlen = len(name)
5570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def filter(self, record):
5590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Determine if the specified record is to be logged.
5610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Is the specified record to be logged? Returns 0 for no, nonzero for
5630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        yes. If deemed appropriate, the record may be modified in-place.
5640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.nlen == 0:
5660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return 1
5670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif self.name == record.name:
5680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return 1
5690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        elif record.name.find(self.name, 0, self.nlen) != 0:
5700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return 0
5710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return (record.name[self.nlen] == ".")
5720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5730a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass Filterer(object):
5740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
5750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    A base class for loggers and handlers which allows them to share
5760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    common code.
5770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
5780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self):
5790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initialize the list of filters to be an empty list.
5810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.filters = []
5830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def addFilter(self, filter):
5850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Add the specified filter to this handler.
5870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not (filter in self.filters):
5890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.filters.append(filter)
5900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def removeFilter(self, filter):
5920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Remove the specified filter from this handler.
5940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
5950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if filter in self.filters:
5960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.filters.remove(filter)
5970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
5980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def filter(self, record):
5990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
6000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Determine if a record is loggable by consulting all the filters.
6010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        The default is to allow the record to be logged; any filter can veto
6030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        this and the record is then dropped. Returns a zero value if a record
6040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        is to be dropped, else non-zero.
6050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
6060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rv = 1
6070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for f in self.filters:
6080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not f.filter(record):
6090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                rv = 0
6100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                break
6110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return rv
6120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
6140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   Handler classes and functions
6150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
6160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_handlers = weakref.WeakValueDictionary()  #map of handler names to handlers
6180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_handlerList = [] # added to allow handlers to be removed in reverse of order initialized
6190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6200a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef _removeHandlerRef(wr):
6210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
6220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Remove a handler reference from the internal cleanup list.
6230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
6240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # This function can be called during module teardown, when globals are
6250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # set to None. If _acquireLock is None, assume this is the case and do
6260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # nothing.
6270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if (_acquireLock is not None and _handlerList is not None and
6280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _releaseLock is not None):
6290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _acquireLock()
6300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
6310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if wr in _handlerList:
6320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                _handlerList.remove(wr)
6330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
6340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _releaseLock()
6350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6360a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef _addHandlerRef(handler):
6370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
6380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Add a handler to the internal cleanup list using a weak reference.
6390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
6400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _acquireLock()
6410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
6420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _handlerList.append(weakref.ref(handler, _removeHandlerRef))
6430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    finally:
6440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _releaseLock()
6450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6460a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass Handler(Filterer):
6470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
6480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Handler instances dispatch logging events to specific destinations.
6490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    The base handler class. Acts as a placeholder which defines the Handler
6510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    interface. Handlers can optionally use Formatter instances to format
6520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    records as desired. By default, no formatter is specified; in this case,
6530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    the 'raw' message as determined by record.message is logged.
6540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
6550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, level=NOTSET):
6560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
6570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initializes the instance - basically setting the formatter to None
6580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        and the filter list to empty.
6590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
6600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Filterer.__init__(self)
6610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self._name = None
6620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.level = _checkLevel(level)
6630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.formatter = None
6640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # Add the handler to the global _handlerList (for cleanup on shutdown)
6650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _addHandlerRef(self)
6660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.createLock()
6670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def get_name(self):
6690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self._name
6700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def set_name(self, name):
6720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _acquireLock()
6730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
6740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self._name in _handlers:
6750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                del _handlers[self._name]
6760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self._name = name
6770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if name:
6780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                _handlers[name] = self
6790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
6800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _releaseLock()
6810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    name = property(get_name, set_name)
6830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def createLock(self):
6850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
6860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Acquire a thread lock for serializing access to the underlying I/O.
6870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
6880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if thread:
6890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.lock = threading.RLock()
6900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
6910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.lock = None
6920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
6930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def acquire(self):
6940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
6950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Acquire the I/O thread lock.
6960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
6970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.lock:
6980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.lock.acquire()
6990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def release(self):
7010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Release the I/O thread lock.
7030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.lock:
7050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.lock.release()
7060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def setLevel(self, level):
7080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Set the logging level of this handler.
7100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.level = _checkLevel(level)
7120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def format(self, record):
7140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Format the specified record.
7160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        If a formatter is set, use it. Otherwise, use the default formatter
7180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for the module.
7190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.formatter:
7210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fmt = self.formatter
7220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
7230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fmt = _defaultFormatter
7240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return fmt.format(record)
7250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def emit(self, record):
7270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Do whatever it takes to actually log the specified logging record.
7290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        This version is intended to be implemented by subclasses and so
7310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raises a NotImplementedError.
7320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        raise NotImplementedError('emit must be implemented '
7340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                  'by Handler subclasses')
7350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def handle(self, record):
7370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Conditionally emit the specified logging record.
7390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Emission depends on filters which may have been added to the handler.
7410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Wrap the actual emission of the record with acquisition/release of
7420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        the I/O thread lock. Returns whether the filter passed the record for
7430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        emission.
7440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rv = self.filter(record)
7460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if rv:
7470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.acquire()
7480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
7490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.emit(record)
7500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            finally:
7510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.release()
7520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return rv
7530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def setFormatter(self, fmt):
7550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Set the formatter for this handler.
7570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.formatter = fmt
7590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def flush(self):
7610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Ensure all logging output has been flushed.
7630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        This version does nothing and is intended to be implemented by
7650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        subclasses.
7660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pass
7680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def close(self):
7700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Tidy up any resources used by the handler.
7720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        This version removes the handler from an internal map of handlers,
7740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _handlers, which is used for handler lookup by name. Subclasses
7750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        should ensure that this gets called from overridden close()
7760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        methods.
7770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #get the module data lock, as we're updating a shared structure.
7790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _acquireLock()
7800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:    #unlikely to raise an exception, but you never know...
7810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self._name and self._name in _handlers:
7820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                del _handlers[self._name]
7830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
7840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _releaseLock()
7850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def handleError(self, record):
7870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Handle errors which occur during an emit() call.
7890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
7900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        This method should be called from handlers when an exception is
7910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        encountered during an emit() call. If raiseExceptions is false,
7920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        exceptions get silently ignored. This is what is mostly wanted
7930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for a logging system - most users will not care about errors in
7940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        the logging system, they are more interested in application errors.
7950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        You could, however, replace this with a custom handler if you wish.
7960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        The record which was being processed is passed in to this method.
7970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
7980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if raiseExceptions and sys.stderr:  # see issue 13807
7990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ei = sys.exc_info()
8000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
8010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                traceback.print_exception(ei[0], ei[1], ei[2],
8020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                          None, sys.stderr)
8030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                sys.stderr.write('Logged from file %s, line %s\n' % (
8040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                 record.filename, record.lineno))
8050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except IOError:
8060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                pass    # see issue 5971
8070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            finally:
8080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                del ei
8090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass StreamHandler(Handler):
8110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
8120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    A handler class which writes logging records, appropriately formatted,
8130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    to a stream. Note that this class does not close the stream, as
8140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    sys.stdout or sys.stderr may be used.
8150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
8160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, stream=None):
8180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
8190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initialize the handler.
8200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        If stream is not specified, sys.stderr is used.
8220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
8230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Handler.__init__(self)
8240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if stream is None:
8250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            stream = sys.stderr
8260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.stream = stream
8270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def flush(self):
8290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
8300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Flushes the stream.
8310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
8320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.acquire()
8330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
8340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self.stream and hasattr(self.stream, "flush"):
8350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.stream.flush()
8360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
8370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.release()
8380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def emit(self, record):
8400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
8410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Emit a record.
8420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        If a formatter is specified, it is used to format the record.
8440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        The record is then written to the stream with a trailing newline.  If
8450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        exception information is present, it is formatted using
8460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        traceback.print_exception and appended to the stream.  If the stream
8470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        has an 'encoding' attribute, it is used to determine how to do the
8480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        output to the stream.
8490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
8500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
8510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            msg = self.format(record)
8520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            stream = self.stream
8530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fs = "%s\n"
8540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not _unicode: #if no unicode support...
8550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                stream.write(fs % msg)
8560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
8570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                try:
8580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    if (isinstance(msg, unicode) and
8590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        getattr(stream, 'encoding', None)):
8600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        ufs = fs.decode(stream.encoding)
8610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        try:
8620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            stream.write(ufs % msg)
8630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        except UnicodeEncodeError:
8640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            #Printing to terminals sometimes fails. For example,
8650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            #with an encoding of 'cp1251', the above write will
8660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            #work if written to a stream opened or wrapped by
8670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            #the codecs module, but fail when writing to a
8680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            #terminal even when the codepage is set to cp1251.
8690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            #An extra encoding step seems to be needed.
8700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            stream.write((ufs % msg).encode(stream.encoding))
8710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    else:
8720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        stream.write(fs % msg)
8730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                except UnicodeError:
8740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    stream.write(fs % msg.encode("UTF-8"))
8750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.flush()
8760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except (KeyboardInterrupt, SystemExit):
8770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise
8780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except:
8790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.handleError(record)
8800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
8810a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FileHandler(StreamHandler):
8820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
8830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    A handler class which writes formatted logging records to disk files.
8840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
8850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, filename, mode='a', encoding=None, delay=0):
8860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
8870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Open the specified file and use it as the stream for logging.
8880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
8890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #keep the absolute path, otherwise derived classes which use this
8900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #may come a cropper when the current directory changes
8910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if codecs is None:
8920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            encoding = None
8930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.baseFilename = os.path.abspath(filename)
8940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.mode = mode
8950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.encoding = encoding
8960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if delay:
8970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #We don't open the stream, but we still need to call the
8980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #Handler constructor to set level, formatter, lock etc.
8990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            Handler.__init__(self)
9000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.stream = None
9010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
9020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            StreamHandler.__init__(self, self._open())
9030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def close(self):
9050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
9060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Closes the stream.
9070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
9080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.acquire()
9090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
9100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if self.stream:
9110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.flush()
9120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if hasattr(self.stream, "close"):
9130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.stream.close()
9140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                StreamHandler.close(self)
9150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.stream = None
9160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
9170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.release()
9180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def _open(self):
9200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
9210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Open the current base file with the (original) mode and encoding.
9220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Return the resulting stream.
9230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
9240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.encoding is None:
9250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            stream = open(self.baseFilename, self.mode)
9260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
9270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            stream = codecs.open(self.baseFilename, self.mode, self.encoding)
9280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return stream
9290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def emit(self, record):
9310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
9320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Emit a record.
9330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        If the stream was not opened because 'delay' was specified in the
9350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        constructor, open it before calling the superclass's emit.
9360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
9370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.stream is None:
9380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.stream = self._open()
9390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        StreamHandler.emit(self, record)
9400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
9420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   Manager classes and functions
9430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
9440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9450a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass PlaceHolder(object):
9460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
9470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    PlaceHolder instances are used in the Manager logger hierarchy to take
9480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    the place of nodes for which no loggers have been defined. This class is
9490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    intended for internal use only and not as part of the public API.
9500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
9510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, alogger):
9520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
9530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initialize with the specified logger being a child of this placeholder.
9540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
9550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #self.loggers = [alogger]
9560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.loggerMap = { alogger : None }
9570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def append(self, alogger):
9590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
9600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Add the specified logger as a child of this placeholder.
9610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
9620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #if alogger not in self.loggers:
9630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if alogger not in self.loggerMap:
9640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #self.loggers.append(alogger)
9650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.loggerMap[alogger] = None
9660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
9680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   Determine which class to use when instantiating loggers.
9690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
9700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_loggerClass = None
9710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9720a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef setLoggerClass(klass):
9730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
9740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Set the class to be used when instantiating a logger. The class should
9750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    define __init__() such that only a name argument is required, and the
9760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    __init__() should call Logger.__init__()
9770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
9780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if klass != Logger:
9790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not issubclass(klass, Logger):
9800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise TypeError("logger not derived from logging.Logger: "
9810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                            + klass.__name__)
9820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    global _loggerClass
9830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _loggerClass = klass
9840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9850a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getLoggerClass():
9860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
9870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Return the class to be used when instantiating a logger.
9880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
9890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return _loggerClass
9910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
9920a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass Manager(object):
9930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
9940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    There is [under normal circumstances] just one Manager instance, which
9950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    holds the hierarchy of loggers.
9960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
9970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, rootnode):
9980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
9990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initialize the manager with the root node of the logger hierarchy.
10000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
10010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.root = rootnode
10020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.disable = 0
10030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.emittedNoHandlerWarning = 0
10040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.loggerDict = {}
10050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.loggerClass = None
10060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def getLogger(self, name):
10080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
10090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Get a logger with the specified name (channel name), creating it
10100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if it doesn't yet exist. This name is a dot-separated hierarchical
10110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        name, such as "a", "a.b", "a.b.c" or similar.
10120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        If a PlaceHolder existed for the specified name [i.e. the logger
10140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        didn't exist but a child of it did], replace it with the created
10150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logger and fix up the parent/child references which pointed to the
10160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        placeholder to now point to the logger.
10170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
10180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rv = None
10190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not isinstance(name, basestring):
10200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            raise TypeError('A logger name must be string or Unicode')
10210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if isinstance(name, unicode):
10220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            name = name.encode('utf-8')
10230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _acquireLock()
10240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
10250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if name in self.loggerDict:
10260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                rv = self.loggerDict[name]
10270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if isinstance(rv, PlaceHolder):
10280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    ph = rv
10290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    rv = (self.loggerClass or _loggerClass)(name)
10300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    rv.manager = self
10310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.loggerDict[name] = rv
10320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self._fixupChildren(ph, rv)
10330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self._fixupParents(rv)
10340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
10350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                rv = (self.loggerClass or _loggerClass)(name)
10360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                rv.manager = self
10370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.loggerDict[name] = rv
10380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self._fixupParents(rv)
10390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
10400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _releaseLock()
10410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return rv
10420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def setLoggerClass(self, klass):
10440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
10450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Set the class to be used when instantiating a logger with this Manager.
10460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
10470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if klass != Logger:
10480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not issubclass(klass, Logger):
10490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                raise TypeError("logger not derived from logging.Logger: "
10500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                + klass.__name__)
10510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.loggerClass = klass
10520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def _fixupParents(self, alogger):
10540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
10550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Ensure that there are either loggers or placeholders all the way
10560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        from the specified logger to the root of the logger hierarchy.
10570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
10580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        name = alogger.name
10590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        i = name.rfind(".")
10600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rv = None
10610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        while (i > 0) and not rv:
10620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            substr = name[:i]
10630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if substr not in self.loggerDict:
10640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.loggerDict[substr] = PlaceHolder(alogger)
10650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
10660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                obj = self.loggerDict[substr]
10670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if isinstance(obj, Logger):
10680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    rv = obj
10690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                else:
10700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    assert isinstance(obj, PlaceHolder)
10710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    obj.append(alogger)
10720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            i = name.rfind(".", 0, i - 1)
10730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not rv:
10740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            rv = self.root
10750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        alogger.parent = rv
10760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def _fixupChildren(self, ph, alogger):
10780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
10790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Ensure that children of the placeholder ph are connected to the
10800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        specified logger.
10810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
10820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        name = alogger.name
10830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        namelen = len(name)
10840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for c in ph.loggerMap.keys():
10850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #The if means ... if not c.parent.name.startswith(nm)
10860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if c.parent.name[:namelen] != name:
10870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                alogger.parent = c.parent
10880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                c.parent = alogger
10890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
10910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#   Logger classes and functions
10920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
10930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
10940a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass Logger(Filterer):
10950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
10960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Instances of the Logger class represent a single logging channel. A
10970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    "logging channel" indicates an area of an application. Exactly how an
10980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    "area" is defined is up to the application developer. Since an
10990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    application can have any number of areas, logging channels are identified
11000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    by a unique string. Application areas can be nested (e.g. an area
11010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    of "input processing" might include sub-areas "read CSV files", "read
11020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    XLS files" and "read Gnumeric files"). To cater for this natural nesting,
11030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    channel names are organized into a namespace hierarchy where levels are
11040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    separated by periods, much like the Java or Python package namespace. So
11050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    in the instance given above, channel names might be "input" for the upper
11060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
11070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    There is no arbitrary limit to the depth of nesting.
11080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
11090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, name, level=NOTSET):
11100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initialize the logger with a name and an optional level.
11120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Filterer.__init__(self)
11140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.name = name
11150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.level = _checkLevel(level)
11160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.parent = None
11170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.propagate = 1
11180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.handlers = []
11190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.disabled = 0
11200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def setLevel(self, level):
11220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Set the logging level of this logger.
11240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.level = _checkLevel(level)
11260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def debug(self, msg, *args, **kwargs):
11280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Log 'msg % args' with severity 'DEBUG'.
11300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        To pass exception information, use the keyword argument exc_info with
11320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a true value, e.g.
11330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
11350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.isEnabledFor(DEBUG):
11370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self._log(DEBUG, msg, args, **kwargs)
11380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def info(self, msg, *args, **kwargs):
11400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Log 'msg % args' with severity 'INFO'.
11420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        To pass exception information, use the keyword argument exc_info with
11440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a true value, e.g.
11450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
11470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.isEnabledFor(INFO):
11490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self._log(INFO, msg, args, **kwargs)
11500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def warning(self, msg, *args, **kwargs):
11520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Log 'msg % args' with severity 'WARNING'.
11540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        To pass exception information, use the keyword argument exc_info with
11560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a true value, e.g.
11570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
11590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.isEnabledFor(WARNING):
11610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self._log(WARNING, msg, args, **kwargs)
11620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    warn = warning
11640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def error(self, msg, *args, **kwargs):
11660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Log 'msg % args' with severity 'ERROR'.
11680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        To pass exception information, use the keyword argument exc_info with
11700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a true value, e.g.
11710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logger.error("Houston, we have a %s", "major problem", exc_info=1)
11730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.isEnabledFor(ERROR):
11750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self._log(ERROR, msg, args, **kwargs)
11760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def exception(self, msg, *args, **kwargs):
11780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Convenience method for logging an ERROR with exception information.
11800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        kwargs['exc_info'] = 1
11820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.error(msg, *args, **kwargs)
11830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def critical(self, msg, *args, **kwargs):
11850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Log 'msg % args' with severity 'CRITICAL'.
11870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        To pass exception information, use the keyword argument exc_info with
11890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a true value, e.g.
11900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
11920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
11930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.isEnabledFor(CRITICAL):
11940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self._log(CRITICAL, msg, args, **kwargs)
11950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    fatal = critical
11970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
11980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def log(self, level, msg, *args, **kwargs):
11990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Log 'msg % args' with the integer severity 'level'.
12010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        To pass exception information, use the keyword argument exc_info with
12030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a true value, e.g.
12040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
12060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not isinstance(level, int):
12080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if raiseExceptions:
12090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                raise TypeError("level must be an integer")
12100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
12110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return
12120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.isEnabledFor(level):
12130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self._log(level, msg, args, **kwargs)
12140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def findCaller(self):
12160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Find the stack frame of the caller so that we can note the source
12180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        file name, line number and function name.
12190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        f = currentframe()
12210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #On some versions of IronPython, currentframe() returns None if
12220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #IronPython isn't run with -X:Frames.
12230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if f is not None:
12240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            f = f.f_back
12250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rv = "(unknown file)", 0, "(unknown function)"
12260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        while hasattr(f, "f_code"):
12270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            co = f.f_code
12280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            filename = os.path.normcase(co.co_filename)
12290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if filename == _srcfile:
12300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                f = f.f_back
12310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                continue
12320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            rv = (co.co_filename, f.f_lineno, co.co_name)
12330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            break
12340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return rv
12350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
12370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        A factory method which can be overridden in subclasses to create
12390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        specialized LogRecords.
12400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
12420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if extra is not None:
12430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for key in extra:
12440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if (key in ["message", "asctime"]) or (key in rv.__dict__):
12450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    raise KeyError("Attempt to overwrite %r in LogRecord" % key)
12460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                rv.__dict__[key] = extra[key]
12470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return rv
12480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def _log(self, level, msg, args, exc_info=None, extra=None):
12500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Low-level logging routine which creates a LogRecord and then calls
12520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        all the handlers of this logger to handle the record.
12530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if _srcfile:
12550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #IronPython doesn't track Python frames, so findCaller raises an
12560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #exception on some versions of IronPython. We trap it here so that
12570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #IronPython can use logging.
12580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            try:
12590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                fn, lno, func = self.findCaller()
12600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            except ValueError:
12610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                fn, lno, func = "(unknown file)", 0, "(unknown function)"
12620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else:
12630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fn, lno, func = "(unknown file)", 0, "(unknown function)"
12640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if exc_info:
12650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not isinstance(exc_info, tuple):
12660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                exc_info = sys.exc_info()
12670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
12680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.handle(record)
12690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def handle(self, record):
12710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Call the handlers for the specified record.
12730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        This method is used for unpickled records received from a socket, as
12750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        well as those created locally. Logger-level filtering is applied.
12760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if (not self.disabled) and self.filter(record):
12780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.callHandlers(record)
12790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def addHandler(self, hdlr):
12810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Add the specified handler to this logger.
12830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _acquireLock()
12850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
12860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not (hdlr in self.handlers):
12870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.handlers.append(hdlr)
12880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
12890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _releaseLock()
12900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
12910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def removeHandler(self, hdlr):
12920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Remove the specified handler from this logger.
12940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
12950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _acquireLock()
12960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
12970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if hdlr in self.handlers:
12980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.handlers.remove(hdlr)
12990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
13000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _releaseLock()
13010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def callHandlers(self, record):
13030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
13040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Pass a record to all relevant handlers.
13050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Loop through all handlers for this logger and its parents in the
13070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logger hierarchy. If no handler was found, output a one-off error
13080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        message to sys.stderr. Stop searching up the hierarchy whenever a
13090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logger with the "propagate" attribute set to zero is found - that
13100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        will be the last logger whose handlers are called.
13110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
13120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        c = self
13130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        found = 0
13140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        while c:
13150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            for hdlr in c.handlers:
13160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                found = found + 1
13170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if record.levelno >= hdlr.level:
13180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    hdlr.handle(record)
13190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if not c.propagate:
13200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                c = None    #break out
13210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
13220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                c = c.parent
13230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
13240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            sys.stderr.write("No handlers could be found for logger"
13250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                             " \"%s\"\n" % self.name)
13260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.manager.emittedNoHandlerWarning = 1
13270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def getEffectiveLevel(self):
13290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
13300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Get the effective level for this logger.
13310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Loop through this logger and its parents in the logger hierarchy,
13330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        looking for a non-zero logging level. Return the first one found.
13340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
13350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logger = self
13360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        while logger:
13370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if logger.level:
13380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                return logger.level
13390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            logger = logger.parent
13400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return NOTSET
13410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def isEnabledFor(self, level):
13430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
13440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Is this logger enabled for level 'level'?
13450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
13460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.manager.disable >= level:
13470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            return 0
13480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return level >= self.getEffectiveLevel()
13490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def getChild(self, suffix):
13510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
13520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Get a logger which is a descendant to this one.
13530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        This is a convenience method, such that
13550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logging.getLogger('abc').getChild('def.ghi')
13570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        is the same as
13590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logging.getLogger('abc.def.ghi')
13610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        It's useful, for example, when the parent logger is named using
13630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        __name__ rather than a literal string.
13640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
13650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if self.root is not self:
13660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            suffix = '.'.join((self.name, suffix))
13670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.manager.getLogger(suffix)
13680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13690a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass RootLogger(Logger):
13700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
13710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    A root logger is not that different to any other logger, except that
13720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    it must have a logging level and there is only one instance of it in
13730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    the hierarchy.
13740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
13750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, level):
13760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
13770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initialize the logger with the name "root".
13780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
13790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Logger.__init__(self, "root", level)
13800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_loggerClass = Logger
13820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13830a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass LoggerAdapter(object):
13840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
13850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    An adapter for loggers which makes it easier to specify contextual
13860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    information in logging output.
13870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
13880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def __init__(self, logger, extra):
13900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
13910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Initialize the adapter with a logger and a dict-like object which
13920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        provides contextual information. This constructor signature allows
13930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        easy stacking of LoggerAdapters, if so desired.
13940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        You can effectively pass keyword arguments as shown in the
13960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        following example:
13970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
13980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
13990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.logger = logger
14010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.extra = extra
14020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def process(self, msg, kwargs):
14040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Process the logging message and keyword arguments passed in to
14060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        a logging call to insert contextual information. You can either
14070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        manipulate the message itself, the keyword args or both. Return
14080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        the message and kwargs modified (or not) to suit your needs.
14090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Normally, you'll only need to override this one method in a
14110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        LoggerAdapter subclass for your specific needs.
14120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        kwargs["extra"] = self.extra
14140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return msg, kwargs
14150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def debug(self, msg, *args, **kwargs):
14170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Delegate a debug call to the underlying logger, after adding
14190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        contextual information from this adapter instance.
14200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        msg, kwargs = self.process(msg, kwargs)
14220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.logger.debug(msg, *args, **kwargs)
14230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def info(self, msg, *args, **kwargs):
14250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Delegate an info call to the underlying logger, after adding
14270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        contextual information from this adapter instance.
14280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        msg, kwargs = self.process(msg, kwargs)
14300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.logger.info(msg, *args, **kwargs)
14310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def warning(self, msg, *args, **kwargs):
14330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Delegate a warning call to the underlying logger, after adding
14350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        contextual information from this adapter instance.
14360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        msg, kwargs = self.process(msg, kwargs)
14380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.logger.warning(msg, *args, **kwargs)
14390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def error(self, msg, *args, **kwargs):
14410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Delegate an error call to the underlying logger, after adding
14430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        contextual information from this adapter instance.
14440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        msg, kwargs = self.process(msg, kwargs)
14460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.logger.error(msg, *args, **kwargs)
14470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def exception(self, msg, *args, **kwargs):
14490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Delegate an exception call to the underlying logger, after adding
14510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        contextual information from this adapter instance.
14520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        msg, kwargs = self.process(msg, kwargs)
14540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        kwargs["exc_info"] = 1
14550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.logger.error(msg, *args, **kwargs)
14560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def critical(self, msg, *args, **kwargs):
14580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Delegate a critical call to the underlying logger, after adding
14600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        contextual information from this adapter instance.
14610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        msg, kwargs = self.process(msg, kwargs)
14630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.logger.critical(msg, *args, **kwargs)
14640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def log(self, level, msg, *args, **kwargs):
14660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        Delegate a log call to the underlying logger, after adding
14680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        contextual information from this adapter instance.
14690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        msg, kwargs = self.process(msg, kwargs)
14710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.logger.log(level, msg, *args, **kwargs)
14720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def isEnabledFor(self, level):
14740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        See if the underlying logger is enabled for the specified level.
14760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        """
14770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return self.logger.isEnabledFor(level)
14780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14790a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoroot = RootLogger(WARNING)
14800a8c90248264a8b26970b4473770bcc3df8515fJosh GaoLogger.root = root
14810a8c90248264a8b26970b4473770bcc3df8515fJosh GaoLogger.manager = Manager(Logger.root)
14820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
14840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Configuration classes and functions
14850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
14860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14870a8c90248264a8b26970b4473770bcc3df8515fJosh GaoBASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
14880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14890a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef basicConfig(**kwargs):
14900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
14910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Do basic configuration for the logging system.
14920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    This function does nothing if the root logger already has handlers
14940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    configured. It is a convenience method intended for use by simple scripts
14950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    to do one-shot configuration of the logging package.
14960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
14970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    The default behaviour is to create a StreamHandler which writes to
14980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    sys.stderr, set a formatter using the BASIC_FORMAT format string, and
14990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    add the handler to the root logger.
15000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    A number of optional keyword arguments may be specified, which can alter
15020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    the default behaviour.
15030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    filename  Specifies that a FileHandler be created, using the specified
15050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              filename, rather than a StreamHandler.
15060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    filemode  Specifies the mode to open the file, if filename is specified
15070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              (if filemode is unspecified, it defaults to 'a').
15080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    format    Use the specified format string for the handler.
15090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    datefmt   Use the specified date/time format.
15100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    level     Set the root logger level to the specified level.
15110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    stream    Use the specified stream to initialize the StreamHandler. Note
15120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              that this argument is incompatible with 'filename' - if both
15130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao              are present, 'stream' is ignored.
15140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Note that you could specify a stream created using open(filename, mode)
15160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    rather than passing the filename and mode in. However, it should be
15170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    remembered that StreamHandler does not close its stream (since it may be
15180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    using sys.stdout or sys.stderr), whereas FileHandler closes its stream
15190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    when the handler is closed.
15200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
15210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Add thread safety in case someone mistakenly calls
15220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # basicConfig() from multiple threads
15230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    _acquireLock()
15240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    try:
15250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if len(root.handlers) == 0:
15260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            filename = kwargs.get("filename")
15270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if filename:
15280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                mode = kwargs.get("filemode", 'a')
15290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                hdlr = FileHandler(filename, mode)
15300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            else:
15310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                stream = kwargs.get("stream")
15320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                hdlr = StreamHandler(stream)
15330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fs = kwargs.get("format", BASIC_FORMAT)
15340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            dfs = kwargs.get("datefmt", None)
15350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            fmt = Formatter(fs, dfs)
15360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            hdlr.setFormatter(fmt)
15370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            root.addHandler(hdlr)
15380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            level = kwargs.get("level")
15390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if level is not None:
15400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                root.setLevel(level)
15410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    finally:
15420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        _releaseLock()
15430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
15450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Utility functions at module level.
15460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Basically delegate everything to the root logger.
15470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#---------------------------------------------------------------------------
15480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15490a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef getLogger(name=None):
15500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
15510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Return a logger with the specified name, creating it if necessary.
15520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    If no name is specified, return the root logger.
15540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
15550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if name:
15560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return Logger.manager.getLogger(name)
15570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
15580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        return root
15590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#def getRootLogger():
15610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#    """
15620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#    Return the root logger.
15630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#
15640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#    Note that getLogger('') now does the same thing, so this function is
15650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#    deprecated and may disappear in the future.
15660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#    """
15670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#    return root
15680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15690a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef critical(msg, *args, **kwargs):
15700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
15710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Log a message with severity 'CRITICAL' on the root logger.
15720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
15730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(root.handlers) == 0:
15740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        basicConfig()
15750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    root.critical(msg, *args, **kwargs)
15760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15770a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofatal = critical
15780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15790a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef error(msg, *args, **kwargs):
15800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
15810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Log a message with severity 'ERROR' on the root logger.
15820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
15830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(root.handlers) == 0:
15840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        basicConfig()
15850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    root.error(msg, *args, **kwargs)
15860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15870a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef exception(msg, *args, **kwargs):
15880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
15890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Log a message with severity 'ERROR' on the root logger,
15900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    with exception information.
15910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
15920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    kwargs['exc_info'] = 1
15930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    error(msg, *args, **kwargs)
15940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
15950a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef warning(msg, *args, **kwargs):
15960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
15970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Log a message with severity 'WARNING' on the root logger.
15980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
15990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(root.handlers) == 0:
16000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        basicConfig()
16010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    root.warning(msg, *args, **kwargs)
16020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16030a8c90248264a8b26970b4473770bcc3df8515fJosh Gaowarn = warning
16040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16050a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef info(msg, *args, **kwargs):
16060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Log a message with severity 'INFO' on the root logger.
16080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(root.handlers) == 0:
16100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        basicConfig()
16110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    root.info(msg, *args, **kwargs)
16120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16130a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef debug(msg, *args, **kwargs):
16140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Log a message with severity 'DEBUG' on the root logger.
16160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(root.handlers) == 0:
16180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        basicConfig()
16190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    root.debug(msg, *args, **kwargs)
16200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16210a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef log(level, msg, *args, **kwargs):
16220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Log 'msg % args' with the integer severity 'level' on the root logger.
16240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if len(root.handlers) == 0:
16260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        basicConfig()
16270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    root.log(level, msg, *args, **kwargs)
16280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16290a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef disable(level):
16300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Disable all logging calls of severity 'level' and below.
16320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    root.manager.disable = level
16340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16350a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef shutdown(handlerList=_handlerList):
16360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Perform any cleanup actions in the logging system (e.g. flushing
16380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    buffers).
16390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Should be called at application exit.
16410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    for wr in reversed(handlerList[:]):
16430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #errors might occur, for example, if files are locked
16440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        #we just ignore them if raiseExceptions is not set
16450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
16460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            h = wr()
16470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if h:
16480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                try:
16490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    h.acquire()
16500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    h.flush()
16510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    h.close()
16520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                except (IOError, ValueError):
16530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # Ignore errors which might be caused
16540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # because handlers have been closed but
16550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # references to them are still around at
16560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    # application exit.
16570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    pass
16580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                finally:
16590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    h.release()
16600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        except:
16610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if raiseExceptions:
16620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                raise
16630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            #else, swallow
16640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#Let's try and shutdown automatically on application exit...
16660a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport atexit
16670a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoatexit.register(shutdown)
16680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Null handler
16700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16710a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass NullHandler(Handler):
16720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    This handler does nothing. It's intended to be used to avoid the
16740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    "No handlers could be found for logger XXX" one-off warning. This is
16750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    important for library code, which may contain code to log events. If a user
16760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    of the library does not configure logging, the one-off warning might be
16770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    produced; to avoid this, the library developer simply needs to instantiate
16780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    a NullHandler and add it to the top-level logger of the library module or
16790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    package.
16800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def handle(self, record):
16820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pass
16830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def emit(self, record):
16850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pass
16860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def createLock(self):
16880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.lock = None
16890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Warnings integration
16910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao_warnings_showwarning = None
16930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
16940a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef _showwarning(message, category, filename, lineno, file=None, line=None):
16950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
16960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    Implementation of showwarnings which redirects to logging, which will first
16970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    check to see if the file parameter is None. If a file is specified, it will
16980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    delegate to the original warnings implementation of showwarning. Otherwise,
16990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    it will call warnings.formatwarning and will log the resulting string to a
17000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    warnings logger named "py.warnings" with level logging.WARNING.
17010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
17020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if file is not None:
17030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if _warnings_showwarning is not None:
17040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _warnings_showwarning(message, category, filename, lineno, file, line)
17050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
17060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        s = warnings.formatwarning(message, category, filename, lineno, line)
17070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logger = getLogger("py.warnings")
17080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if not logger.handlers:
17090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            logger.addHandler(NullHandler())
17100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        logger.warning("%s", s)
17110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
17120a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef captureWarnings(capture):
17130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
17140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    If capture is true, redirect all warnings to the logging package.
17150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    If capture is False, ensure that warnings are not redirected to logging
17160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    but to their original destinations.
17170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    """
17180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    global _warnings_showwarning
17190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    if capture:
17200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if _warnings_showwarning is None:
17210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _warnings_showwarning = warnings.showwarning
17220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            warnings.showwarning = _showwarning
17230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    else:
17240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if _warnings_showwarning is not None:
17250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            warnings.showwarning = _warnings_showwarning
17260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _warnings_showwarning = None
1727