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