1638e6220557db50b01653b410eb12f11b9b8ab1cVinay Sajip# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved. 257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Permission to use, copy, modify, and distribute this software and its 457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# documentation for any purpose and without fee is hereby granted, 557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# provided that the above copyright notice appear in all copies and that 657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# both that copyright notice and this permission notice appear in 757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# supporting documentation, and that the name of Vinay Sajip 857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# not be used in advertising or publicity pertaining to distribution 957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# of the software without specific, written prior permission. 1057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 1157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL 1257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 1357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 1457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 1557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 1757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum""" 1857102f861d506b6c2d2215d100dac9143574fa77Guido van RossumLogging package for Python. Based on PEP 282 and comments thereto in 190abf61db4dd0d008ad06c84cd882fb84e5c11181Vinay Sajipcomp.lang.python. 2057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 21638e6220557db50b01653b410eb12f11b9b8ab1cVinay SajipCopyright (C) 2001-2016 Vinay Sajip. All Rights Reserved. 2257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 2357102f861d506b6c2d2215d100dac9143574fa77Guido van RossumTo use, simply 'import logging' and log away! 2457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum""" 2557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 261b7611405d80df5387cad6492b7b12436450ccedVinay Sajipimport sys, os, time, io, traceback, warnings, weakref, collections 271b7611405d80df5387cad6492b7b12436450ccedVinay Sajip 286a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajipfrom string import Template 29f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl 3018c66898b0a14761786161c07d89d65c8f088601Christian Heimes__all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR', 31ad5fa2fbd08ee221002f41fd6a9c41362396cb6dVinay Sajip 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO', 32ad5fa2fbd08ee221002f41fd6a9c41362396cb6dVinay Sajip 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler', 33ad5fa2fbd08ee221002f41fd6a9c41362396cb6dVinay Sajip 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig', 34ad5fa2fbd08ee221002f41fd6a9c41362396cb6dVinay Sajip 'captureWarnings', 'critical', 'debug', 'disable', 'error', 35ad5fa2fbd08ee221002f41fd6a9c41362396cb6dVinay Sajip 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass', 3619e69c5a2067fe6322ead88733ebbca77673010bMartin Panter 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown', 3719e69c5a2067fe6322ead88733ebbca77673010bMartin Panter 'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory', 3819e69c5a2067fe6322ead88733ebbca77673010bMartin Panter 'lastResort', 'raiseExceptions'] 39b89e7c9bc97d3f9332ecc94c88a055c0fe947625Vinay Sajip 40b89e7c9bc97d3f9332ecc94c88a055c0fe947625Vinay Sajiptry: 4157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum import threading 42cd171c8e92c10d327151400fd8f16b11a4964615Brett Cannonexcept ImportError: #pragma: no cover 432a12974bca2433eea0131d904a423ed8234dcf7aVictor Stinner threading = None 4457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 4557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>" 46477c8d5e70240744d24631b18341ad892c8a8e1cThomas Wouters__status__ = "production" 47698abe75d4e44dfecb8e6b8aa421b8505d24be05Vinay Sajip# The following module attributes are no longer updated. 48db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip__version__ = "0.5.1.2" 49db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip__date__ = "07 February 2010" 5057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 5157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 5257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Miscellaneous module data 5357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 5457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 5557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 5657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#_startTime is used as the base when calculating the relative time of events 5757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 5857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum_startTime = time.time() 5957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 6057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 6157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#raiseExceptions is used to see if exceptions during handling should be 6257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#propagated 6357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 6426fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay SajipraiseExceptions = True 6557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 66d364a07517bb2a413e5d4739c2f43c4af218be43Vinay Sajip# 67d364a07517bb2a413e5d4739c2f43c4af218be43Vinay Sajip# If you don't want threading information in the log, set this to zero 68d364a07517bb2a413e5d4739c2f43c4af218be43Vinay Sajip# 6926fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay SajiplogThreads = True 70d364a07517bb2a413e5d4739c2f43c4af218be43Vinay Sajip 71d364a07517bb2a413e5d4739c2f43c4af218be43Vinay Sajip# 729a0fc97bf4a336d81160b19a52ab4f5d2e2317e0Jesse Noller# If you don't want multiprocessing information in the log, set this to zero 739a0fc97bf4a336d81160b19a52ab4f5d2e2317e0Jesse Noller# 7426fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay SajiplogMultiprocessing = True 759a0fc97bf4a336d81160b19a52ab4f5d2e2317e0Jesse Noller 769a0fc97bf4a336d81160b19a52ab4f5d2e2317e0Jesse Noller# 77d364a07517bb2a413e5d4739c2f43c4af218be43Vinay Sajip# If you don't want process information in the log, set this to zero 78d364a07517bb2a413e5d4739c2f43c4af218be43Vinay Sajip# 7926fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay SajiplogProcesses = True 80d364a07517bb2a413e5d4739c2f43c4af218be43Vinay Sajip 8157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 8257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Level related stuff 8357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 8457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 8557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Default levels and level names, these can be replaced with any positive set 8657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# of values having corresponding names. There is a pseudo-level, NOTSET, which 8757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# is only really there as a lower limit for user-defined levels. Handlers and 8857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# loggers are initialized with NOTSET so that they will log all messages, even 8957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# at user-defined levels. 9057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 91b89e7c9bc97d3f9332ecc94c88a055c0fe947625Vinay Sajip 9257102f861d506b6c2d2215d100dac9143574fa77Guido van RossumCRITICAL = 50 9357102f861d506b6c2d2215d100dac9143574fa77Guido van RossumFATAL = CRITICAL 9457102f861d506b6c2d2215d100dac9143574fa77Guido van RossumERROR = 40 956fa635df7aa88ae9fd8b41ae42743341316c90f7Neal NorwitzWARNING = 30 966fa635df7aa88ae9fd8b41ae42743341316c90f7Neal NorwitzWARN = WARNING 9757102f861d506b6c2d2215d100dac9143574fa77Guido van RossumINFO = 20 9857102f861d506b6c2d2215d100dac9143574fa77Guido van RossumDEBUG = 10 9957102f861d506b6c2d2215d100dac9143574fa77Guido van RossumNOTSET = 0 10057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 1013b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip_levelToName = { 1023b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip CRITICAL: 'CRITICAL', 1033b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip ERROR: 'ERROR', 1043b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip WARNING: 'WARNING', 1053b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip INFO: 'INFO', 1063b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip DEBUG: 'DEBUG', 1073b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip NOTSET: 'NOTSET', 1083b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip} 1093b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip_nameToLevel = { 1103b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip 'CRITICAL': CRITICAL, 1112500c9827886fb1826317877aacaef023707349eVinay Sajip 'FATAL': FATAL, 1123b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip 'ERROR': ERROR, 1133b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip 'WARN': WARNING, 1143b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip 'WARNING': WARNING, 1153b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip 'INFO': INFO, 1163b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip 'DEBUG': DEBUG, 1173b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip 'NOTSET': NOTSET, 11857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum} 11957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 12057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumdef getLevelName(level): 12157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 12257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Return the textual representation of logging level 'level'. 12357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 1246fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz If the level is one of the predefined levels (CRITICAL, ERROR, WARNING, 12557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum INFO, DEBUG) then you get the corresponding string. If you have 12657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum associated levels with names using addLevelName then the name you have 127779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip associated with 'level' is returned. 128779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip 129779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip If a numeric value corresponding to one of the defined levels is passed 130779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip in, the corresponding string representation is returned. 131779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip 132779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip Otherwise, the string "Level %s" % level is returned. 13357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 134924aaae4c2a99015ca6b448f16eed31bbb598b98Vinay Sajip # See Issues #22386, #27937 and #29220 for why it's this way 135924aaae4c2a99015ca6b448f16eed31bbb598b98Vinay Sajip result = _levelToName.get(level) 136924aaae4c2a99015ca6b448f16eed31bbb598b98Vinay Sajip if result is not None: 137924aaae4c2a99015ca6b448f16eed31bbb598b98Vinay Sajip return result 138924aaae4c2a99015ca6b448f16eed31bbb598b98Vinay Sajip result = _nameToLevel.get(level) 139924aaae4c2a99015ca6b448f16eed31bbb598b98Vinay Sajip if result is not None: 140924aaae4c2a99015ca6b448f16eed31bbb598b98Vinay Sajip return result 141924aaae4c2a99015ca6b448f16eed31bbb598b98Vinay Sajip return "Level %s" % level 14257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 14357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumdef addLevelName(level, levelName): 14457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 14557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Associate 'levelName' with 'level'. 14657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 14757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum This is used when converting levels to text during message formatting. 14857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 14957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum _acquireLock() 15057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum try: #unlikely to cause an exception, but you never know... 1513b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip _levelToName[level] = levelName 1523b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip _nameToLevel[levelName] = level 15357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum finally: 15457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum _releaseLock() 15557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 156194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajipif hasattr(sys, '_getframe'): 157194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip currentframe = lambda: sys._getframe(3) 158194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajipelse: #pragma: no cover 159194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip def currentframe(): 160194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip """Return the frame object for the caller's stack frame.""" 161194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip try: 162194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip raise Exception 163194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip except Exception: 164194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip return sys.exc_info()[2].tb_frame.f_back 165194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip 166194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# 167194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# _srcfile is used when walking the stack to check when we've got the first 168194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# caller stack frame, by skipping frames whose filename is that of this 169194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# module's source. It therefore should contain the filename of this module's 170194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# source file. 171194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# 172194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# Ordinarily we would use __file__ for this, but frozen modules don't always 173194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# have __file__ set, for some reason (see Issue #21736). Thus, we get the 174194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# filename from a handy code object from a function defined in this module. 175194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# (There's no particular reason for picking addLevelName.) 176194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# 177194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip 178194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip_srcfile = os.path.normcase(addLevelName.__code__.co_filename) 179194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip 180194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# _srcfile is only used in conjunction with sys._getframe(). 181194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# To provide compatibility with older versions of Python, set _srcfile 182194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# to None if _getframe() is not available; this value will prevent 183194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# findCaller() from being called. You can also do this if you want to avoid 184194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# the overhead of fetching caller information, even when _getframe() is 185194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# available. 186194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip#if not hasattr(sys, '_getframe'): 187194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip# _srcfile = None 188194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip 189194bcaf4dc4a7cfcfd33ff90dd22178df28f78d7Vinay Sajip 190d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajipdef _checkLevel(level): 191d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajip if isinstance(level, int): 192d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajip rv = level 193d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajip elif str(level) == level: 1943b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip if level not in _nameToLevel: 195d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajip raise ValueError("Unknown level: %r" % level) 1963b84eae03ebd8122fdbdced3d85999dd9aedfc7eVinay Sajip rv = _nameToLevel[level] 197d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajip else: 198d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajip raise TypeError("Level not an integer or a valid string: %r" % level) 199d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajip return rv 200d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajip 20157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 20257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Thread-related stuff 20357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 20457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 20557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 20657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#_lock is used to serialize access to shared data structures in this module. 2075554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson#This needs to be an RLock because fileConfig() creates and configures 2085554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson#Handlers, and so might arbitrary user threads. Since Handler code updates the 2095554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson#shared dictionary _handlers, it needs to acquire the lock. But if configuring, 21057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#the lock would already have been acquired - so we need an RLock. 21157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#The same argument applies to Loggers and Manager.loggerDict. 21257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 2132a12974bca2433eea0131d904a423ed8234dcf7aVictor Stinnerif threading: 21403f6c11f07f7f7163186c7f8cb9da086ba703162Vinay Sajip _lock = threading.RLock() 21526fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay Sajipelse: #pragma: no cover 21603f6c11f07f7f7163186c7f8cb9da086ba703162Vinay Sajip _lock = None 21703f6c11f07f7f7163186c7f8cb9da086ba703162Vinay Sajip 21857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 21957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumdef _acquireLock(): 22057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 22157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Acquire the module-level lock for serializing access to shared data. 22257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 22357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum This should be released with _releaseLock(). 22457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 22557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if _lock: 22657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum _lock.acquire() 22757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 22857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumdef _releaseLock(): 22957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 23057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Release the module-level lock acquired by calling _acquireLock(). 23157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 23257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if _lock: 23357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum _lock.release() 23457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 23557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 23657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# The logging record 23757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 23857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 2395554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Petersonclass LogRecord(object): 24057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 24157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum A LogRecord instance represents an event being logged. 24257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 24357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum LogRecord instances are created every time something is logged. They 24457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum contain all the information pertinent to the event being logged. The 24557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum main information passed in is in msg and args, which are combined 24657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum using str(msg) % args to create the message field of the record. The 24757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum record also includes information such as when the record was created, 24857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum the source line where the logging call was made, and any exception 24957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum information to be logged. 25057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 251ed1992f2aa29d433a56f26e28bfb12f0ddc21b95Vinay Sajip def __init__(self, name, level, pathname, lineno, 252615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip msg, args, exc_info, func=None, sinfo=None, **kwargs): 25357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 25457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Initialize a logging record with interesting information. 25557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 25657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum ct = time.time() 25757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.name = name 25857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.msg = msg 2594ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip # 2604ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip # The following statement allows passing of a dictionary as a sole 2614ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip # argument, so that you can do something like 2624ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2}) 2634ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip # Suggested by Stefan Behnel. 2644ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip # Note that without the test for args[0], we get a problem because 2654ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip # during formatting, we test to see if the arg is present using 2664ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip # 'if self.args:'. If the event being logged is e.g. 'Value is %d' 2674ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip # and if the passed arg fails 'if self.args:' then no formatting 2680a889534e7e4beb41fc3a6837501b68a24139083Vinay Sajip # is done. For example, logger.warning('Value is %d', 0) would log 2694ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip # 'Value is %d' instead of 'Value is 0'. 2704ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip # For the use case of passing a dictionary, this should not be a 2714ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip # problem. 2721b7611405d80df5387cad6492b7b12436450ccedVinay Sajip # Issue #21172: a request was made to relax the isinstance check 2731b7611405d80df5387cad6492b7b12436450ccedVinay Sajip # to hasattr(args[0], '__getitem__'). However, the docs on string 2741b7611405d80df5387cad6492b7b12436450ccedVinay Sajip # formatting still seem to suggest a mapping object is required. 2751b7611405d80df5387cad6492b7b12436450ccedVinay Sajip # Thus, while not removing the isinstance check, it does now look 2761b7611405d80df5387cad6492b7b12436450ccedVinay Sajip # for collections.Mapping rather than, as before, dict. 2771b7611405d80df5387cad6492b7b12436450ccedVinay Sajip if (args and len(args) == 1 and isinstance(args[0], collections.Mapping) 2781b7611405d80df5387cad6492b7b12436450ccedVinay Sajip and args[0]): 2794ed315ae6674e710c5374bda3660ede3a5f0a95cVinay Sajip args = args[0] 28057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.args = args 28157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.levelname = getLevelName(level) 28257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.levelno = level 28357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.pathname = pathname 28457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum try: 28557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.filename = os.path.basename(pathname) 28657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.module = os.path.splitext(self.filename)[0] 287902d6ebddd07a6086b54ae42929293418f0852d7Thomas Wouters except (TypeError, ValueError, AttributeError): 28857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.filename = pathname 28957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.module = "Unknown module" 29057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.exc_info = exc_info 291ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip self.exc_text = None # used to cache the traceback text 2928593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip self.stack_info = sinfo 29357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.lineno = lineno 294ed1992f2aa29d433a56f26e28bfb12f0ddc21b95Vinay Sajip self.funcName = func 29557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.created = ct 296e2a383d062434c05b73031f0da57fe82b9da8942Guido van Rossum self.msecs = (ct - int(ct)) * 1000 29757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.relativeCreated = (self.created - _startTime) * 1000 2982a12974bca2433eea0131d904a423ed8234dcf7aVictor Stinner if logThreads and threading: 2992a12974bca2433eea0131d904a423ed8234dcf7aVictor Stinner self.thread = threading.get_ident() 300727537077043bb03a0c9e537cacbb9e695f7f4a8Benjamin Peterson self.threadName = threading.current_thread().name 30126fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay Sajip else: # pragma: no cover 30257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.thread = None 3034a70486c37856c5e648e77e245c9a27a52fa157bVinay Sajip self.threadName = None 30426fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay Sajip if not logMultiprocessing: # pragma: no cover 3059a0fc97bf4a336d81160b19a52ab4f5d2e2317e0Jesse Noller self.processName = None 3064ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson else: 30722005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson self.processName = 'MainProcess' 30822005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson mp = sys.modules.get('multiprocessing') 30922005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson if mp is not None: 31022005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson # Errors may occur if multiprocessing has not finished loading 31122005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson # yet - e.g. if a custom import hook causes third-party code 31222005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson # to run when multiprocessing calls import. See issue 8200 31322005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson # for an example 31422005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson try: 31522005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson self.processName = mp.current_process().name 3169b727eca26ac97e2029dff669cf031d3ae5150c2Vinay Sajip except Exception: #pragma: no cover 31722005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson pass 318d364a07517bb2a413e5d4739c2f43c4af218be43Vinay Sajip if logProcesses and hasattr(os, 'getpid'): 3194c641d0ce1cc764f300e8c6863eaaf37c956a8d2Jack Jansen self.process = os.getpid() 3204c641d0ce1cc764f300e8c6863eaaf37c956a8d2Jack Jansen else: 3214c641d0ce1cc764f300e8c6863eaaf37c956a8d2Jack Jansen self.process = None 32257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 32357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def __str__(self): 32457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno, 32557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.pathname, self.lineno, self.msg) 32657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 32702980426d001dfdcdf683476184b43ab1b1dd5b8Vinay Sajip __repr__ = __str__ 32802980426d001dfdcdf683476184b43ab1b1dd5b8Vinay Sajip 32957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def getMessage(self): 33057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 33157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Return the message for this LogRecord. 33257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 33357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Return the message for this LogRecord after merging any user-supplied 33457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum arguments with the message. 33557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 336dc5097ff07f246bac461939ab6a6cba5d71b78c8Vinay Sajip msg = str(self.msg) 33757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if self.args: 33857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum msg = msg % self.args 33957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return msg 34057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 341062d56b1f04122cd631a1d0815d4505598a5183dVinay Sajip# 342062d56b1f04122cd631a1d0815d4505598a5183dVinay Sajip# Determine which class to use when instantiating log records. 343062d56b1f04122cd631a1d0815d4505598a5183dVinay Sajip# 344615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip_logRecordFactory = LogRecord 345062d56b1f04122cd631a1d0815d4505598a5183dVinay Sajip 346615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajipdef setLogRecordFactory(factory): 347062d56b1f04122cd631a1d0815d4505598a5183dVinay Sajip """ 348fad058f0caca689fffad29617d0858caa13291adVinay Sajip Set the factory to be used when instantiating a log record. 349615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip 350615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip :param factory: A callable which will be called to instantiate 351615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip a log record. 352062d56b1f04122cd631a1d0815d4505598a5183dVinay Sajip """ 353615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip global _logRecordFactory 354615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip _logRecordFactory = factory 355062d56b1f04122cd631a1d0815d4505598a5183dVinay Sajip 356615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajipdef getLogRecordFactory(): 357062d56b1f04122cd631a1d0815d4505598a5183dVinay Sajip """ 358fad058f0caca689fffad29617d0858caa13291adVinay Sajip Return the factory to be used when instantiating a log record. 359062d56b1f04122cd631a1d0815d4505598a5183dVinay Sajip """ 360062d56b1f04122cd631a1d0815d4505598a5183dVinay Sajip 361615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip return _logRecordFactory 362062d56b1f04122cd631a1d0815d4505598a5183dVinay Sajip 3636f3eaa67e51ed0c1b493a26afdf4417d4105d96dRaymond Hettingerdef makeLogRecord(dict): 3646f3eaa67e51ed0c1b493a26afdf4417d4105d96dRaymond Hettinger """ 3656f3eaa67e51ed0c1b493a26afdf4417d4105d96dRaymond Hettinger Make a LogRecord whose attributes are defined by the specified dictionary, 3666f3eaa67e51ed0c1b493a26afdf4417d4105d96dRaymond Hettinger This function is useful for converting a logging event received over 3676f3eaa67e51ed0c1b493a26afdf4417d4105d96dRaymond Hettinger a socket connection (which is sent as a dictionary) into a LogRecord 3686f3eaa67e51ed0c1b493a26afdf4417d4105d96dRaymond Hettinger instance. 3696f3eaa67e51ed0c1b493a26afdf4417d4105d96dRaymond Hettinger """ 370615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip rv = _logRecordFactory(None, None, "", 0, "", (), None, None) 3716f3eaa67e51ed0c1b493a26afdf4417d4105d96dRaymond Hettinger rv.__dict__.update(dict) 3726f3eaa67e51ed0c1b493a26afdf4417d4105d96dRaymond Hettinger return rv 3736f3eaa67e51ed0c1b493a26afdf4417d4105d96dRaymond Hettinger 37457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 37557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Formatter classes and functions 37657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 37757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 3786a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajipclass PercentStyle(object): 3796a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 3806a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip default_format = '%(message)s' 3816a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip asctime_format = '%(asctime)s' 38210914b7473262a108b1de4a72c90d1203471102eVinay Sajip asctime_search = '%(asctime)' 3836a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 3846a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip def __init__(self, fmt): 3856a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip self._fmt = fmt or self.default_format 3866a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 3876a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip def usesTime(self): 38810914b7473262a108b1de4a72c90d1203471102eVinay Sajip return self._fmt.find(self.asctime_search) >= 0 3896a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 3906a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip def format(self, record): 3916a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip return self._fmt % record.__dict__ 3926a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 3936a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajipclass StrFormatStyle(PercentStyle): 3946a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip default_format = '{message}' 3956a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip asctime_format = '{asctime}' 39610914b7473262a108b1de4a72c90d1203471102eVinay Sajip asctime_search = '{asctime' 3976a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 3986a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip def format(self, record): 3996a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip return self._fmt.format(**record.__dict__) 4006a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 4016a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 4026a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajipclass StringTemplateStyle(PercentStyle): 4036a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip default_format = '${message}' 4046a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip asctime_format = '${asctime}' 40589807a5277be5733c7a8308867103bd75a1ece23Vinay Sajip asctime_search = '${asctime}' 4066a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 4076a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip def __init__(self, fmt): 4086a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip self._fmt = fmt or self.default_format 4096a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip self._tpl = Template(self._fmt) 4106a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 4116a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip def usesTime(self): 4126a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip fmt = self._fmt 4136a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_format) >= 0 4146a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 4156a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip def format(self, record): 4166a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip return self._tpl.substitute(**record.__dict__) 4176a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 4181fd1202072e198a7b3cf1254787aff3e3bf1c99eVinay SajipBASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s" 4191fd1202072e198a7b3cf1254787aff3e3bf1c99eVinay Sajip 4206a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip_STYLES = { 4211fd1202072e198a7b3cf1254787aff3e3bf1c99eVinay Sajip '%': (PercentStyle, BASIC_FORMAT), 4221fd1202072e198a7b3cf1254787aff3e3bf1c99eVinay Sajip '{': (StrFormatStyle, '{levelname}:{name}:{message}'), 4231fd1202072e198a7b3cf1254787aff3e3bf1c99eVinay Sajip '$': (StringTemplateStyle, '${levelname}:${name}:${message}'), 4246a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip} 4256a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip 4265554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Petersonclass Formatter(object): 42757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 42857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Formatter instances are used to convert a LogRecord to text. 42957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 43057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Formatters need to know how a LogRecord is constructed. They are 43157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum responsible for converting a LogRecord to (usually) a string which can 43257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum be interpreted by either a human or an external system. The base Formatter 43357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum allows a formatting string to be specified. If none is supplied, the 4342a20dfc2aabc3259d5b4276eeec91f83230fdcacVinay Sajip default value of "%s(message)" is used. 43557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 43657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum The Formatter can be initialized with a format string which makes use of 43757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum knowledge of the LogRecord attributes - e.g. the default value mentioned 43857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum above makes use of the fact that the user's message and arguments are pre- 43957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum formatted into a LogRecord's message attribute. Currently, the useful 44057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum attributes in a LogRecord are described by: 44157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 44257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(name)s Name of the logger (logging channel) 44357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(levelno)s Numeric logging level for the message (DEBUG, INFO, 4446fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz WARNING, ERROR, CRITICAL) 44557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(levelname)s Text logging level for the message ("DEBUG", "INFO", 4466fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz "WARNING", "ERROR", "CRITICAL") 44757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(pathname)s Full pathname of the source file where the logging 44857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum call was issued (if available) 44957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(filename)s Filename portion of pathname 45057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(module)s Module (name portion of filename) 45157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(lineno)d Source line number where the logging call was issued 45257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum (if available) 453ed1992f2aa29d433a56f26e28bfb12f0ddc21b95Vinay Sajip %(funcName)s Function name 45457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(created)f Time when the LogRecord was created (time.time() 45557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return value) 45657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(asctime)s Textual time when the LogRecord was created 45757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(msecs)d Millisecond portion of the creation time 45857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(relativeCreated)d Time in milliseconds when the LogRecord was created, 45957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum relative to the time the logging module was loaded 46057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum (typically at application startup time) 46157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(thread)d Thread ID (if available) 4624a70486c37856c5e648e77e245c9a27a52fa157bVinay Sajip %(threadName)s Thread name (if available) 4636fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz %(process)d Process ID (if available) 46457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum %(message)s The result of record.getMessage(), computed just as 46557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum the record is emitted 46657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 46757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 46857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum converter = time.localtime 46957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 470a39c571061658967918276224a4992d1b421ae3fVinay Sajip def __init__(self, fmt=None, datefmt=None, style='%'): 47157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 47257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Initialize the formatter with specified format strings. 47357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 47457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Initialize the formatter either with the specified format string, or a 47557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum default as described above. Allow for specialized date formatting with 47657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum the optional datefmt argument (if omitted, you get the ISO8601 format). 477a39c571061658967918276224a4992d1b421ae3fVinay Sajip 478a39c571061658967918276224a4992d1b421ae3fVinay Sajip Use a style parameter of '%', '{' or '$' to specify that you want to 479a39c571061658967918276224a4992d1b421ae3fVinay Sajip use one of %-formatting, :meth:`str.format` (``{}``) formatting or 480a39c571061658967918276224a4992d1b421ae3fVinay Sajip :class:`string.Template` formatting in your format string. 481a39c571061658967918276224a4992d1b421ae3fVinay Sajip 4828c16cb9f65bfc7d732bc6bd3f533856795a95690Georg Brandl .. versionchanged:: 3.2 483a39c571061658967918276224a4992d1b421ae3fVinay Sajip Added the ``style`` parameter. 48457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 4856a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip if style not in _STYLES: 4866a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip raise ValueError('Style must be one of: %s' % ','.join( 4876a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip _STYLES.keys())) 4881fd1202072e198a7b3cf1254787aff3e3bf1c99eVinay Sajip self._style = _STYLES[style][0](fmt) 4896a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip self._fmt = self._style._fmt 49057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.datefmt = datefmt 49157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 492ae5740f139304a2d032602f17b87ec485aa4c750Vinay Sajip default_time_format = '%Y-%m-%d %H:%M:%S' 493ae5740f139304a2d032602f17b87ec485aa4c750Vinay Sajip default_msec_format = '%s,%03d' 494ae5740f139304a2d032602f17b87ec485aa4c750Vinay Sajip 49557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def formatTime(self, record, datefmt=None): 49657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 49757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Return the creation time of the specified LogRecord as formatted text. 49857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 49957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum This method should be called from format() by a formatter which 50057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum wants to make use of a formatted time. This method can be overridden 50157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum in formatters to provide for any specific requirement, but the 50257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum basic behaviour is as follows: if datefmt (a string) is specified, 50357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum it is used with time.strftime() to format the creation time of the 50457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum record. Otherwise, the ISO8601 format is used. The resulting 50557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum string is returned. This function uses a user-configurable function 50657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum to convert the creation time to a tuple. By default, time.localtime() 50757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum is used; to change this for a particular formatter instance, set the 50857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 'converter' attribute to a function with the same signature as 50957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum time.localtime() or time.gmtime(). To change it for all formatters, 51057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum for example if you want all logging times to be shown in GMT, 51157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum set the 'converter' attribute in the Formatter class. 51257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 51357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum ct = self.converter(record.created) 51457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if datefmt: 51557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum s = time.strftime(datefmt, ct) 51657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum else: 517ae5740f139304a2d032602f17b87ec485aa4c750Vinay Sajip t = time.strftime(self.default_time_format, ct) 518ae5740f139304a2d032602f17b87ec485aa4c750Vinay Sajip s = self.default_msec_format % (t, record.msecs) 51957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return s 52057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 52157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def formatException(self, ei): 52257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 52357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Format and return the specified exception information as a string. 52457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 52557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum This default implementation just uses 52657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum traceback.print_exception() 52757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 52834d1928766bcae11d8f679a6bf361d9210b6429eGuido van Rossum sio = io.StringIO() 52940d9a4e854d71a9c307f4f92a1e8336b4714a3c8Vinay Sajip tb = ei[2] 53040d9a4e854d71a9c307f4f92a1e8336b4714a3c8Vinay Sajip # See issues #9427, #1553375. Commented out for now. 53140d9a4e854d71a9c307f4f92a1e8336b4714a3c8Vinay Sajip #if getattr(self, 'fullstack', False): 53240d9a4e854d71a9c307f4f92a1e8336b4714a3c8Vinay Sajip # traceback.print_stack(tb.tb_frame.f_back, file=sio) 53340d9a4e854d71a9c307f4f92a1e8336b4714a3c8Vinay Sajip traceback.print_exception(ei[0], ei[1], tb, None, sio) 53457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum s = sio.getvalue() 53557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum sio.close() 536486364b821ad25bc33e7247539d2c48a9e3b7051Guido van Rossum if s[-1:] == "\n": 53757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum s = s[:-1] 53857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return s 53957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 5409451a1c6ae14cc31ea88eaaf68d5a8f946b82831Benjamin Peterson def usesTime(self): 5419451a1c6ae14cc31ea88eaaf68d5a8f946b82831Benjamin Peterson """ 5429451a1c6ae14cc31ea88eaaf68d5a8f946b82831Benjamin Peterson Check if the format uses the creation time of the record. 5439451a1c6ae14cc31ea88eaaf68d5a8f946b82831Benjamin Peterson """ 5446a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip return self._style.usesTime() 5459451a1c6ae14cc31ea88eaaf68d5a8f946b82831Benjamin Peterson 546d0557bfe77eeedf9f59e6ba2954ab785095244dcVinay Sajip def formatMessage(self, record): 5476a65c5df869f2526711ff00c07ca28e2dc394372Vinay Sajip return self._style.format(record) 548d0557bfe77eeedf9f59e6ba2954ab785095244dcVinay Sajip 5498593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip def formatStack(self, stack_info): 5508593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip """ 5518593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip This method is provided as an extension point for specialized 5528593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip formatting of stack information. 5538593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip 5548593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip The input data is a string as returned from a call to 5558593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip :func:`traceback.print_stack`, but with the last trailing newline 5568593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip removed. 5578593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip 5588593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip The base implementation just returns the value passed in. 5598593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip """ 5608593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip return stack_info 5618593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip 56257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def format(self, record): 56357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 56457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Format the specified record as text. 56557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 56657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum The record's attribute dictionary is used as the operand to a 56757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum string formatting operation which yields the returned string. 56857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Before formatting the dictionary, a couple of preparatory steps 56957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum are carried out. The message attribute of the record is computed 5709451a1c6ae14cc31ea88eaaf68d5a8f946b82831Benjamin Peterson using LogRecord.getMessage(). If the formatting string uses the 5719451a1c6ae14cc31ea88eaaf68d5a8f946b82831Benjamin Peterson time (as determined by a call to usesTime(), formatTime() is 5729451a1c6ae14cc31ea88eaaf68d5a8f946b82831Benjamin Peterson called to format the event time. If there is exception information, 5739451a1c6ae14cc31ea88eaaf68d5a8f946b82831Benjamin Peterson it is formatted using formatException() and appended to the message. 57457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 57557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum record.message = record.getMessage() 5769451a1c6ae14cc31ea88eaaf68d5a8f946b82831Benjamin Peterson if self.usesTime(): 57757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum record.asctime = self.formatTime(record, self.datefmt) 578d0557bfe77eeedf9f59e6ba2954ab785095244dcVinay Sajip s = self.formatMessage(record) 57957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if record.exc_info: 580ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip # Cache the traceback text to avoid converting it multiple times 581ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip # (it's constant anyway) 582ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip if not record.exc_text: 583ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip record.exc_text = self.formatException(record.exc_info) 584ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip if record.exc_text: 585486364b821ad25bc33e7247539d2c48a9e3b7051Guido van Rossum if s[-1:] != "\n": 58657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum s = s + "\n" 587ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip s = s + record.exc_text 5888593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip if record.stack_info: 5898593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip if s[-1:] != "\n": 5908593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip s = s + "\n" 5918593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip s = s + self.formatStack(record.stack_info) 59257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return s 59357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 59457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 59557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# The default formatter to use when no other is specified 59657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 59757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum_defaultFormatter = Formatter() 59857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 5995554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Petersonclass BufferingFormatter(object): 60057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 60157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum A formatter suitable for formatting a number of records. 60257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 60357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def __init__(self, linefmt=None): 60457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 60557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Optionally specify a formatter which will be used to format each 60657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum individual record. 60757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 60857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if linefmt: 60957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.linefmt = linefmt 61057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum else: 61157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.linefmt = _defaultFormatter 61257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 61357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def formatHeader(self, records): 61457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 61557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Return the header string for the specified records. 61657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 61757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return "" 61857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 61957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def formatFooter(self, records): 62057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 62157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Return the footer string for the specified records. 62257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 62357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return "" 62457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 62557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def format(self, records): 62657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 62757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Format the specified records and return the result as a string. 62857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 62957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum rv = "" 63057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if len(records) > 0: 63157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum rv = rv + self.formatHeader(records) 63257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum for record in records: 63357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum rv = rv + self.linefmt.format(record) 63457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum rv = rv + self.formatFooter(records) 63557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return rv 63657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 63757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 63857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Filter classes and functions 63957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 64057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 6415554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Petersonclass Filter(object): 64257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 64357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Filter instances are used to perform arbitrary filtering of LogRecords. 64457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 64557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Loggers and Handlers can optionally use Filter instances to filter 64657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum records as desired. The base filter class only allows events which are 64757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum below a certain point in the logger hierarchy. For example, a filter 64857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum initialized with "A.B" will allow events logged by loggers "A.B", 64957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If 65057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum initialized with the empty string, all events are passed. 65157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 65257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def __init__(self, name=''): 65357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 65457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Initialize a filter. 65557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 65657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Initialize with the name of the logger which, together with its 65757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum children, will have its events allowed through the filter. If no 65857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum name is specified, allow every event. 65957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 66057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.name = name 66157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.nlen = len(name) 66257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 66357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def filter(self, record): 66457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 66557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Determine if the specified record is to be logged. 66657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 66757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Is the specified record to be logged? Returns 0 for no, nonzero for 66857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum yes. If deemed appropriate, the record may be modified in-place. 66957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 67057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if self.nlen == 0: 67126fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay Sajip return True 67257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum elif self.name == record.name: 67326fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay Sajip return True 6749d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz elif record.name.find(self.name, 0, self.nlen) != 0: 67526fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay Sajip return False 67657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return (record.name[self.nlen] == ".") 67757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 6785554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Petersonclass Filterer(object): 67957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 68057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum A base class for loggers and handlers which allows them to share 68157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum common code. 68257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 68357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def __init__(self): 68457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 68557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Initialize the list of filters to be an empty list. 68657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 68757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.filters = [] 68857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 68957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def addFilter(self, filter): 69057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 69157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Add the specified filter to this handler. 69257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 69357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if not (filter in self.filters): 69457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.filters.append(filter) 69557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 69657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def removeFilter(self, filter): 69757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 69857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Remove the specified filter from this handler. 69957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 70057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if filter in self.filters: 70157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.filters.remove(filter) 70257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 70357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def filter(self, record): 70457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 70557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Determine if a record is loggable by consulting all the filters. 70657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 70757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum The default is to allow the record to be logged; any filter can veto 70857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum this and the record is then dropped. Returns a zero value if a record 70957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum is to be dropped, else non-zero. 7106dbed2e8b3fb90b25e2b99c5e522a5205626d07eVinay Sajip 7118c16cb9f65bfc7d732bc6bd3f533856795a95690Georg Brandl .. versionchanged:: 3.2 7126dbed2e8b3fb90b25e2b99c5e522a5205626d07eVinay Sajip 7136dbed2e8b3fb90b25e2b99c5e522a5205626d07eVinay Sajip Allow filters to be just callables. 71457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 715312cc0d28e86d36c1430814c91f9c1bb6087d588Vinay Sajip rv = True 71657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum for f in self.filters: 7176dbed2e8b3fb90b25e2b99c5e522a5205626d07eVinay Sajip if hasattr(f, 'filter'): 7186dbed2e8b3fb90b25e2b99c5e522a5205626d07eVinay Sajip result = f.filter(record) 7196dbed2e8b3fb90b25e2b99c5e522a5205626d07eVinay Sajip else: 720fc082cafa6076ab3ef06638643d93a6313f36e72Vinay Sajip result = f(record) # assume callable - will raise if not 7216dbed2e8b3fb90b25e2b99c5e522a5205626d07eVinay Sajip if not result: 722312cc0d28e86d36c1430814c91f9c1bb6087d588Vinay Sajip rv = False 72357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum break 72457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return rv 72557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 72657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 72757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Handler classes and functions 72857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 72957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 7305554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson_handlers = weakref.WeakValueDictionary() #map of handler names to handlers 7310ee9ba258ec8fd3c600d6ffa28091f2c6fa8d40cVinay Sajip_handlerList = [] # added to allow handlers to be removed in reverse of order initialized 73257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 7335554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Petersondef _removeHandlerRef(wr): 7345554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson """ 7355554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson Remove a handler reference from the internal cleanup list. 7365554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson """ 737de6e9d615ddada40fb0ee4e005777eb73a147058Vinay Sajip # This function can be called during module teardown, when globals are 738156307bfd67aacbdeb393c6bf831b6a63df92eb2Vinay Sajip # set to None. It can also be called from another thread. So we need to 739156307bfd67aacbdeb393c6bf831b6a63df92eb2Vinay Sajip # pre-emptively grab the necessary globals and check if they're None, 740156307bfd67aacbdeb393c6bf831b6a63df92eb2Vinay Sajip # to prevent race conditions and failures during interpreter shutdown. 741156307bfd67aacbdeb393c6bf831b6a63df92eb2Vinay Sajip acquire, release, handlers = _acquireLock, _releaseLock, _handlerList 742156307bfd67aacbdeb393c6bf831b6a63df92eb2Vinay Sajip if acquire and release and handlers: 743156307bfd67aacbdeb393c6bf831b6a63df92eb2Vinay Sajip acquire() 744de6e9d615ddada40fb0ee4e005777eb73a147058Vinay Sajip try: 745156307bfd67aacbdeb393c6bf831b6a63df92eb2Vinay Sajip if wr in handlers: 746156307bfd67aacbdeb393c6bf831b6a63df92eb2Vinay Sajip handlers.remove(wr) 747de6e9d615ddada40fb0ee4e005777eb73a147058Vinay Sajip finally: 748156307bfd67aacbdeb393c6bf831b6a63df92eb2Vinay Sajip release() 7495554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson 7505554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Petersondef _addHandlerRef(handler): 7515554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson """ 7525554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson Add a handler to the internal cleanup list using a weak reference. 7535554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson """ 7545554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson _acquireLock() 7555554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson try: 7565554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson _handlerList.append(weakref.ref(handler, _removeHandlerRef)) 7575554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson finally: 7585554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson _releaseLock() 7595554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson 76057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumclass Handler(Filterer): 76157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 76257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Handler instances dispatch logging events to specific destinations. 76357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 76457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum The base handler class. Acts as a placeholder which defines the Handler 76557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum interface. Handlers can optionally use Formatter instances to format 76657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum records as desired. By default, no formatter is specified; in this case, 76757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum the 'raw' message as determined by record.message is logged. 76857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 76957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def __init__(self, level=NOTSET): 77057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 77157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Initializes the instance - basically setting the formatter to None 77257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum and the filter list to empty. 77357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 77457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Filterer.__init__(self) 7755554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson self._name = None 776d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajip self.level = _checkLevel(level) 77757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.formatter = None 7785554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson # Add the handler to the global _handlerList (for cleanup on shutdown) 7795554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson _addHandlerRef(self) 7805554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson self.createLock() 7815554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson 7825554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson def get_name(self): 7835554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson return self._name 7845554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson 7855554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson def set_name(self, name): 78657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum _acquireLock() 7875554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson try: 7885554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson if self._name in _handlers: 7895554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson del _handlers[self._name] 7905554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson self._name = name 7915554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson if name: 7925554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson _handlers[name] = self 79357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum finally: 79457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum _releaseLock() 7955554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson 7965554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson name = property(get_name, set_name) 79757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 79857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def createLock(self): 79957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 80057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Acquire a thread lock for serializing access to the underlying I/O. 80157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 8022a12974bca2433eea0131d904a423ed8234dcf7aVictor Stinner if threading: 8034a70486c37856c5e648e77e245c9a27a52fa157bVinay Sajip self.lock = threading.RLock() 80426fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay Sajip else: #pragma: no cover 80557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.lock = None 80657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 80757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def acquire(self): 80857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 80957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Acquire the I/O thread lock. 81057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 81157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if self.lock: 81257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.lock.acquire() 81357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 81457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def release(self): 81557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 81657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Release the I/O thread lock. 81757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 81857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if self.lock: 81957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.lock.release() 82057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 82157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def setLevel(self, level): 82257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 823e85488c6f4d01ad53e0836e90fcd6095d0a7a987Gregory P. Smith Set the logging level of this handler. level must be an int or a str. 82457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 825d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajip self.level = _checkLevel(level) 82657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 82757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def format(self, record): 82857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 82957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Format the specified record. 83057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 83157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum If a formatter is set, use it. Otherwise, use the default formatter 83257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum for the module. 83357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 83457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if self.formatter: 83557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum fmt = self.formatter 83657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum else: 83757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum fmt = _defaultFormatter 83857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return fmt.format(record) 83957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 84057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def emit(self, record): 84157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 84257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Do whatever it takes to actually log the specified logging record. 84357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 84457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum This version is intended to be implemented by subclasses and so 84557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum raises a NotImplementedError. 84657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 847ce36ad8a467d914eb5c91f33835b9eaea18ee93bCollin Winter raise NotImplementedError('emit must be implemented ' 848ce36ad8a467d914eb5c91f33835b9eaea18ee93bCollin Winter 'by Handler subclasses') 84957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 85057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def handle(self, record): 85157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 85257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Conditionally emit the specified logging record. 85357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 85457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Emission depends on filters which may have been added to the handler. 85557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Wrap the actual emission of the record with acquisition/release of 8566fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz the I/O thread lock. Returns whether the filter passed the record for 8576fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz emission. 85857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 8596fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz rv = self.filter(record) 8606fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz if rv: 86157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.acquire() 86257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum try: 86357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.emit(record) 86457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum finally: 86557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.release() 8666fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz return rv 86757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 86857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def setFormatter(self, fmt): 86957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 87057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Set the formatter for this handler. 87157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 87257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.formatter = fmt 87357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 87457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def flush(self): 87557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 87657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Ensure all logging output has been flushed. 87757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 87857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum This version does nothing and is intended to be implemented by 87957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum subclasses. 88057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 88157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum pass 88257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 88357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def close(self): 88457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 88557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Tidy up any resources used by the handler. 88657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 8875554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson This version removes the handler from an internal map of handlers, 8885554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson _handlers, which is used for handler lookup by name. Subclasses 889ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip should ensure that this gets called from overridden close() 890ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip methods. 89157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 892ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip #get the module data lock, as we're updating a shared structure. 893ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip _acquireLock() 894ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip try: #unlikely to raise an exception, but you never know... 8955554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson if self._name and self._name in _handlers: 8965554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson del _handlers[self._name] 897ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip finally: 898ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip _releaseLock() 89957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 9006fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz def handleError(self, record): 90157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 90257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Handle errors which occur during an emit() call. 90357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 90457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum This method should be called from handlers when an exception is 9056fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz encountered during an emit() call. If raiseExceptions is false, 90657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum exceptions get silently ignored. This is what is mostly wanted 90757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum for a logging system - most users will not care about errors in 90857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum the logging system, they are more interested in application errors. 90957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum You could, however, replace this with a custom handler if you wish. 9106fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz The record which was being processed is passed in to this method. 91157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 912889bb2969d00a548279c7e4dd237c23b100548e2Vinay Sajip if raiseExceptions and sys.stderr: # see issue 13807 913d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip t, v, tb = sys.exc_info() 914fa0d7034339fee79cf5f095ee48488ea13a3fc4bBenjamin Peterson try: 915d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip sys.stderr.write('--- Logging error ---\n') 916d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip traceback.print_exception(t, v, tb, None, sys.stderr) 917d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip sys.stderr.write('Call stack:\n') 918d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip # Walk the stack frame up until we're out of logging, 919d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip # so as to print the calling context. 920d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip frame = tb.tb_frame 921d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip while (frame and os.path.dirname(frame.f_code.co_filename) == 922d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip __path__[0]): 923d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip frame = frame.f_back 924d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip if frame: 925d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip traceback.print_stack(frame, file=sys.stderr) 926d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip else: 927d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip # couldn't find the right stack frame, for some reason 928d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip sys.stderr.write('Logged from file %s, line %s\n' % ( 929d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip record.filename, record.lineno)) 9303f58277382f3e337d225da547bdb26bc555570a4Vinay Sajip # Issue 18671: output logging message and arguments 931698abe75d4e44dfecb8e6b8aa421b8505d24be05Vinay Sajip try: 932698abe75d4e44dfecb8e6b8aa421b8505d24be05Vinay Sajip sys.stderr.write('Message: %r\n' 933698abe75d4e44dfecb8e6b8aa421b8505d24be05Vinay Sajip 'Arguments: %s\n' % (record.msg, 934698abe75d4e44dfecb8e6b8aa421b8505d24be05Vinay Sajip record.args)) 935698abe75d4e44dfecb8e6b8aa421b8505d24be05Vinay Sajip except Exception: 936698abe75d4e44dfecb8e6b8aa421b8505d24be05Vinay Sajip sys.stderr.write('Unable to print the message and arguments' 937698abe75d4e44dfecb8e6b8aa421b8505d24be05Vinay Sajip ' - possible formatting error.\nUse the' 938698abe75d4e44dfecb8e6b8aa421b8505d24be05Vinay Sajip ' traceback above to help find the error.\n' 939698abe75d4e44dfecb8e6b8aa421b8505d24be05Vinay Sajip ) 940f7a17b48d748e1835bcf9df86fb7fb318bb020f8Andrew Svetlov except OSError: #pragma: no cover 941fa0d7034339fee79cf5f095ee48488ea13a3fc4bBenjamin Peterson pass # see issue 5971 942fa0d7034339fee79cf5f095ee48488ea13a3fc4bBenjamin Peterson finally: 943d06d5403de5409be3db7c8218ecd8400cd94f40dVinay Sajip del t, v, tb 94457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 945c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip def __repr__(self): 946c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip level = getLevelName(self.level) 947c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip return '<%s (%s)>' % (self.__class__.__name__, level) 948c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip 94957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumclass StreamHandler(Handler): 95057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 95157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum A handler class which writes logging records, appropriately formatted, 95257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum to a stream. Note that this class does not close the stream, as 95357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum sys.stdout or sys.stderr may be used. 95457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 9553e4f055602496a7388058b4d5020b27d9ac7bd4bBenjamin Peterson 9562a20dfc2aabc3259d5b4276eeec91f83230fdcacVinay Sajip terminator = '\n' 9572a20dfc2aabc3259d5b4276eeec91f83230fdcacVinay Sajip 9584ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson def __init__(self, stream=None): 95957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 96057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Initialize the handler. 96157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 9624ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson If stream is not specified, sys.stderr is used. 96357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 96457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Handler.__init__(self) 9654ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson if stream is None: 9664ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson stream = sys.stderr 9674ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson self.stream = stream 96857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 96957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def flush(self): 97057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 97157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Flushes the stream. 97257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 973f05090372a43966266a8d20b9c21d348e417a48eVinay Sajip self.acquire() 974f05090372a43966266a8d20b9c21d348e417a48eVinay Sajip try: 9750abf61db4dd0d008ad06c84cd882fb84e5c11181Vinay Sajip if self.stream and hasattr(self.stream, "flush"): 9760abf61db4dd0d008ad06c84cd882fb84e5c11181Vinay Sajip self.stream.flush() 977f05090372a43966266a8d20b9c21d348e417a48eVinay Sajip finally: 978f05090372a43966266a8d20b9c21d348e417a48eVinay Sajip self.release() 97957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 98057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def emit(self, record): 98157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 98257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Emit a record. 98357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 98457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum If a formatter is specified, it is used to format the record. 9853e4f055602496a7388058b4d5020b27d9ac7bd4bBenjamin Peterson The record is then written to the stream with a trailing newline. If 9863e4f055602496a7388058b4d5020b27d9ac7bd4bBenjamin Peterson exception information is present, it is formatted using 9873e4f055602496a7388058b4d5020b27d9ac7bd4bBenjamin Peterson traceback.print_exception and appended to the stream. If the stream 98825c95f12987c08f446f355db6b9a807f3dea76a0Benjamin Peterson has an 'encoding' attribute, it is used to determine how to do the 9893e4f055602496a7388058b4d5020b27d9ac7bd4bBenjamin Peterson output to the stream. 99057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 99157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum try: 99257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum msg = self.format(record) 993f91df0465d96affeb101f9892e8e4aaa303192d9Benjamin Peterson stream = self.stream 9942a20dfc2aabc3259d5b4276eeec91f83230fdcacVinay Sajip stream.write(msg) 9952a20dfc2aabc3259d5b4276eeec91f83230fdcacVinay Sajip stream.write(self.terminator) 99657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.flush() 9978cf4eb1463217095e9276c0caacfb2df9372504fVinay Sajip except Exception: 9986fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz self.handleError(record) 99957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 1000c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip def __repr__(self): 1001c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip level = getLevelName(self.level) 1002c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip name = getattr(self.stream, 'name', '') 1003c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip if name: 1004c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip name += ' ' 1005c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip return '<%s %s(%s)>' % (self.__class__.__name__, name, level) 1006c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip 1007c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip 100857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumclass FileHandler(StreamHandler): 100957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 101057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum A handler class which writes formatted logging records to disk files. 101157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 101226fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay Sajip def __init__(self, filename, mode='a', encoding=None, delay=False): 101357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 101457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Open the specified file and use it as the stream for logging. 101557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 1016638e6220557db50b01653b410eb12f11b9b8ab1cVinay Sajip # Issue #27493: add support for Path objects to be passed in 1017638e6220557db50b01653b410eb12f11b9b8ab1cVinay Sajip filename = os.fspath(filename) 10184bbab2bde4fa7df27d9b9f04793d53d4754e22b4Vinay Sajip #keep the absolute path, otherwise derived classes which use this 10194bbab2bde4fa7df27d9b9f04793d53d4754e22b4Vinay Sajip #may come a cropper when the current directory changes 10204bbab2bde4fa7df27d9b9f04793d53d4754e22b4Vinay Sajip self.baseFilename = os.path.abspath(filename) 102157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.mode = mode 1022fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters self.encoding = encoding 102343c6ef189955474001aad75d3b47d895180b2d42Vinay Sajip self.delay = delay 1024e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes if delay: 10256268cbc77190cf6b4112a272f2870d5361903605Vinay Sajip #We don't open the stream, but we still need to call the 10266268cbc77190cf6b4112a272f2870d5361903605Vinay Sajip #Handler constructor to set level, formatter, lock etc. 10276268cbc77190cf6b4112a272f2870d5361903605Vinay Sajip Handler.__init__(self) 1028e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes self.stream = None 1029e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes else: 10306268cbc77190cf6b4112a272f2870d5361903605Vinay Sajip StreamHandler.__init__(self, self._open()) 103157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 103257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def close(self): 103357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 103457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Closes the stream. 103557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 1036f05090372a43966266a8d20b9c21d348e417a48eVinay Sajip self.acquire() 1037f05090372a43966266a8d20b9c21d348e417a48eVinay Sajip try: 10387e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka try: 10397e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka if self.stream: 10407e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka try: 10417e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka self.flush() 10427e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka finally: 10437e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka stream = self.stream 10447e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka self.stream = None 10457e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka if hasattr(stream, "close"): 10467e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka stream.close() 10477e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka finally: 10487e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka # Issue #19523: call unconditionally to 10497e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka # prevent a handler leak when delay is set 10507e7a3dba5fd4262269f713dfe21ba7e4746fc2ddSerhiy Storchaka StreamHandler.close(self) 1051f05090372a43966266a8d20b9c21d348e417a48eVinay Sajip finally: 1052f05090372a43966266a8d20b9c21d348e417a48eVinay Sajip self.release() 105357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 1054fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters def _open(self): 1055fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters """ 1056fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters Open the current base file with the (original) mode and encoding. 1057fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters Return the resulting stream. 1058fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters """ 10595252f9faee97573f5b8ff37d7c22225e5df6cc0bFlorent Xicluna return open(self.baseFilename, self.mode, encoding=self.encoding) 1060fc7bb8c786fd9cb3b1ab84e1976620d0ab545777Thomas Wouters 1061e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes def emit(self, record): 1062e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes """ 1063e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes Emit a record. 1064e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes 1065e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes If the stream was not opened because 'delay' was specified in the 1066e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes constructor, open it before calling the superclass's emit. 1067e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes """ 1068e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes if self.stream is None: 10696268cbc77190cf6b4112a272f2870d5361903605Vinay Sajip self.stream = self._open() 1070e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes StreamHandler.emit(self, record) 1071e7a15bb808f2118920fed0b5949f821940cf7416Christian Heimes 1072c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip def __repr__(self): 1073c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip level = getLevelName(self.level) 1074c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip return '<%s %s (%s)>' % (self.__class__.__name__, self.baseFilename, level) 1075c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip 1076c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip 10775a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajipclass _StderrHandler(StreamHandler): 10785a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip """ 10795a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip This class is like a StreamHandler using sys.stderr, but always uses 10805a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip whatever sys.stderr is currently set to rather than the value of 10815a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip sys.stderr at handler construction time. 10825a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip """ 10835a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip def __init__(self, level=NOTSET): 10845a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip """ 10855a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip Initialize the handler. 10865a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip """ 10875a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip Handler.__init__(self, level) 10885a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip 10895a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip @property 10905a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip def stream(self): 10915a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip return sys.stderr 10925a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip 10935a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip 10945a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip_defaultLastResort = _StderrHandler(WARNING) 10955a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay SajiplastResort = _defaultLastResort 10965a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip 109757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 109857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Manager classes and functions 109957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 110057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 11015554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Petersonclass PlaceHolder(object): 110257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 110357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum PlaceHolder instances are used in the Manager logger hierarchy to take 11043f74284e1baef338b34ed9a17a7b46e9607ccd5dVinay Sajip the place of nodes for which no loggers have been defined. This class is 11053f74284e1baef338b34ed9a17a7b46e9607ccd5dVinay Sajip intended for internal use only and not as part of the public API. 110657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 110757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def __init__(self, alogger): 110857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 110957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Initialize with the specified logger being a child of this placeholder. 111057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 1111239322b97e40d55b7406b09b953ac4c1fe10dcc5Vinay Sajip self.loggerMap = { alogger : None } 111257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 111357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def append(self, alogger): 111457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 111557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Add the specified logger as a child of this placeholder. 111657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 111793662417e9253ed87eb94f0b7b51491bfcca3eedGuido van Rossum if alogger not in self.loggerMap: 1118239322b97e40d55b7406b09b953ac4c1fe10dcc5Vinay Sajip self.loggerMap[alogger] = None 111957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 112057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 112157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Determine which class to use when instantiating loggers. 112257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# 112357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 112457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumdef setLoggerClass(klass): 112557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 112657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Set the class to be used when instantiating a logger. The class should 112757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum define __init__() such that only a name argument is required, and the 112857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum __init__() should call Logger.__init__() 112957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 113057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if klass != Logger: 113157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if not issubclass(klass, Logger): 1132ce36ad8a467d914eb5c91f33835b9eaea18ee93bCollin Winter raise TypeError("logger not derived from logging.Logger: " 1133ce36ad8a467d914eb5c91f33835b9eaea18ee93bCollin Winter + klass.__name__) 113457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum global _loggerClass 113557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum _loggerClass = klass 113657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 1137b9591174df4a330f75b1a5dc4893af063b8a7b7fVinay Sajipdef getLoggerClass(): 1138b9591174df4a330f75b1a5dc4893af063b8a7b7fVinay Sajip """ 1139b9591174df4a330f75b1a5dc4893af063b8a7b7fVinay Sajip Return the class to be used when instantiating a logger. 1140b9591174df4a330f75b1a5dc4893af063b8a7b7fVinay Sajip """ 1141b9591174df4a330f75b1a5dc4893af063b8a7b7fVinay Sajip return _loggerClass 1142b9591174df4a330f75b1a5dc4893af063b8a7b7fVinay Sajip 11435554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Petersonclass Manager(object): 114457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 114557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum There is [under normal circumstances] just one Manager instance, which 114657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum holds the hierarchy of loggers. 114757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 1148d1cade0d1f7aa00f3659f28cdb70ca5e751c3902Neal Norwitz def __init__(self, rootnode): 114957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 115057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Initialize the manager with the root node of the logger hierarchy. 115157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 1152d1cade0d1f7aa00f3659f28cdb70ca5e751c3902Neal Norwitz self.root = rootnode 115357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.disable = 0 11545a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip self.emittedNoHandlerWarning = False 115557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.loggerDict = {} 1156db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip self.loggerClass = None 1157615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip self.logRecordFactory = None 115857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 115957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def getLogger(self, name): 116057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 116157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Get a logger with the specified name (channel name), creating it 1162b9591174df4a330f75b1a5dc4893af063b8a7b7fVinay Sajip if it doesn't yet exist. This name is a dot-separated hierarchical 1163b9591174df4a330f75b1a5dc4893af063b8a7b7fVinay Sajip name, such as "a", "a.b", "a.b.c" or similar. 116457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 116557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum If a PlaceHolder existed for the specified name [i.e. the logger 116657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum didn't exist but a child of it did], replace it with the created 116757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum logger and fix up the parent/child references which pointed to the 116857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum placeholder to now point to the logger. 116957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 117057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum rv = None 117161b787e6dd00b1e6e24a12e2d5aa6e9fd1352663Vinay Sajip if not isinstance(name, str): 11723bd56387360e0b5ab1930640d0c4830c7fd6de23Vinay Sajip raise TypeError('A logger name must be a string') 117357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum _acquireLock() 117457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum try: 117593662417e9253ed87eb94f0b7b51491bfcca3eedGuido van Rossum if name in self.loggerDict: 117657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum rv = self.loggerDict[name] 117757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if isinstance(rv, PlaceHolder): 117857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum ph = rv 1179db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip rv = (self.loggerClass or _loggerClass)(name) 118057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum rv.manager = self 118157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.loggerDict[name] = rv 118257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self._fixupChildren(ph, rv) 118357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self._fixupParents(rv) 118457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum else: 1185db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip rv = (self.loggerClass or _loggerClass)(name) 118657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum rv.manager = self 118757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.loggerDict[name] = rv 118857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self._fixupParents(rv) 118957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum finally: 119057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum _releaseLock() 119157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return rv 119257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 1193db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip def setLoggerClass(self, klass): 1194db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip """ 1195db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip Set the class to be used when instantiating a logger with this Manager. 1196db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip """ 1197db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip if klass != Logger: 1198db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip if not issubclass(klass, Logger): 1199db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip raise TypeError("logger not derived from logging.Logger: " 1200db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip + klass.__name__) 1201db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip self.loggerClass = klass 1202db81c4c63a702be1ec6e298bbee70634df873e68Vinay Sajip 1203615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip def setLogRecordFactory(self, factory): 12046fac8171367e0f2626613eb0ac07fc79c25f2500Vinay Sajip """ 1205fad058f0caca689fffad29617d0858caa13291adVinay Sajip Set the factory to be used when instantiating a log record with this 12066fac8171367e0f2626613eb0ac07fc79c25f2500Vinay Sajip Manager. 12076fac8171367e0f2626613eb0ac07fc79c25f2500Vinay Sajip """ 1208615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip self.logRecordFactory = factory 12096fac8171367e0f2626613eb0ac07fc79c25f2500Vinay Sajip 121057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def _fixupParents(self, alogger): 121157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 121257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Ensure that there are either loggers or placeholders all the way 121357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum from the specified logger to the root of the logger hierarchy. 121457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 121557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum name = alogger.name 12169d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz i = name.rfind(".") 121757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum rv = None 121857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum while (i > 0) and not rv: 121957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum substr = name[:i] 122093662417e9253ed87eb94f0b7b51491bfcca3eedGuido van Rossum if substr not in self.loggerDict: 122157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.loggerDict[substr] = PlaceHolder(alogger) 122257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum else: 122357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum obj = self.loggerDict[substr] 122457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if isinstance(obj, Logger): 122557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum rv = obj 122657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum else: 122757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum assert isinstance(obj, PlaceHolder) 122857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum obj.append(alogger) 12299d72bb452bced3a100f07f8a9e30c4495a9ec41aNeal Norwitz i = name.rfind(".", 0, i - 1) 123057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if not rv: 123157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum rv = self.root 123257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum alogger.parent = rv 123357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 123457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def _fixupChildren(self, ph, alogger): 123557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 123657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Ensure that children of the placeholder ph are connected to the 123757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum specified logger. 123857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 123989f507fe8c497b3f70fdcecce8bc240f9af2bbe2Thomas Wouters name = alogger.name 124089f507fe8c497b3f70fdcecce8bc240f9af2bbe2Thomas Wouters namelen = len(name) 1241239322b97e40d55b7406b09b953ac4c1fe10dcc5Vinay Sajip for c in ph.loggerMap.keys(): 124289f507fe8c497b3f70fdcecce8bc240f9af2bbe2Thomas Wouters #The if means ... if not c.parent.name.startswith(nm) 124389f507fe8c497b3f70fdcecce8bc240f9af2bbe2Thomas Wouters if c.parent.name[:namelen] != name: 124457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum alogger.parent = c.parent 124557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum c.parent = alogger 124657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 124757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 124857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Logger classes and functions 124957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 125057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 125157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumclass Logger(Filterer): 125257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 125357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Instances of the Logger class represent a single logging channel. A 125457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum "logging channel" indicates an area of an application. Exactly how an 125557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum "area" is defined is up to the application developer. Since an 125657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum application can have any number of areas, logging channels are identified 125757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum by a unique string. Application areas can be nested (e.g. an area 125857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum of "input processing" might include sub-areas "read CSV files", "read 125957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum XLS files" and "read Gnumeric files"). To cater for this natural nesting, 126057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum channel names are organized into a namespace hierarchy where levels are 126157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum separated by periods, much like the Java or Python package namespace. So 126257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum in the instance given above, channel names might be "input" for the upper 126357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels. 126457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum There is no arbitrary limit to the depth of nesting. 126557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 126657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def __init__(self, name, level=NOTSET): 126757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 126857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Initialize the logger with a name and an optional level. 126957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 127057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Filterer.__init__(self) 127157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.name = name 1272d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajip self.level = _checkLevel(level) 127357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.parent = None 1274312cc0d28e86d36c1430814c91f9c1bb6087d588Vinay Sajip self.propagate = True 127557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.handlers = [] 1276312cc0d28e86d36c1430814c91f9c1bb6087d588Vinay Sajip self.disabled = False 127757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 127857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def setLevel(self, level): 127957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 1280e85488c6f4d01ad53e0836e90fcd6095d0a7a987Gregory P. Smith Set the logging level of this logger. level must be an int or a str. 128157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 1282d4fabf410dd1675e25db6d49d3d84336f59b620cVinay Sajip self.level = _checkLevel(level) 128357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 128457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def debug(self, msg, *args, **kwargs): 128557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 128657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Log 'msg % args' with severity 'DEBUG'. 128757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 128857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum To pass exception information, use the keyword argument exc_info with 128957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum a true value, e.g. 129057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 129157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum logger.debug("Houston, we have a %s", "thorny problem", exc_info=1) 129257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 129304110fb8594c969ca187a968a35a59263ddf7209Guido van Rossum if self.isEnabledFor(DEBUG): 1294d91085598f5185b267ea51a3f615da9527af2ed2Neal Norwitz self._log(DEBUG, msg, args, **kwargs) 129557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 129657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def info(self, msg, *args, **kwargs): 129757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 129857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Log 'msg % args' with severity 'INFO'. 129957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 130057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum To pass exception information, use the keyword argument exc_info with 130157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum a true value, e.g. 130257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 130357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum logger.info("Houston, we have a %s", "interesting problem", exc_info=1) 130457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 130504110fb8594c969ca187a968a35a59263ddf7209Guido van Rossum if self.isEnabledFor(INFO): 1306d91085598f5185b267ea51a3f615da9527af2ed2Neal Norwitz self._log(INFO, msg, args, **kwargs) 130757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 13086fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz def warning(self, msg, *args, **kwargs): 130957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 13106fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz Log 'msg % args' with severity 'WARNING'. 131157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 131257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum To pass exception information, use the keyword argument exc_info with 131357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum a true value, e.g. 131457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 13156fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1) 131657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 13176fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz if self.isEnabledFor(WARNING): 1318d91085598f5185b267ea51a3f615da9527af2ed2Neal Norwitz self._log(WARNING, msg, args, **kwargs) 13196fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz 132004d5bc00a219860c69ea17eaa633d3ab9917409fVinay Sajip def warn(self, msg, *args, **kwargs): 132104d5bc00a219860c69ea17eaa633d3ab9917409fVinay Sajip warnings.warn("The 'warn' method is deprecated, " 13220a889534e7e4beb41fc3a6837501b68a24139083Vinay Sajip "use 'warning' instead", DeprecationWarning, 2) 132304d5bc00a219860c69ea17eaa633d3ab9917409fVinay Sajip self.warning(msg, *args, **kwargs) 132457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 132557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def error(self, msg, *args, **kwargs): 132657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 132757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Log 'msg % args' with severity 'ERROR'. 132857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 132957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum To pass exception information, use the keyword argument exc_info with 133057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum a true value, e.g. 133157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 133257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum logger.error("Houston, we have a %s", "major problem", exc_info=1) 133357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 133457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if self.isEnabledFor(ERROR): 1335d91085598f5185b267ea51a3f615da9527af2ed2Neal Norwitz self._log(ERROR, msg, args, **kwargs) 133657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 133702a8f9e9acbe55efcbb7ebc3f821d3d2f9cca368Vinay Sajip def exception(self, msg, *args, exc_info=True, **kwargs): 133857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 133957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Convenience method for logging an ERROR with exception information. 134057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 134102a8f9e9acbe55efcbb7ebc3f821d3d2f9cca368Vinay Sajip self.error(msg, *args, exc_info=exc_info, **kwargs) 134257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 134357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def critical(self, msg, *args, **kwargs): 134457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 134557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Log 'msg % args' with severity 'CRITICAL'. 134657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 134757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum To pass exception information, use the keyword argument exc_info with 134857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum a true value, e.g. 134957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 135057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum logger.critical("Houston, we have a %s", "major disaster", exc_info=1) 135157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 135204110fb8594c969ca187a968a35a59263ddf7209Guido van Rossum if self.isEnabledFor(CRITICAL): 1353d91085598f5185b267ea51a3f615da9527af2ed2Neal Norwitz self._log(CRITICAL, msg, args, **kwargs) 135457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 135557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum fatal = critical 135657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 135757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def log(self, level, msg, *args, **kwargs): 135857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 1359eb477d04f7be4bfbf356825a0d832c012dab1ac7Vinay Sajip Log 'msg % args' with the integer severity 'level'. 136057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 136157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum To pass exception information, use the keyword argument exc_info with 136257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum a true value, e.g. 136357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 136457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum logger.log(level, "We have a %s", "mysterious problem", exc_info=1) 136557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 13661325790b932c4bab4f8f94f5a36c09f4036ed9f8Guido van Rossum if not isinstance(level, int): 1367779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip if raiseExceptions: 1368ce36ad8a467d914eb5c91f33835b9eaea18ee93bCollin Winter raise TypeError("level must be an integer") 1369779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip else: 1370779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip return 137157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if self.isEnabledFor(level): 1372d91085598f5185b267ea51a3f615da9527af2ed2Neal Norwitz self._log(level, msg, args, **kwargs) 137357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 13748593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip def findCaller(self, stack_info=False): 137557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 137657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Find the stack frame of the caller so that we can note the source 1377829dc51a050a68ca79cdde298697d0344639bd14Vinay Sajip file name, line number and function name. 137857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 13794ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson f = currentframe() 13804ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson #On some versions of IronPython, currentframe() returns None if 13814ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson #IronPython isn't run with -X:Frames. 13824ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson if f is not None: 13834ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson f = f.f_back 13848593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip rv = "(unknown file)", 0, "(unknown function)", None 1385a977329b6fb0e4c95cabb9043794de69b27a1099Thomas Wouters while hasattr(f, "f_code"): 1386250684ddd8223de98b5944d13e89a12673d0a51aJeremy Hylton co = f.f_code 1387250684ddd8223de98b5944d13e89a12673d0a51aJeremy Hylton filename = os.path.normcase(co.co_filename) 1388250684ddd8223de98b5944d13e89a12673d0a51aJeremy Hylton if filename == _srcfile: 1389250684ddd8223de98b5944d13e89a12673d0a51aJeremy Hylton f = f.f_back 1390250684ddd8223de98b5944d13e89a12673d0a51aJeremy Hylton continue 13918593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip sinfo = None 13928593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip if stack_info: 13938593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip sio = io.StringIO() 13948593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip sio.write('Stack (most recent call last):\n') 13958593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip traceback.print_stack(f, file=sio) 13968593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip sinfo = sio.getvalue() 13978593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip if sinfo[-1] == '\n': 13988593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip sinfo = sinfo[:-1] 13998593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip sio.close() 14008593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip rv = (co.co_filename, f.f_lineno, co.co_name, sinfo) 1401a977329b6fb0e4c95cabb9043794de69b27a1099Thomas Wouters break 1402a977329b6fb0e4c95cabb9043794de69b27a1099Thomas Wouters return rv 140357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 14048593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip def makeRecord(self, name, level, fn, lno, msg, args, exc_info, 14058593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip func=None, extra=None, sinfo=None): 140657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 140757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum A factory method which can be overridden in subclasses to create 140857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum specialized LogRecords. 140957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 1410615615291f8a59ff194cadb67e9898575061aaa5Vinay Sajip rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func, 14118593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip sinfo) 141204c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes if extra is not None: 1413260ce43252a8144d191fa0a508d42cc8e107caa5Vinay Sajip for key in extra: 1414260ce43252a8144d191fa0a508d42cc8e107caa5Vinay Sajip if (key in ["message", "asctime"]) or (key in rv.__dict__): 1415260ce43252a8144d191fa0a508d42cc8e107caa5Vinay Sajip raise KeyError("Attempt to overwrite %r in LogRecord" % key) 1416260ce43252a8144d191fa0a508d42cc8e107caa5Vinay Sajip rv.__dict__[key] = extra[key] 1417260ce43252a8144d191fa0a508d42cc8e107caa5Vinay Sajip return rv 141857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 14198593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False): 142057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 142157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Low-level logging routine which creates a LogRecord and then calls 142257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum all the handlers of this logger to handle the record. 142357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 14248593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip sinfo = None 1425250684ddd8223de98b5944d13e89a12673d0a51aJeremy Hylton if _srcfile: 1426737fb89dd15e4db6ef30d25963e774ae09cc49dcAndrew Svetlov #IronPython doesn't track Python frames, so findCaller raises an 14274ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson #exception on some versions of IronPython. We trap it here so that 14284ac9ce4f9a33a330a555ae8015e2f2ae2780fafbBenjamin Peterson #IronPython can use logging. 1429b672b6dea65dfae3c8ad04591642e8835f499da2Vinay Sajip try: 14308593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip fn, lno, func, sinfo = self.findCaller(stack_info) 143126fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay Sajip except ValueError: # pragma: no cover 1432b672b6dea65dfae3c8ad04591642e8835f499da2Vinay Sajip fn, lno, func = "(unknown file)", 0, "(unknown function)" 143326fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay Sajip else: # pragma: no cover 1434829dc51a050a68ca79cdde298697d0344639bd14Vinay Sajip fn, lno, func = "(unknown file)", 0, "(unknown function)" 143557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if exc_info: 143602a8f9e9acbe55efcbb7ebc3f821d3d2f9cca368Vinay Sajip if isinstance(exc_info, BaseException): 143702a8f9e9acbe55efcbb7ebc3f821d3d2f9cca368Vinay Sajip exc_info = (type(exc_info), exc_info, exc_info.__traceback__) 143802a8f9e9acbe55efcbb7ebc3f821d3d2f9cca368Vinay Sajip elif not isinstance(exc_info, tuple): 1439ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip exc_info = sys.exc_info() 14408593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip record = self.makeRecord(self.name, level, fn, lno, msg, args, 14418593ae64518bb6d42a330a4015f875c7d9a42d18Vinay Sajip exc_info, func, extra, sinfo) 144257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.handle(record) 144357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 144457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def handle(self, record): 144557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 144657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Call the handlers for the specified record. 144757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 144857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum This method is used for unpickled records received from a socket, as 144957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum well as those created locally. Logger-level filtering is applied. 145057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 145157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if (not self.disabled) and self.filter(record): 145257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum self.callHandlers(record) 145357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 145457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def addHandler(self, hdlr): 145557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 145657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Add the specified handler to this logger. 145757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 145832fb6a81f992d86bb4c227912602c224dbbc7d7fVinay Sajip _acquireLock() 145932fb6a81f992d86bb4c227912602c224dbbc7d7fVinay Sajip try: 146032fb6a81f992d86bb4c227912602c224dbbc7d7fVinay Sajip if not (hdlr in self.handlers): 146132fb6a81f992d86bb4c227912602c224dbbc7d7fVinay Sajip self.handlers.append(hdlr) 146232fb6a81f992d86bb4c227912602c224dbbc7d7fVinay Sajip finally: 146332fb6a81f992d86bb4c227912602c224dbbc7d7fVinay Sajip _releaseLock() 146457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 146557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def removeHandler(self, hdlr): 146657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 146757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Remove the specified handler from this logger. 146857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 146932fb6a81f992d86bb4c227912602c224dbbc7d7fVinay Sajip _acquireLock() 147032fb6a81f992d86bb4c227912602c224dbbc7d7fVinay Sajip try: 147132fb6a81f992d86bb4c227912602c224dbbc7d7fVinay Sajip if hdlr in self.handlers: 1472116f16e4ab9a7cc319ca42ae24221d203d0d8f26Vinay Sajip self.handlers.remove(hdlr) 147332fb6a81f992d86bb4c227912602c224dbbc7d7fVinay Sajip finally: 147432fb6a81f992d86bb4c227912602c224dbbc7d7fVinay Sajip _releaseLock() 147557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 1476b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip def hasHandlers(self): 1477b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip """ 1478b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip See if this logger has any handlers configured. 1479b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip 1480b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip Loop through all handlers for this logger and its parents in the 1481b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip logger hierarchy. Return True if a handler was found, else False. 1482b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip Stop searching up the hierarchy whenever a logger with the "propagate" 1483b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip attribute set to zero is found - that will be the last logger which 1484b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip is checked for the existence of handlers. 1485b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip """ 1486b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip c = self 1487b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip rv = False 1488b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip while c: 1489b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip if c.handlers: 1490b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip rv = True 1491b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip break 1492b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip if not c.propagate: 1493b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip break 1494b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip else: 1495b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip c = c.parent 1496b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip return rv 1497b4a0809ad79dbbd9c263b523499b8f0a0136aa7aVinay Sajip 149857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def callHandlers(self, record): 149957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 150057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Pass a record to all relevant handlers. 150157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 150257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Loop through all handlers for this logger and its parents in the 150357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum logger hierarchy. If no handler was found, output a one-off error 150457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum message to sys.stderr. Stop searching up the hierarchy whenever a 150557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum logger with the "propagate" attribute set to zero is found - that 150657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum will be the last logger whose handlers are called. 150757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 150857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum c = self 150957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum found = 0 151057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum while c: 151157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum for hdlr in c.handlers: 151257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum found = found + 1 151357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if record.levelno >= hdlr.level: 151457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum hdlr.handle(record) 151557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if not c.propagate: 151657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum c = None #break out 151757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum else: 151857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum c = c.parent 15195a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip if (found == 0): 15205a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip if lastResort: 152145dedaafc2d8f83c3021df28251a4a7dae067774Vinay Sajip if record.levelno >= lastResort.level: 152245dedaafc2d8f83c3021df28251a4a7dae067774Vinay Sajip lastResort.handle(record) 15235a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip elif raiseExceptions and not self.manager.emittedNoHandlerWarning: 15245a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip sys.stderr.write("No handlers could be found for logger" 15255a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip " \"%s\"\n" % self.name) 15265a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip self.manager.emittedNoHandlerWarning = True 152757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 152857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def getEffectiveLevel(self): 152957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 153057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Get the effective level for this logger. 153157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 153257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Loop through this logger and its parents in the logger hierarchy, 153357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum looking for a non-zero logging level. Return the first one found. 153457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 153557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum logger = self 153657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum while logger: 153757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if logger.level: 153857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return logger.level 153957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum logger = logger.parent 154057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return NOTSET 154157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 154257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def isEnabledFor(self, level): 154357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 154457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Is this logger enabled for level 'level'? 154557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 154657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if self.manager.disable >= level: 154726fe4b70cf38d9de4001e4b1cf9c2206ad3e1b4bVinay Sajip return False 154857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return level >= self.getEffectiveLevel() 154957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 155022005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson def getChild(self, suffix): 155122005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson """ 155222005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson Get a logger which is a descendant to this one. 155322005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson 155422005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson This is a convenience method, such that 155522005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson 155622005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson logging.getLogger('abc').getChild('def.ghi') 155722005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson 155822005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson is the same as 155922005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson 156022005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson logging.getLogger('abc.def.ghi') 156122005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson 156222005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson It's useful, for example, when the parent logger is named using 156322005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson __name__ rather than a literal string. 156422005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson """ 156522005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson if self.root is not self: 156622005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson suffix = '.'.join((self.name, suffix)) 156722005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson return self.manager.getLogger(suffix) 156822005fc5bad9d2c3eda9defb28e6a56ede4b2c8aBenjamin Peterson 1569c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip def __repr__(self): 1570c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip level = getLevelName(self.getEffectiveLevel()) 1571c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level) 1572c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip 1573c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip 157457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumclass RootLogger(Logger): 157557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 157657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum A root logger is not that different to any other logger, except that 157757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum it must have a logging level and there is only one instance of it in 157857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum the hierarchy. 157957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 158057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum def __init__(self, level): 158157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 158257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Initialize the logger with the name "root". 158357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 158457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Logger.__init__(self, "root", level) 158557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 158657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum_loggerClass = Logger 158757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 15885554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Petersonclass LoggerAdapter(object): 158904c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 159004c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes An adapter for loggers which makes it easier to specify contextual 159104c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes information in logging output. 159204c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 159304c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 159404c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes def __init__(self, logger, extra): 159504c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 159604c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes Initialize the adapter with a logger and a dict-like object which 159704c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes provides contextual information. This constructor signature allows 159804c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes easy stacking of LoggerAdapters, if so desired. 159904c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 160004c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes You can effectively pass keyword arguments as shown in the 160104c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes following example: 160204c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 160304c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2")) 160404c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 160504c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes self.logger = logger 160604c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes self.extra = extra 160704c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 160804c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes def process(self, msg, kwargs): 160904c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 161004c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes Process the logging message and keyword arguments passed in to 161104c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes a logging call to insert contextual information. You can either 161204c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes manipulate the message itself, the keyword args or both. Return 161304c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes the message and kwargs modified (or not) to suit your needs. 161404c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 161504c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes Normally, you'll only need to override this one method in a 161604c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes LoggerAdapter subclass for your specific needs. 161704c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 161804c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes kwargs["extra"] = self.extra 161904c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes return msg, kwargs 162004c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 1621212b590e118e3650b596917021ed9612a918180bVinay Sajip # 1622212b590e118e3650b596917021ed9612a918180bVinay Sajip # Boilerplate convenience methods 1623212b590e118e3650b596917021ed9612a918180bVinay Sajip # 162404c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes def debug(self, msg, *args, **kwargs): 162504c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 1626212b590e118e3650b596917021ed9612a918180bVinay Sajip Delegate a debug call to the underlying logger. 162704c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 1628212b590e118e3650b596917021ed9612a918180bVinay Sajip self.log(DEBUG, msg, *args, **kwargs) 162904c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 163004c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes def info(self, msg, *args, **kwargs): 163104c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 1632212b590e118e3650b596917021ed9612a918180bVinay Sajip Delegate an info call to the underlying logger. 163304c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 1634212b590e118e3650b596917021ed9612a918180bVinay Sajip self.log(INFO, msg, *args, **kwargs) 163504c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 163604c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes def warning(self, msg, *args, **kwargs): 163704c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 1638212b590e118e3650b596917021ed9612a918180bVinay Sajip Delegate a warning call to the underlying logger. 163904c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 1640212b590e118e3650b596917021ed9612a918180bVinay Sajip self.log(WARNING, msg, *args, **kwargs) 164104c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 164204d5bc00a219860c69ea17eaa633d3ab9917409fVinay Sajip def warn(self, msg, *args, **kwargs): 164304d5bc00a219860c69ea17eaa633d3ab9917409fVinay Sajip warnings.warn("The 'warn' method is deprecated, " 16440a889534e7e4beb41fc3a6837501b68a24139083Vinay Sajip "use 'warning' instead", DeprecationWarning, 2) 164504d5bc00a219860c69ea17eaa633d3ab9917409fVinay Sajip self.warning(msg, *args, **kwargs) 1646c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip 164704c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes def error(self, msg, *args, **kwargs): 164804c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 1649212b590e118e3650b596917021ed9612a918180bVinay Sajip Delegate an error call to the underlying logger. 165004c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 1651212b590e118e3650b596917021ed9612a918180bVinay Sajip self.log(ERROR, msg, *args, **kwargs) 165204c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 165302a8f9e9acbe55efcbb7ebc3f821d3d2f9cca368Vinay Sajip def exception(self, msg, *args, exc_info=True, **kwargs): 165404c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 1655212b590e118e3650b596917021ed9612a918180bVinay Sajip Delegate an exception call to the underlying logger. 165604c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 165702a8f9e9acbe55efcbb7ebc3f821d3d2f9cca368Vinay Sajip self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs) 165804c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 165904c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes def critical(self, msg, *args, **kwargs): 166004c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 1661212b590e118e3650b596917021ed9612a918180bVinay Sajip Delegate a critical call to the underlying logger. 166204c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 1663212b590e118e3650b596917021ed9612a918180bVinay Sajip self.log(CRITICAL, msg, *args, **kwargs) 166404c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 166504c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes def log(self, level, msg, *args, **kwargs): 166604c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 166704c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes Delegate a log call to the underlying logger, after adding 166804c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes contextual information from this adapter instance. 166904c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes """ 1670212b590e118e3650b596917021ed9612a918180bVinay Sajip if self.isEnabledFor(level): 1671212b590e118e3650b596917021ed9612a918180bVinay Sajip msg, kwargs = self.process(msg, kwargs) 1672212b590e118e3650b596917021ed9612a918180bVinay Sajip self.logger._log(level, msg, args, **kwargs) 1673212b590e118e3650b596917021ed9612a918180bVinay Sajip 1674212b590e118e3650b596917021ed9612a918180bVinay Sajip def isEnabledFor(self, level): 1675212b590e118e3650b596917021ed9612a918180bVinay Sajip """ 1676212b590e118e3650b596917021ed9612a918180bVinay Sajip Is this logger enabled for level 'level'? 1677212b590e118e3650b596917021ed9612a918180bVinay Sajip """ 1678212b590e118e3650b596917021ed9612a918180bVinay Sajip if self.logger.manager.disable >= level: 1679212b590e118e3650b596917021ed9612a918180bVinay Sajip return False 1680212b590e118e3650b596917021ed9612a918180bVinay Sajip return level >= self.getEffectiveLevel() 168104c420f605b2bb7902f1afc3d62a45fbb0295bd0Christian Heimes 1682c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip def setLevel(self, level): 1683c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip """ 1684c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip Set the specified level on the underlying logger. 1685c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip """ 1686c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip self.logger.setLevel(level) 1687c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip 1688c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip def getEffectiveLevel(self): 1689c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip """ 1690c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip Get the effective level for the underlying logger. 1691c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip """ 1692c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip return self.logger.getEffectiveLevel() 1693c84f01698874902863396e82a248f5fd6ec59d0eVinay Sajip 169461c3f0dae732589b11f4a1a2cb26173fe0fb5983Vinay Sajip def hasHandlers(self): 169561c3f0dae732589b11f4a1a2cb26173fe0fb5983Vinay Sajip """ 169661c3f0dae732589b11f4a1a2cb26173fe0fb5983Vinay Sajip See if the underlying logger has any handlers. 169761c3f0dae732589b11f4a1a2cb26173fe0fb5983Vinay Sajip """ 169861c3f0dae732589b11f4a1a2cb26173fe0fb5983Vinay Sajip return self.logger.hasHandlers() 169961c3f0dae732589b11f4a1a2cb26173fe0fb5983Vinay Sajip 1700c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip def __repr__(self): 1701c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip logger = self.logger 1702c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip level = getLevelName(logger.getEffectiveLevel()) 1703c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level) 1704c0752011472790e34d171b89f4b862cc3fd8ad08Vinay Sajip 17056fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitzroot = RootLogger(WARNING) 170657102f861d506b6c2d2215d100dac9143574fa77Guido van RossumLogger.root = root 170757102f861d506b6c2d2215d100dac9143574fa77Guido van RossumLogger.manager = Manager(Logger.root) 170857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 170957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 171057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Configuration classes and functions 171157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 171257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 1713779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajipdef basicConfig(**kwargs): 171457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 1715779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip Do basic configuration for the logging system. 1716779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip 1717779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip This function does nothing if the root logger already has handlers 1718779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip configured. It is a convenience method intended for use by simple scripts 1719779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip to do one-shot configuration of the logging package. 1720779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip 1721779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip The default behaviour is to create a StreamHandler which writes to 1722779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip sys.stderr, set a formatter using the BASIC_FORMAT format string, and 1723779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip add the handler to the root logger. 1724779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip 1725779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip A number of optional keyword arguments may be specified, which can alter 1726779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip the default behaviour. 1727779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip 1728779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip filename Specifies that a FileHandler be created, using the specified 1729779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip filename, rather than a StreamHandler. 1730779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip filemode Specifies the mode to open the file, if filename is specified 1731b89e7c9bc97d3f9332ecc94c88a055c0fe947625Vinay Sajip (if filemode is unspecified, it defaults to 'a'). 1732779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip format Use the specified format string for the handler. 1733779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip datefmt Use the specified date/time format. 1734c5b273011b86d6ec534c935d4520c5db5a35bde1Vinay Sajip style If a format string is specified, use this to specify the 1735c5b273011b86d6ec534c935d4520c5db5a35bde1Vinay Sajip type of format string (possible values '%', '{', '$', for 1736c5b273011b86d6ec534c935d4520c5db5a35bde1Vinay Sajip %-formatting, :meth:`str.format` and :class:`string.Template` 1737c5b273011b86d6ec534c935d4520c5db5a35bde1Vinay Sajip - defaults to '%'). 1738779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip level Set the root logger level to the specified level. 1739779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip stream Use the specified stream to initialize the StreamHandler. Note 1740779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip that this argument is incompatible with 'filename' - if both 1741779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip are present, 'stream' is ignored. 17424a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip handlers If specified, this should be an iterable of already created 17434a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip handlers, which will be added to the root handler. Any handler 17444a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip in the list which does not have a formatter assigned will be 17454a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip assigned the formatter created in this function. 1746779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip 1747779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip Note that you could specify a stream created using open(filename, mode) 1748779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip rather than passing the filename and mode in. However, it should be 1749779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip remembered that StreamHandler does not close its stream (since it may be 1750779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip using sys.stdout or sys.stderr), whereas FileHandler closes its stream 1751779e0c93346ab5458a8417148c4a23c1d915f6b8Vinay Sajip when the handler is closed. 1752c5b273011b86d6ec534c935d4520c5db5a35bde1Vinay Sajip 17534a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip .. versionchanged:: 3.2 1754c5b273011b86d6ec534c935d4520c5db5a35bde1Vinay Sajip Added the ``style`` parameter. 1755a3359eec7d96237eff157e513ccfd5c5370088bcVinay Sajip 17564a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip .. versionchanged:: 3.3 17574a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip Added the ``handlers`` parameter. A ``ValueError`` is now thrown for 17584a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip incompatible arguments (e.g. ``handlers`` specified together with 17594a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip ``filename``/``filemode``, or ``filename``/``filemode`` specified 17604a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip together with ``stream``, or ``handlers`` specified together with 17614a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip ``stream``. 176257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 17632314fc729b7192a041ae7630febdc376519b8b9aVinay Sajip # Add thread safety in case someone mistakenly calls 17642314fc729b7192a041ae7630febdc376519b8b9aVinay Sajip # basicConfig() from multiple threads 17652314fc729b7192a041ae7630febdc376519b8b9aVinay Sajip _acquireLock() 17662314fc729b7192a041ae7630febdc376519b8b9aVinay Sajip try: 17672314fc729b7192a041ae7630febdc376519b8b9aVinay Sajip if len(root.handlers) == 0: 17685abca7023c06dbe77a974d060e5d0e81d7785709Vinay Sajip handlers = kwargs.pop("handlers", None) 17694a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip if handlers is None: 17704a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip if "stream" in kwargs and "filename" in kwargs: 17714a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip raise ValueError("'stream' and 'filename' should not be " 17724a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip "specified together") 17732314fc729b7192a041ae7630febdc376519b8b9aVinay Sajip else: 17744a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip if "stream" in kwargs or "filename" in kwargs: 17754a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip raise ValueError("'stream' or 'filename' should not be " 17764a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip "specified together with 'handlers'") 17774a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip if handlers is None: 17785abca7023c06dbe77a974d060e5d0e81d7785709Vinay Sajip filename = kwargs.pop("filename", None) 1779d55436ace3cb908e0f7a1f368a2cd8879175947dVinay Sajip mode = kwargs.pop("filemode", 'a') 17804a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip if filename: 17814a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip h = FileHandler(filename, mode) 17824a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip else: 17835abca7023c06dbe77a974d060e5d0e81d7785709Vinay Sajip stream = kwargs.pop("stream", None) 17844a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip h = StreamHandler(stream) 17854a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip handlers = [h] 17865abca7023c06dbe77a974d060e5d0e81d7785709Vinay Sajip dfs = kwargs.pop("datefmt", None) 17875abca7023c06dbe77a974d060e5d0e81d7785709Vinay Sajip style = kwargs.pop("style", '%') 17881fd1202072e198a7b3cf1254787aff3e3bf1c99eVinay Sajip if style not in _STYLES: 17891fd1202072e198a7b3cf1254787aff3e3bf1c99eVinay Sajip raise ValueError('Style must be one of: %s' % ','.join( 17901fd1202072e198a7b3cf1254787aff3e3bf1c99eVinay Sajip _STYLES.keys())) 17915abca7023c06dbe77a974d060e5d0e81d7785709Vinay Sajip fs = kwargs.pop("format", _STYLES[style][1]) 1792c5b273011b86d6ec534c935d4520c5db5a35bde1Vinay Sajip fmt = Formatter(fs, dfs, style) 17934a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip for h in handlers: 17944a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip if h.formatter is None: 17954a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip h.setFormatter(fmt) 17964a0a31df5c6ab79dd7dc8ee828379dca1d1f632fVinay Sajip root.addHandler(h) 17975abca7023c06dbe77a974d060e5d0e81d7785709Vinay Sajip level = kwargs.pop("level", None) 17982314fc729b7192a041ae7630febdc376519b8b9aVinay Sajip if level is not None: 17992314fc729b7192a041ae7630febdc376519b8b9aVinay Sajip root.setLevel(level) 18005abca7023c06dbe77a974d060e5d0e81d7785709Vinay Sajip if kwargs: 18015abca7023c06dbe77a974d060e5d0e81d7785709Vinay Sajip keys = ', '.join(kwargs.keys()) 18025abca7023c06dbe77a974d060e5d0e81d7785709Vinay Sajip raise ValueError('Unrecognised argument(s): %s' % keys) 18032314fc729b7192a041ae7630febdc376519b8b9aVinay Sajip finally: 18042314fc729b7192a041ae7630febdc376519b8b9aVinay Sajip _releaseLock() 180557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 180657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 180757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Utility functions at module level. 180857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum# Basically delegate everything to the root logger. 180957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum#--------------------------------------------------------------------------- 181057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 181157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumdef getLogger(name=None): 181257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 181357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Return a logger with the specified name, creating it if necessary. 181457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 181557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum If no name is specified, return the root logger. 181657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 181757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if name: 181857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return Logger.manager.getLogger(name) 181957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum else: 182057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum return root 182157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 182257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumdef critical(msg, *args, **kwargs): 182357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 18245a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip Log a message with severity 'CRITICAL' on the root logger. If the logger 18255a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip has no handlers, call basicConfig() to add a console handler with a 18265a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip pre-defined format. 182757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 182857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if len(root.handlers) == 0: 182957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum basicConfig() 1830d91085598f5185b267ea51a3f615da9527af2ed2Neal Norwitz root.critical(msg, *args, **kwargs) 183157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 183257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumfatal = critical 183357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 183457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumdef error(msg, *args, **kwargs): 183557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 18365a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip Log a message with severity 'ERROR' on the root logger. If the logger has 18375a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip no handlers, call basicConfig() to add a console handler with a pre-defined 18385a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip format. 183957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 184057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if len(root.handlers) == 0: 184157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum basicConfig() 1842d91085598f5185b267ea51a3f615da9527af2ed2Neal Norwitz root.error(msg, *args, **kwargs) 184357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 184402a8f9e9acbe55efcbb7ebc3f821d3d2f9cca368Vinay Sajipdef exception(msg, *args, exc_info=True, **kwargs): 184557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 18465a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip Log a message with severity 'ERROR' on the root logger, with exception 18475a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip information. If the logger has no handlers, basicConfig() is called to add 18485a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip a console handler with a pre-defined format. 184957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 185002a8f9e9acbe55efcbb7ebc3f821d3d2f9cca368Vinay Sajip error(msg, *args, exc_info=exc_info, **kwargs) 185157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 18526fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitzdef warning(msg, *args, **kwargs): 185357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 18545a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip Log a message with severity 'WARNING' on the root logger. If the logger has 18555a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip no handlers, call basicConfig() to add a console handler with a pre-defined 18565a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip format. 185757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 185857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if len(root.handlers) == 0: 185957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum basicConfig() 1860d91085598f5185b267ea51a3f615da9527af2ed2Neal Norwitz root.warning(msg, *args, **kwargs) 18616fa635df7aa88ae9fd8b41ae42743341316c90f7Neal Norwitz 186204d5bc00a219860c69ea17eaa633d3ab9917409fVinay Sajipdef warn(msg, *args, **kwargs): 186304d5bc00a219860c69ea17eaa633d3ab9917409fVinay Sajip warnings.warn("The 'warn' function is deprecated, " 18640a889534e7e4beb41fc3a6837501b68a24139083Vinay Sajip "use 'warning' instead", DeprecationWarning, 2) 186504d5bc00a219860c69ea17eaa633d3ab9917409fVinay Sajip warning(msg, *args, **kwargs) 186657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 186757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumdef info(msg, *args, **kwargs): 186857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 18695a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip Log a message with severity 'INFO' on the root logger. If the logger has 18705a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip no handlers, call basicConfig() to add a console handler with a pre-defined 18715a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip format. 187257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 187357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if len(root.handlers) == 0: 187457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum basicConfig() 1875d91085598f5185b267ea51a3f615da9527af2ed2Neal Norwitz root.info(msg, *args, **kwargs) 187657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 187757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumdef debug(msg, *args, **kwargs): 187857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 18795a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip Log a message with severity 'DEBUG' on the root logger. If the logger has 18805a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip no handlers, call basicConfig() to add a console handler with a pre-defined 18815a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip format. 188257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 188357102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum if len(root.handlers) == 0: 188457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum basicConfig() 1885d91085598f5185b267ea51a3f615da9527af2ed2Neal Norwitz root.debug(msg, *args, **kwargs) 188657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 1887b2635b2f7163716d735e7eda7c1d5c039410d3e4Vinay Sajipdef log(level, msg, *args, **kwargs): 1888b2635b2f7163716d735e7eda7c1d5c039410d3e4Vinay Sajip """ 18895a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip Log 'msg % args' with the integer severity 'level' on the root logger. If 18905a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip the logger has no handlers, call basicConfig() to add a console handler 18915a27d4018692a9cb9f30b5ed81ac7061c8fe3c82Vinay Sajip with a pre-defined format. 1892b2635b2f7163716d735e7eda7c1d5c039410d3e4Vinay Sajip """ 1893b2635b2f7163716d735e7eda7c1d5c039410d3e4Vinay Sajip if len(root.handlers) == 0: 1894b2635b2f7163716d735e7eda7c1d5c039410d3e4Vinay Sajip basicConfig() 1895d91085598f5185b267ea51a3f615da9527af2ed2Neal Norwitz root.log(level, msg, *args, **kwargs) 1896b2635b2f7163716d735e7eda7c1d5c039410d3e4Vinay Sajip 189757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossumdef disable(level): 189857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 1899886af966d8f5ae3a2333e559c43d721ac70d83d8Benjamin Peterson Disable all logging calls of severity 'level' and below. 190057102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 190157102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum root.manager.disable = level 190257102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 190300ee7baf49430d8a6eed355a5fd7a05179325747Thomas Woutersdef shutdown(handlerList=_handlerList): 190457102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 190557102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Perform any cleanup actions in the logging system (e.g. flushing 190657102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum buffers). 190757102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum 190857102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum Should be called at application exit. 190957102f861d506b6c2d2215d100dac9143574fa77Guido van Rossum """ 19105554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson for wr in reversed(handlerList[:]): 1911e12f71586ac4d3387fa635dd6617b4f8ebed083aVinay Sajip #errors might occur, for example, if files are locked 1912260ce43252a8144d191fa0a508d42cc8e107caa5Vinay Sajip #we just ignore them if raiseExceptions is not set 1913e12f71586ac4d3387fa635dd6617b4f8ebed083aVinay Sajip try: 19145554993d375b43114ac6b431d596a0ef2cb58a5eBenjamin Peterson h = wr() 1915de6e9d615ddada40fb0ee4e005777eb73a147058Vinay Sajip if h: 1916de6e9d615ddada40fb0ee4e005777eb73a147058Vinay Sajip try: 1917d9512e9ac11cb6b22669d7c06a321dbeb56ec0f5Vinay Sajip h.acquire() 1918de6e9d615ddada40fb0ee4e005777eb73a147058Vinay Sajip h.flush() 1919de6e9d615ddada40fb0ee4e005777eb73a147058Vinay Sajip h.close() 1920f7a17b48d748e1835bcf9df86fb7fb318bb020f8Andrew Svetlov except (OSError, ValueError): 1921de6e9d615ddada40fb0ee4e005777eb73a147058Vinay Sajip # Ignore errors which might be caused 1922de6e9d615ddada40fb0ee4e005777eb73a147058Vinay Sajip # because handlers have been closed but 1923de6e9d615ddada40fb0ee4e005777eb73a147058Vinay Sajip # references to them are still around at 1924de6e9d615ddada40fb0ee4e005777eb73a147058Vinay Sajip # application exit. 1925de6e9d615ddada40fb0ee4e005777eb73a147058Vinay Sajip pass 1926d9512e9ac11cb6b22669d7c06a321dbeb56ec0f5Vinay Sajip finally: 1927d9512e9ac11cb6b22669d7c06a321dbeb56ec0f5Vinay Sajip h.release() 19288cf4eb1463217095e9276c0caacfb2df9372504fVinay Sajip except: # ignore everything, as we're shutting down 1929260ce43252a8144d191fa0a508d42cc8e107caa5Vinay Sajip if raiseExceptions: 1930260ce43252a8144d191fa0a508d42cc8e107caa5Vinay Sajip raise 1931260ce43252a8144d191fa0a508d42cc8e107caa5Vinay Sajip #else, swallow 1932ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip 1933ed6bb1414c62d352b97af171829dcba0aa42fc8cVinay Sajip#Let's try and shutdown automatically on application exit... 193401e4d57b0f07480e37172a0ca12212b8a31ed6f7Georg Brandlimport atexit 193501e4d57b0f07480e37172a0ca12212b8a31ed6f7Georg Brandlatexit.register(shutdown) 1936f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl 1937f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl# Null handler 1938f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl 1939f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandlclass NullHandler(Handler): 1940f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl """ 1941f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl This handler does nothing. It's intended to be used to avoid the 1942f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl "No handlers could be found for logger XXX" one-off warning. This is 1943f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl important for library code, which may contain code to log events. If a user 1944f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl of the library does not configure logging, the one-off warning might be 1945f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl produced; to avoid this, the library developer simply needs to instantiate 1946f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl a NullHandler and add it to the top-level logger of the library module or 1947f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl package. 1948f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl """ 19494fbe4b340a9c2c7c286cd871070f1782fd92a7b8Vinay Sajip def handle(self, record): 1950e6c1eb92675f67d1907bd7ba00c44262c18e93d4Vinay Sajip """Stub.""" 19514fbe4b340a9c2c7c286cd871070f1782fd92a7b8Vinay Sajip 1952f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl def emit(self, record): 1953e6c1eb92675f67d1907bd7ba00c44262c18e93d4Vinay Sajip """Stub.""" 1954f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl 19554fbe4b340a9c2c7c286cd871070f1782fd92a7b8Vinay Sajip def createLock(self): 19564fbe4b340a9c2c7c286cd871070f1782fd92a7b8Vinay Sajip self.lock = None 19574fbe4b340a9c2c7c286cd871070f1782fd92a7b8Vinay Sajip 1958f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl# Warnings integration 1959f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl 1960f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl_warnings_showwarning = None 1961f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl 1962f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandldef _showwarning(message, category, filename, lineno, file=None, line=None): 1963f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl """ 1964f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl Implementation of showwarnings which redirects to logging, which will first 1965f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl check to see if the file parameter is None. If a file is specified, it will 1966f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl delegate to the original warnings implementation of showwarning. Otherwise, 1967f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl it will call warnings.formatwarning and will log the resulting string to a 1968f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl warnings logger named "py.warnings" with level logging.WARNING. 1969f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl """ 1970f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl if file is not None: 1971f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl if _warnings_showwarning is not None: 1972f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl _warnings_showwarning(message, category, filename, lineno, file, line) 1973f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl else: 1974f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl s = warnings.formatwarning(message, category, filename, lineno, line) 1975f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl logger = getLogger("py.warnings") 1976f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl if not logger.handlers: 1977f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl logger.addHandler(NullHandler()) 1978f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl logger.warning("%s", s) 1979f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl 1980f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandldef captureWarnings(capture): 1981f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl """ 1982f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl If capture is true, redirect all warnings to the logging package. 1983f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl If capture is False, ensure that warnings are not redirected to logging 1984f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl but to their original destinations. 1985f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl """ 1986f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl global _warnings_showwarning 1987f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl if capture: 1988f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl if _warnings_showwarning is None: 1989f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl _warnings_showwarning = warnings.showwarning 1990f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl warnings.showwarning = _showwarning 1991f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl else: 1992f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl if _warnings_showwarning is not None: 1993f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl warnings.showwarning = _warnings_showwarning 1994f9734076cf12444fb1b5e4296993bf6df3b1e7f2Georg Brandl _warnings_showwarning = None 1995