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