Home | History | Annotate | Download | only in logging
      1 # Copyright 2001-2014 by Vinay Sajip. All Rights Reserved.
      2 #
      3 # Permission to use, copy, modify, and distribute this software and its
      4 # documentation for any purpose and without fee is hereby granted,
      5 # provided that the above copyright notice appear in all copies and that
      6 # both that copyright notice and this permission notice appear in
      7 # supporting documentation, and that the name of Vinay Sajip
      8 # not be used in advertising or publicity pertaining to distribution
      9 # of the software without specific, written prior permission.
     10 # VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
     11 # ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
     12 # VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
     13 # ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
     14 # IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
     15 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     16 
     17 """
     18 Logging package for Python. Based on PEP 282 and comments thereto in
     19 comp.lang.python.
     20 
     21 Copyright (C) 2001-2014 Vinay Sajip. All Rights Reserved.
     22 
     23 To use, simply 'import logging' and log away!
     24 """
     25 
     26 import sys, os, time, cStringIO, traceback, warnings, weakref, collections
     27 
     28 __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
     29            'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO',
     30            'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler',
     31            'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig',
     32            'captureWarnings', 'critical', 'debug', 'disable', 'error',
     33            'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass',
     34            'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning']
     35 
     36 try:
     37     import codecs
     38 except ImportError:
     39     codecs = None
     40 
     41 try:
     42     import thread
     43     import threading
     44 except ImportError:
     45     thread = None
     46 
     47 __author__  = "Vinay Sajip <vinay_sajip (at] red-dove.com>"
     48 __status__  = "production"
     49 # Note: the attributes below are no longer maintained.
     50 __version__ = "0.5.1.2"
     51 __date__    = "07 February 2010"
     52 
     53 #---------------------------------------------------------------------------
     54 #   Miscellaneous module data
     55 #---------------------------------------------------------------------------
     56 try:
     57     unicode
     58     _unicode = True
     59 except NameError:
     60     _unicode = False
     61 
     62 # next bit filched from 1.5.2's inspect.py
     63 def currentframe():
     64     """Return the frame object for the caller's stack frame."""
     65     try:
     66         raise Exception
     67     except:
     68         return sys.exc_info()[2].tb_frame.f_back
     69 
     70 if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
     71 # done filching
     72 
     73 #
     74 # _srcfile is used when walking the stack to check when we've got the first
     75 # caller stack frame.
     76 #
     77 _srcfile = os.path.normcase(currentframe.__code__.co_filename)
     78 
     79 # _srcfile is only used in conjunction with sys._getframe().
     80 # To provide compatibility with older versions of Python, set _srcfile
     81 # to None if _getframe() is not available; this value will prevent
     82 # findCaller() from being called.
     83 #if not hasattr(sys, "_getframe"):
     84 #    _srcfile = None
     85 
     86 #
     87 #_startTime is used as the base when calculating the relative time of events
     88 #
     89 _startTime = time.time()
     90 
     91 #
     92 #raiseExceptions is used to see if exceptions during handling should be
     93 #propagated
     94 #
     95 raiseExceptions = 1
     96 
     97 #
     98 # If you don't want threading information in the log, set this to zero
     99 #
    100 logThreads = 1
    101 
    102 #
    103 # If you don't want multiprocessing information in the log, set this to zero
    104 #
    105 logMultiprocessing = 1
    106 
    107 #
    108 # If you don't want process information in the log, set this to zero
    109 #
    110 logProcesses = 1
    111 
    112 #---------------------------------------------------------------------------
    113 #   Level related stuff
    114 #---------------------------------------------------------------------------
    115 #
    116 # Default levels and level names, these can be replaced with any positive set
    117 # of values having corresponding names. There is a pseudo-level, NOTSET, which
    118 # is only really there as a lower limit for user-defined levels. Handlers and
    119 # loggers are initialized with NOTSET so that they will log all messages, even
    120 # at user-defined levels.
    121 #
    122 
    123 CRITICAL = 50
    124 FATAL = CRITICAL
    125 ERROR = 40
    126 WARNING = 30
    127 WARN = WARNING
    128 INFO = 20
    129 DEBUG = 10
    130 NOTSET = 0
    131 
    132 _levelNames = {
    133     CRITICAL : 'CRITICAL',
    134     ERROR : 'ERROR',
    135     WARNING : 'WARNING',
    136     INFO : 'INFO',
    137     DEBUG : 'DEBUG',
    138     NOTSET : 'NOTSET',
    139     'CRITICAL' : CRITICAL,
    140     'ERROR' : ERROR,
    141     'WARN' : WARNING,
    142     'WARNING' : WARNING,
    143     'INFO' : INFO,
    144     'DEBUG' : DEBUG,
    145     'NOTSET' : NOTSET,
    146 }
    147 
    148 def getLevelName(level):
    149     """
    150     Return the textual representation of logging level 'level'.
    151 
    152     If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
    153     INFO, DEBUG) then you get the corresponding string. If you have
    154     associated levels with names using addLevelName then the name you have
    155     associated with 'level' is returned.
    156 
    157     If a numeric value corresponding to one of the defined levels is passed
    158     in, the corresponding string representation is returned.
    159 
    160     Otherwise, the string "Level %s" % level is returned.
    161     """
    162     return _levelNames.get(level, ("Level %s" % level))
    163 
    164 def addLevelName(level, levelName):
    165     """
    166     Associate 'levelName' with 'level'.
    167 
    168     This is used when converting levels to text during message formatting.
    169     """
    170     _acquireLock()
    171     try:    #unlikely to cause an exception, but you never know...
    172         _levelNames[level] = levelName
    173         _levelNames[levelName] = level
    174     finally:
    175         _releaseLock()
    176 
    177 def _checkLevel(level):
    178     if isinstance(level, (int, long)):
    179         rv = level
    180     elif str(level) == level:
    181         if level not in _levelNames:
    182             raise ValueError("Unknown level: %r" % level)
    183         rv = _levelNames[level]
    184     else:
    185         raise TypeError("Level not an integer or a valid string: %r" % level)
    186     return rv
    187 
    188 #---------------------------------------------------------------------------
    189 #   Thread-related stuff
    190 #---------------------------------------------------------------------------
    191 
    192 #
    193 #_lock is used to serialize access to shared data structures in this module.
    194 #This needs to be an RLock because fileConfig() creates and configures
    195 #Handlers, and so might arbitrary user threads. Since Handler code updates the
    196 #shared dictionary _handlers, it needs to acquire the lock. But if configuring,
    197 #the lock would already have been acquired - so we need an RLock.
    198 #The same argument applies to Loggers and Manager.loggerDict.
    199 #
    200 if thread:
    201     _lock = threading.RLock()
    202 else:
    203     _lock = None
    204 
    205 def _acquireLock():
    206     """
    207     Acquire the module-level lock for serializing access to shared data.
    208 
    209     This should be released with _releaseLock().
    210     """
    211     if _lock:
    212         _lock.acquire()
    213 
    214 def _releaseLock():
    215     """
    216     Release the module-level lock acquired by calling _acquireLock().
    217     """
    218     if _lock:
    219         _lock.release()
    220 
    221 #---------------------------------------------------------------------------
    222 #   The logging record
    223 #---------------------------------------------------------------------------
    224 
    225 class LogRecord(object):
    226     """
    227     A LogRecord instance represents an event being logged.
    228 
    229     LogRecord instances are created every time something is logged. They
    230     contain all the information pertinent to the event being logged. The
    231     main information passed in is in msg and args, which are combined
    232     using str(msg) % args to create the message field of the record. The
    233     record also includes information such as when the record was created,
    234     the source line where the logging call was made, and any exception
    235     information to be logged.
    236     """
    237     def __init__(self, name, level, pathname, lineno,
    238                  msg, args, exc_info, func=None):
    239         """
    240         Initialize a logging record with interesting information.
    241         """
    242         ct = time.time()
    243         self.name = name
    244         self.msg = msg
    245         #
    246         # The following statement allows passing of a dictionary as a sole
    247         # argument, so that you can do something like
    248         #  logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
    249         # Suggested by Stefan Behnel.
    250         # Note that without the test for args[0], we get a problem because
    251         # during formatting, we test to see if the arg is present using
    252         # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
    253         # and if the passed arg fails 'if self.args:' then no formatting
    254         # is done. For example, logger.warn('Value is %d', 0) would log
    255         # 'Value is %d' instead of 'Value is 0'.
    256         # For the use case of passing a dictionary, this should not be a
    257         # problem.
    258         # Issue #21172: a request was made to relax the isinstance check
    259         # to hasattr(args[0], '__getitem__'). However, the docs on string
    260         # formatting still seem to suggest a mapping object is required.
    261         # Thus, while not removing the isinstance check, it does now look
    262         # for collections.Mapping rather than, as before, dict.
    263         if (args and len(args) == 1 and isinstance(args[0], collections.Mapping)
    264             and args[0]):
    265             args = args[0]
    266         self.args = args
    267         self.levelname = getLevelName(level)
    268         self.levelno = level
    269         self.pathname = pathname
    270         try:
    271             self.filename = os.path.basename(pathname)
    272             self.module = os.path.splitext(self.filename)[0]
    273         except (TypeError, ValueError, AttributeError):
    274             self.filename = pathname
    275             self.module = "Unknown module"
    276         self.exc_info = exc_info
    277         self.exc_text = None      # used to cache the traceback text
    278         self.lineno = lineno
    279         self.funcName = func
    280         self.created = ct
    281         self.msecs = (ct - long(ct)) * 1000
    282         self.relativeCreated = (self.created - _startTime) * 1000
    283         if logThreads and thread:
    284             self.thread = thread.get_ident()
    285             self.threadName = threading.current_thread().name
    286         else:
    287             self.thread = None
    288             self.threadName = None
    289         if not logMultiprocessing:
    290             self.processName = None
    291         else:
    292             self.processName = 'MainProcess'
    293             mp = sys.modules.get('multiprocessing')
    294             if mp is not None:
    295                 # Errors may occur if multiprocessing has not finished loading
    296                 # yet - e.g. if a custom import hook causes third-party code
    297                 # to run when multiprocessing calls import. See issue 8200
    298                 # for an example
    299                 try:
    300                     self.processName = mp.current_process().name
    301                 except StandardError:
    302                     pass
    303         if logProcesses and hasattr(os, 'getpid'):
    304             self.process = os.getpid()
    305         else:
    306             self.process = None
    307 
    308     def __str__(self):
    309         return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
    310             self.pathname, self.lineno, self.msg)
    311 
    312     def getMessage(self):
    313         """
    314         Return the message for this LogRecord.
    315 
    316         Return the message for this LogRecord after merging any user-supplied
    317         arguments with the message.
    318         """
    319         if not _unicode: #if no unicode support...
    320             msg = str(self.msg)
    321         else:
    322             msg = self.msg
    323             if not isinstance(msg, basestring):
    324                 try:
    325                     msg = str(self.msg)
    326                 except UnicodeError:
    327                     msg = self.msg      #Defer encoding till later
    328         if self.args:
    329             msg = msg % self.args
    330         return msg
    331 
    332 def makeLogRecord(dict):
    333     """
    334     Make a LogRecord whose attributes are defined by the specified dictionary,
    335     This function is useful for converting a logging event received over
    336     a socket connection (which is sent as a dictionary) into a LogRecord
    337     instance.
    338     """
    339     rv = LogRecord(None, None, "", 0, "", (), None, None)
    340     rv.__dict__.update(dict)
    341     return rv
    342 
    343 #---------------------------------------------------------------------------
    344 #   Formatter classes and functions
    345 #---------------------------------------------------------------------------
    346 
    347 class Formatter(object):
    348     """
    349     Formatter instances are used to convert a LogRecord to text.
    350 
    351     Formatters need to know how a LogRecord is constructed. They are
    352     responsible for converting a LogRecord to (usually) a string which can
    353     be interpreted by either a human or an external system. The base Formatter
    354     allows a formatting string to be specified. If none is supplied, the
    355     default value of "%s(message)\\n" is used.
    356 
    357     The Formatter can be initialized with a format string which makes use of
    358     knowledge of the LogRecord attributes - e.g. the default value mentioned
    359     above makes use of the fact that the user's message and arguments are pre-
    360     formatted into a LogRecord's message attribute. Currently, the useful
    361     attributes in a LogRecord are described by:
    362 
    363     %(name)s            Name of the logger (logging channel)
    364     %(levelno)s         Numeric logging level for the message (DEBUG, INFO,
    365                         WARNING, ERROR, CRITICAL)
    366     %(levelname)s       Text logging level for the message ("DEBUG", "INFO",
    367                         "WARNING", "ERROR", "CRITICAL")
    368     %(pathname)s        Full pathname of the source file where the logging
    369                         call was issued (if available)
    370     %(filename)s        Filename portion of pathname
    371     %(module)s          Module (name portion of filename)
    372     %(lineno)d          Source line number where the logging call was issued
    373                         (if available)
    374     %(funcName)s        Function name
    375     %(created)f         Time when the LogRecord was created (time.time()
    376                         return value)
    377     %(asctime)s         Textual time when the LogRecord was created
    378     %(msecs)d           Millisecond portion of the creation time
    379     %(relativeCreated)d Time in milliseconds when the LogRecord was created,
    380                         relative to the time the logging module was loaded
    381                         (typically at application startup time)
    382     %(thread)d          Thread ID (if available)
    383     %(threadName)s      Thread name (if available)
    384     %(process)d         Process ID (if available)
    385     %(message)s         The result of record.getMessage(), computed just as
    386                         the record is emitted
    387     """
    388 
    389     converter = time.localtime
    390 
    391     def __init__(self, fmt=None, datefmt=None):
    392         """
    393         Initialize the formatter with specified format strings.
    394 
    395         Initialize the formatter either with the specified format string, or a
    396         default as described above. Allow for specialized date formatting with
    397         the optional datefmt argument (if omitted, you get the ISO8601 format).
    398         """
    399         if fmt:
    400             self._fmt = fmt
    401         else:
    402             self._fmt = "%(message)s"
    403         self.datefmt = datefmt
    404 
    405     def formatTime(self, record, datefmt=None):
    406         """
    407         Return the creation time of the specified LogRecord as formatted text.
    408 
    409         This method should be called from format() by a formatter which
    410         wants to make use of a formatted time. This method can be overridden
    411         in formatters to provide for any specific requirement, but the
    412         basic behaviour is as follows: if datefmt (a string) is specified,
    413         it is used with time.strftime() to format the creation time of the
    414         record. Otherwise, the ISO8601 format is used. The resulting
    415         string is returned. This function uses a user-configurable function
    416         to convert the creation time to a tuple. By default, time.localtime()
    417         is used; to change this for a particular formatter instance, set the
    418         'converter' attribute to a function with the same signature as
    419         time.localtime() or time.gmtime(). To change it for all formatters,
    420         for example if you want all logging times to be shown in GMT,
    421         set the 'converter' attribute in the Formatter class.
    422         """
    423         ct = self.converter(record.created)
    424         if datefmt:
    425             s = time.strftime(datefmt, ct)
    426         else:
    427             t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
    428             s = "%s,%03d" % (t, record.msecs)
    429         return s
    430 
    431     def formatException(self, ei):
    432         """
    433         Format and return the specified exception information as a string.
    434 
    435         This default implementation just uses
    436         traceback.print_exception()
    437         """
    438         sio = cStringIO.StringIO()
    439         traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
    440         s = sio.getvalue()
    441         sio.close()
    442         if s[-1:] == "\n":
    443             s = s[:-1]
    444         return s
    445 
    446     def usesTime(self):
    447         """
    448         Check if the format uses the creation time of the record.
    449         """
    450         return self._fmt.find("%(asctime)") >= 0
    451 
    452     def format(self, record):
    453         """
    454         Format the specified record as text.
    455 
    456         The record's attribute dictionary is used as the operand to a
    457         string formatting operation which yields the returned string.
    458         Before formatting the dictionary, a couple of preparatory steps
    459         are carried out. The message attribute of the record is computed
    460         using LogRecord.getMessage(). If the formatting string uses the
    461         time (as determined by a call to usesTime(), formatTime() is
    462         called to format the event time. If there is exception information,
    463         it is formatted using formatException() and appended to the message.
    464         """
    465         record.message = record.getMessage()
    466         if self.usesTime():
    467             record.asctime = self.formatTime(record, self.datefmt)
    468         try:
    469             s = self._fmt % record.__dict__
    470         except UnicodeDecodeError as e:
    471             # Issue 25664. The logger name may be Unicode. Try again ...
    472             try:
    473                 record.name = record.name.decode('utf-8')
    474                 s = self._fmt % record.__dict__
    475             except UnicodeDecodeError:
    476                 raise e
    477         if record.exc_info:
    478             # Cache the traceback text to avoid converting it multiple times
    479             # (it's constant anyway)
    480             if not record.exc_text:
    481                 record.exc_text = self.formatException(record.exc_info)
    482         if record.exc_text:
    483             if s[-1:] != "\n":
    484                 s = s + "\n"
    485             try:
    486                 s = s + record.exc_text
    487             except UnicodeError:
    488                 # Sometimes filenames have non-ASCII chars, which can lead
    489                 # to errors when s is Unicode and record.exc_text is str
    490                 # See issue 8924.
    491                 # We also use replace for when there are multiple
    492                 # encodings, e.g. UTF-8 for the filesystem and latin-1
    493                 # for a script. See issue 13232.
    494                 s = s + record.exc_text.decode(sys.getfilesystemencoding(),
    495                                                'replace')
    496         return s
    497 
    498 #
    499 #   The default formatter to use when no other is specified
    500 #
    501 _defaultFormatter = Formatter()
    502 
    503 class BufferingFormatter(object):
    504     """
    505     A formatter suitable for formatting a number of records.
    506     """
    507     def __init__(self, linefmt=None):
    508         """
    509         Optionally specify a formatter which will be used to format each
    510         individual record.
    511         """
    512         if linefmt:
    513             self.linefmt = linefmt
    514         else:
    515             self.linefmt = _defaultFormatter
    516 
    517     def formatHeader(self, records):
    518         """
    519         Return the header string for the specified records.
    520         """
    521         return ""
    522 
    523     def formatFooter(self, records):
    524         """
    525         Return the footer string for the specified records.
    526         """
    527         return ""
    528 
    529     def format(self, records):
    530         """
    531         Format the specified records and return the result as a string.
    532         """
    533         rv = ""
    534         if len(records) > 0:
    535             rv = rv + self.formatHeader(records)
    536             for record in records:
    537                 rv = rv + self.linefmt.format(record)
    538             rv = rv + self.formatFooter(records)
    539         return rv
    540 
    541 #---------------------------------------------------------------------------
    542 #   Filter classes and functions
    543 #---------------------------------------------------------------------------
    544 
    545 class Filter(object):
    546     """
    547     Filter instances are used to perform arbitrary filtering of LogRecords.
    548 
    549     Loggers and Handlers can optionally use Filter instances to filter
    550     records as desired. The base filter class only allows events which are
    551     below a certain point in the logger hierarchy. For example, a filter
    552     initialized with "A.B" will allow events logged by loggers "A.B",
    553     "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
    554     initialized with the empty string, all events are passed.
    555     """
    556     def __init__(self, name=''):
    557         """
    558         Initialize a filter.
    559 
    560         Initialize with the name of the logger which, together with its
    561         children, will have its events allowed through the filter. If no
    562         name is specified, allow every event.
    563         """
    564         self.name = name
    565         self.nlen = len(name)
    566 
    567     def filter(self, record):
    568         """
    569         Determine if the specified record is to be logged.
    570 
    571         Is the specified record to be logged? Returns 0 for no, nonzero for
    572         yes. If deemed appropriate, the record may be modified in-place.
    573         """
    574         if self.nlen == 0:
    575             return 1
    576         elif self.name == record.name:
    577             return 1
    578         elif record.name.find(self.name, 0, self.nlen) != 0:
    579             return 0
    580         return (record.name[self.nlen] == ".")
    581 
    582 class Filterer(object):
    583     """
    584     A base class for loggers and handlers which allows them to share
    585     common code.
    586     """
    587     def __init__(self):
    588         """
    589         Initialize the list of filters to be an empty list.
    590         """
    591         self.filters = []
    592 
    593     def addFilter(self, filter):
    594         """
    595         Add the specified filter to this handler.
    596         """
    597         if not (filter in self.filters):
    598             self.filters.append(filter)
    599 
    600     def removeFilter(self, filter):
    601         """
    602         Remove the specified filter from this handler.
    603         """
    604         if filter in self.filters:
    605             self.filters.remove(filter)
    606 
    607     def filter(self, record):
    608         """
    609         Determine if a record is loggable by consulting all the filters.
    610 
    611         The default is to allow the record to be logged; any filter can veto
    612         this and the record is then dropped. Returns a zero value if a record
    613         is to be dropped, else non-zero.
    614         """
    615         rv = 1
    616         for f in self.filters:
    617             if not f.filter(record):
    618                 rv = 0
    619                 break
    620         return rv
    621 
    622 #---------------------------------------------------------------------------
    623 #   Handler classes and functions
    624 #---------------------------------------------------------------------------
    625 
    626 _handlers = weakref.WeakValueDictionary()  #map of handler names to handlers
    627 _handlerList = [] # added to allow handlers to be removed in reverse of order initialized
    628 
    629 def _removeHandlerRef(wr):
    630     """
    631     Remove a handler reference from the internal cleanup list.
    632     """
    633     # This function can be called during module teardown, when globals are
    634     # set to None. It can also be called from another thread. So we need to
    635     # pre-emptively grab the necessary globals and check if they're None,
    636     # to prevent race conditions and failures during interpreter shutdown.
    637     acquire, release, handlers = _acquireLock, _releaseLock, _handlerList
    638     if acquire and release and handlers:
    639         acquire()
    640         try:
    641             if wr in handlers:
    642                 handlers.remove(wr)
    643         finally:
    644             release()
    645 
    646 def _addHandlerRef(handler):
    647     """
    648     Add a handler to the internal cleanup list using a weak reference.
    649     """
    650     _acquireLock()
    651     try:
    652         _handlerList.append(weakref.ref(handler, _removeHandlerRef))
    653     finally:
    654         _releaseLock()
    655 
    656 class Handler(Filterer):
    657     """
    658     Handler instances dispatch logging events to specific destinations.
    659 
    660     The base handler class. Acts as a placeholder which defines the Handler
    661     interface. Handlers can optionally use Formatter instances to format
    662     records as desired. By default, no formatter is specified; in this case,
    663     the 'raw' message as determined by record.message is logged.
    664     """
    665     def __init__(self, level=NOTSET):
    666         """
    667         Initializes the instance - basically setting the formatter to None
    668         and the filter list to empty.
    669         """
    670         Filterer.__init__(self)
    671         self._name = None
    672         self.level = _checkLevel(level)
    673         self.formatter = None
    674         # Add the handler to the global _handlerList (for cleanup on shutdown)
    675         _addHandlerRef(self)
    676         self.createLock()
    677 
    678     def get_name(self):
    679         return self._name
    680 
    681     def set_name(self, name):
    682         _acquireLock()
    683         try:
    684             if self._name in _handlers:
    685                 del _handlers[self._name]
    686             self._name = name
    687             if name:
    688                 _handlers[name] = self
    689         finally:
    690             _releaseLock()
    691 
    692     name = property(get_name, set_name)
    693 
    694     def createLock(self):
    695         """
    696         Acquire a thread lock for serializing access to the underlying I/O.
    697         """
    698         if thread:
    699             self.lock = threading.RLock()
    700         else:
    701             self.lock = None
    702 
    703     def acquire(self):
    704         """
    705         Acquire the I/O thread lock.
    706         """
    707         if self.lock:
    708             self.lock.acquire()
    709 
    710     def release(self):
    711         """
    712         Release the I/O thread lock.
    713         """
    714         if self.lock:
    715             self.lock.release()
    716 
    717     def setLevel(self, level):
    718         """
    719         Set the logging level of this handler.
    720         """
    721         self.level = _checkLevel(level)
    722 
    723     def format(self, record):
    724         """
    725         Format the specified record.
    726 
    727         If a formatter is set, use it. Otherwise, use the default formatter
    728         for the module.
    729         """
    730         if self.formatter:
    731             fmt = self.formatter
    732         else:
    733             fmt = _defaultFormatter
    734         return fmt.format(record)
    735 
    736     def emit(self, record):
    737         """
    738         Do whatever it takes to actually log the specified logging record.
    739 
    740         This version is intended to be implemented by subclasses and so
    741         raises a NotImplementedError.
    742         """
    743         raise NotImplementedError('emit must be implemented '
    744                                   'by Handler subclasses')
    745 
    746     def handle(self, record):
    747         """
    748         Conditionally emit the specified logging record.
    749 
    750         Emission depends on filters which may have been added to the handler.
    751         Wrap the actual emission of the record with acquisition/release of
    752         the I/O thread lock. Returns whether the filter passed the record for
    753         emission.
    754         """
    755         rv = self.filter(record)
    756         if rv:
    757             self.acquire()
    758             try:
    759                 self.emit(record)
    760             finally:
    761                 self.release()
    762         return rv
    763 
    764     def setFormatter(self, fmt):
    765         """
    766         Set the formatter for this handler.
    767         """
    768         self.formatter = fmt
    769 
    770     def flush(self):
    771         """
    772         Ensure all logging output has been flushed.
    773 
    774         This version does nothing and is intended to be implemented by
    775         subclasses.
    776         """
    777         pass
    778 
    779     def close(self):
    780         """
    781         Tidy up any resources used by the handler.
    782 
    783         This version removes the handler from an internal map of handlers,
    784         _handlers, which is used for handler lookup by name. Subclasses
    785         should ensure that this gets called from overridden close()
    786         methods.
    787         """
    788         #get the module data lock, as we're updating a shared structure.
    789         _acquireLock()
    790         try:    #unlikely to raise an exception, but you never know...
    791             if self._name and self._name in _handlers:
    792                 del _handlers[self._name]
    793         finally:
    794             _releaseLock()
    795 
    796     def handleError(self, record):
    797         """
    798         Handle errors which occur during an emit() call.
    799 
    800         This method should be called from handlers when an exception is
    801         encountered during an emit() call. If raiseExceptions is false,
    802         exceptions get silently ignored. This is what is mostly wanted
    803         for a logging system - most users will not care about errors in
    804         the logging system, they are more interested in application errors.
    805         You could, however, replace this with a custom handler if you wish.
    806         The record which was being processed is passed in to this method.
    807         """
    808         if raiseExceptions and sys.stderr:  # see issue 13807
    809             ei = sys.exc_info()
    810             try:
    811                 traceback.print_exception(ei[0], ei[1], ei[2],
    812                                           None, sys.stderr)
    813                 sys.stderr.write('Logged from file %s, line %s\n' % (
    814                                  record.filename, record.lineno))
    815             except IOError:
    816                 pass    # see issue 5971
    817             finally:
    818                 del ei
    819 
    820 class StreamHandler(Handler):
    821     """
    822     A handler class which writes logging records, appropriately formatted,
    823     to a stream. Note that this class does not close the stream, as
    824     sys.stdout or sys.stderr may be used.
    825     """
    826 
    827     def __init__(self, stream=None):
    828         """
    829         Initialize the handler.
    830 
    831         If stream is not specified, sys.stderr is used.
    832         """
    833         Handler.__init__(self)
    834         if stream is None:
    835             stream = sys.stderr
    836         self.stream = stream
    837 
    838     def flush(self):
    839         """
    840         Flushes the stream.
    841         """
    842         self.acquire()
    843         try:
    844             if self.stream and hasattr(self.stream, "flush"):
    845                 self.stream.flush()
    846         finally:
    847             self.release()
    848 
    849     def emit(self, record):
    850         """
    851         Emit a record.
    852 
    853         If a formatter is specified, it is used to format the record.
    854         The record is then written to the stream with a trailing newline.  If
    855         exception information is present, it is formatted using
    856         traceback.print_exception and appended to the stream.  If the stream
    857         has an 'encoding' attribute, it is used to determine how to do the
    858         output to the stream.
    859         """
    860         try:
    861             msg = self.format(record)
    862             stream = self.stream
    863             fs = "%s\n"
    864             if not _unicode: #if no unicode support...
    865                 stream.write(fs % msg)
    866             else:
    867                 try:
    868                     if (isinstance(msg, unicode) and
    869                         getattr(stream, 'encoding', None)):
    870                         ufs = u'%s\n'
    871                         try:
    872                             stream.write(ufs % msg)
    873                         except UnicodeEncodeError:
    874                             #Printing to terminals sometimes fails. For example,
    875                             #with an encoding of 'cp1251', the above write will
    876                             #work if written to a stream opened or wrapped by
    877                             #the codecs module, but fail when writing to a
    878                             #terminal even when the codepage is set to cp1251.
    879                             #An extra encoding step seems to be needed.
    880                             stream.write((ufs % msg).encode(stream.encoding))
    881                     else:
    882                         stream.write(fs % msg)
    883                 except UnicodeError:
    884                     stream.write(fs % msg.encode("UTF-8"))
    885             self.flush()
    886         except (KeyboardInterrupt, SystemExit):
    887             raise
    888         except:
    889             self.handleError(record)
    890 
    891 class FileHandler(StreamHandler):
    892     """
    893     A handler class which writes formatted logging records to disk files.
    894     """
    895     def __init__(self, filename, mode='a', encoding=None, delay=0):
    896         """
    897         Open the specified file and use it as the stream for logging.
    898         """
    899         #keep the absolute path, otherwise derived classes which use this
    900         #may come a cropper when the current directory changes
    901         if codecs is None:
    902             encoding = None
    903         self.baseFilename = os.path.abspath(filename)
    904         self.mode = mode
    905         self.encoding = encoding
    906         self.delay = delay
    907         if delay:
    908             #We don't open the stream, but we still need to call the
    909             #Handler constructor to set level, formatter, lock etc.
    910             Handler.__init__(self)
    911             self.stream = None
    912         else:
    913             StreamHandler.__init__(self, self._open())
    914 
    915     def close(self):
    916         """
    917         Closes the stream.
    918         """
    919         self.acquire()
    920         try:
    921             try:
    922                 if self.stream:
    923                     try:
    924                         self.flush()
    925                     finally:
    926                         stream = self.stream
    927                         self.stream = None
    928                         if hasattr(stream, "close"):
    929                             stream.close()
    930             finally:
    931                 # Issue #19523: call unconditionally to
    932                 # prevent a handler leak when delay is set
    933                 StreamHandler.close(self)
    934         finally:
    935             self.release()
    936 
    937     def _open(self):
    938         """
    939         Open the current base file with the (original) mode and encoding.
    940         Return the resulting stream.
    941         """
    942         if self.encoding is None:
    943             stream = open(self.baseFilename, self.mode)
    944         else:
    945             stream = codecs.open(self.baseFilename, self.mode, self.encoding)
    946         return stream
    947 
    948     def emit(self, record):
    949         """
    950         Emit a record.
    951 
    952         If the stream was not opened because 'delay' was specified in the
    953         constructor, open it before calling the superclass's emit.
    954         """
    955         if self.stream is None:
    956             self.stream = self._open()
    957         StreamHandler.emit(self, record)
    958 
    959 #---------------------------------------------------------------------------
    960 #   Manager classes and functions
    961 #---------------------------------------------------------------------------
    962 
    963 class PlaceHolder(object):
    964     """
    965     PlaceHolder instances are used in the Manager logger hierarchy to take
    966     the place of nodes for which no loggers have been defined. This class is
    967     intended for internal use only and not as part of the public API.
    968     """
    969     def __init__(self, alogger):
    970         """
    971         Initialize with the specified logger being a child of this placeholder.
    972         """
    973         #self.loggers = [alogger]
    974         self.loggerMap = { alogger : None }
    975 
    976     def append(self, alogger):
    977         """
    978         Add the specified logger as a child of this placeholder.
    979         """
    980         #if alogger not in self.loggers:
    981         if alogger not in self.loggerMap:
    982             #self.loggers.append(alogger)
    983             self.loggerMap[alogger] = None
    984 
    985 #
    986 #   Determine which class to use when instantiating loggers.
    987 #
    988 _loggerClass = None
    989 
    990 def setLoggerClass(klass):
    991     """
    992     Set the class to be used when instantiating a logger. The class should
    993     define __init__() such that only a name argument is required, and the
    994     __init__() should call Logger.__init__()
    995     """
    996     if klass != Logger:
    997         if not issubclass(klass, Logger):
    998             raise TypeError("logger not derived from logging.Logger: "
    999                             + klass.__name__)
   1000     global _loggerClass
   1001     _loggerClass = klass
   1002 
   1003 def getLoggerClass():
   1004     """
   1005     Return the class to be used when instantiating a logger.
   1006     """
   1007 
   1008     return _loggerClass
   1009 
   1010 class Manager(object):
   1011     """
   1012     There is [under normal circumstances] just one Manager instance, which
   1013     holds the hierarchy of loggers.
   1014     """
   1015     def __init__(self, rootnode):
   1016         """
   1017         Initialize the manager with the root node of the logger hierarchy.
   1018         """
   1019         self.root = rootnode
   1020         self.disable = 0
   1021         self.emittedNoHandlerWarning = 0
   1022         self.loggerDict = {}
   1023         self.loggerClass = None
   1024 
   1025     def getLogger(self, name):
   1026         """
   1027         Get a logger with the specified name (channel name), creating it
   1028         if it doesn't yet exist. This name is a dot-separated hierarchical
   1029         name, such as "a", "a.b", "a.b.c" or similar.
   1030 
   1031         If a PlaceHolder existed for the specified name [i.e. the logger
   1032         didn't exist but a child of it did], replace it with the created
   1033         logger and fix up the parent/child references which pointed to the
   1034         placeholder to now point to the logger.
   1035         """
   1036         rv = None
   1037         if not isinstance(name, basestring):
   1038             raise TypeError('A logger name must be string or Unicode')
   1039         if isinstance(name, unicode):
   1040             name = name.encode('utf-8')
   1041         _acquireLock()
   1042         try:
   1043             if name in self.loggerDict:
   1044                 rv = self.loggerDict[name]
   1045                 if isinstance(rv, PlaceHolder):
   1046                     ph = rv
   1047                     rv = (self.loggerClass or _loggerClass)(name)
   1048                     rv.manager = self
   1049                     self.loggerDict[name] = rv
   1050                     self._fixupChildren(ph, rv)
   1051                     self._fixupParents(rv)
   1052             else:
   1053                 rv = (self.loggerClass or _loggerClass)(name)
   1054                 rv.manager = self
   1055                 self.loggerDict[name] = rv
   1056                 self._fixupParents(rv)
   1057         finally:
   1058             _releaseLock()
   1059         return rv
   1060 
   1061     def setLoggerClass(self, klass):
   1062         """
   1063         Set the class to be used when instantiating a logger with this Manager.
   1064         """
   1065         if klass != Logger:
   1066             if not issubclass(klass, Logger):
   1067                 raise TypeError("logger not derived from logging.Logger: "
   1068                                 + klass.__name__)
   1069         self.loggerClass = klass
   1070 
   1071     def _fixupParents(self, alogger):
   1072         """
   1073         Ensure that there are either loggers or placeholders all the way
   1074         from the specified logger to the root of the logger hierarchy.
   1075         """
   1076         name = alogger.name
   1077         i = name.rfind(".")
   1078         rv = None
   1079         while (i > 0) and not rv:
   1080             substr = name[:i]
   1081             if substr not in self.loggerDict:
   1082                 self.loggerDict[substr] = PlaceHolder(alogger)
   1083             else:
   1084                 obj = self.loggerDict[substr]
   1085                 if isinstance(obj, Logger):
   1086                     rv = obj
   1087                 else:
   1088                     assert isinstance(obj, PlaceHolder)
   1089                     obj.append(alogger)
   1090             i = name.rfind(".", 0, i - 1)
   1091         if not rv:
   1092             rv = self.root
   1093         alogger.parent = rv
   1094 
   1095     def _fixupChildren(self, ph, alogger):
   1096         """
   1097         Ensure that children of the placeholder ph are connected to the
   1098         specified logger.
   1099         """
   1100         name = alogger.name
   1101         namelen = len(name)
   1102         for c in ph.loggerMap.keys():
   1103             #The if means ... if not c.parent.name.startswith(nm)
   1104             if c.parent.name[:namelen] != name:
   1105                 alogger.parent = c.parent
   1106                 c.parent = alogger
   1107 
   1108 #---------------------------------------------------------------------------
   1109 #   Logger classes and functions
   1110 #---------------------------------------------------------------------------
   1111 
   1112 class Logger(Filterer):
   1113     """
   1114     Instances of the Logger class represent a single logging channel. A
   1115     "logging channel" indicates an area of an application. Exactly how an
   1116     "area" is defined is up to the application developer. Since an
   1117     application can have any number of areas, logging channels are identified
   1118     by a unique string. Application areas can be nested (e.g. an area
   1119     of "input processing" might include sub-areas "read CSV files", "read
   1120     XLS files" and "read Gnumeric files"). To cater for this natural nesting,
   1121     channel names are organized into a namespace hierarchy where levels are
   1122     separated by periods, much like the Java or Python package namespace. So
   1123     in the instance given above, channel names might be "input" for the upper
   1124     level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
   1125     There is no arbitrary limit to the depth of nesting.
   1126     """
   1127     def __init__(self, name, level=NOTSET):
   1128         """
   1129         Initialize the logger with a name and an optional level.
   1130         """
   1131         Filterer.__init__(self)
   1132         self.name = name
   1133         self.level = _checkLevel(level)
   1134         self.parent = None
   1135         self.propagate = 1
   1136         self.handlers = []
   1137         self.disabled = 0
   1138 
   1139     def setLevel(self, level):
   1140         """
   1141         Set the logging level of this logger.
   1142         """
   1143         self.level = _checkLevel(level)
   1144 
   1145     def debug(self, msg, *args, **kwargs):
   1146         """
   1147         Log 'msg % args' with severity 'DEBUG'.
   1148 
   1149         To pass exception information, use the keyword argument exc_info with
   1150         a true value, e.g.
   1151 
   1152         logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
   1153         """
   1154         if self.isEnabledFor(DEBUG):
   1155             self._log(DEBUG, msg, args, **kwargs)
   1156 
   1157     def info(self, msg, *args, **kwargs):
   1158         """
   1159         Log 'msg % args' with severity 'INFO'.
   1160 
   1161         To pass exception information, use the keyword argument exc_info with
   1162         a true value, e.g.
   1163 
   1164         logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
   1165         """
   1166         if self.isEnabledFor(INFO):
   1167             self._log(INFO, msg, args, **kwargs)
   1168 
   1169     def warning(self, msg, *args, **kwargs):
   1170         """
   1171         Log 'msg % args' with severity 'WARNING'.
   1172 
   1173         To pass exception information, use the keyword argument exc_info with
   1174         a true value, e.g.
   1175 
   1176         logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
   1177         """
   1178         if self.isEnabledFor(WARNING):
   1179             self._log(WARNING, msg, args, **kwargs)
   1180 
   1181     warn = warning
   1182 
   1183     def error(self, msg, *args, **kwargs):
   1184         """
   1185         Log 'msg % args' with severity 'ERROR'.
   1186 
   1187         To pass exception information, use the keyword argument exc_info with
   1188         a true value, e.g.
   1189 
   1190         logger.error("Houston, we have a %s", "major problem", exc_info=1)
   1191         """
   1192         if self.isEnabledFor(ERROR):
   1193             self._log(ERROR, msg, args, **kwargs)
   1194 
   1195     def exception(self, msg, *args, **kwargs):
   1196         """
   1197         Convenience method for logging an ERROR with exception information.
   1198         """
   1199         kwargs['exc_info'] = 1
   1200         self.error(msg, *args, **kwargs)
   1201 
   1202     def critical(self, msg, *args, **kwargs):
   1203         """
   1204         Log 'msg % args' with severity 'CRITICAL'.
   1205 
   1206         To pass exception information, use the keyword argument exc_info with
   1207         a true value, e.g.
   1208 
   1209         logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
   1210         """
   1211         if self.isEnabledFor(CRITICAL):
   1212             self._log(CRITICAL, msg, args, **kwargs)
   1213 
   1214     fatal = critical
   1215 
   1216     def log(self, level, msg, *args, **kwargs):
   1217         """
   1218         Log 'msg % args' with the integer severity 'level'.
   1219 
   1220         To pass exception information, use the keyword argument exc_info with
   1221         a true value, e.g.
   1222 
   1223         logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
   1224         """
   1225         if not isinstance(level, int):
   1226             if raiseExceptions:
   1227                 raise TypeError("level must be an integer")
   1228             else:
   1229                 return
   1230         if self.isEnabledFor(level):
   1231             self._log(level, msg, args, **kwargs)
   1232 
   1233     def findCaller(self):
   1234         """
   1235         Find the stack frame of the caller so that we can note the source
   1236         file name, line number and function name.
   1237         """
   1238         f = currentframe()
   1239         #On some versions of IronPython, currentframe() returns None if
   1240         #IronPython isn't run with -X:Frames.
   1241         if f is not None:
   1242             f = f.f_back
   1243         rv = "(unknown file)", 0, "(unknown function)"
   1244         while hasattr(f, "f_code"):
   1245             co = f.f_code
   1246             filename = os.path.normcase(co.co_filename)
   1247             if filename == _srcfile:
   1248                 f = f.f_back
   1249                 continue
   1250             rv = (co.co_filename, f.f_lineno, co.co_name)
   1251             break
   1252         return rv
   1253 
   1254     def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
   1255         """
   1256         A factory method which can be overridden in subclasses to create
   1257         specialized LogRecords.
   1258         """
   1259         rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
   1260         if extra is not None:
   1261             for key in extra:
   1262                 if (key in ["message", "asctime"]) or (key in rv.__dict__):
   1263                     raise KeyError("Attempt to overwrite %r in LogRecord" % key)
   1264                 rv.__dict__[key] = extra[key]
   1265         return rv
   1266 
   1267     def _log(self, level, msg, args, exc_info=None, extra=None):
   1268         """
   1269         Low-level logging routine which creates a LogRecord and then calls
   1270         all the handlers of this logger to handle the record.
   1271         """
   1272         if _srcfile:
   1273             #IronPython doesn't track Python frames, so findCaller raises an
   1274             #exception on some versions of IronPython. We trap it here so that
   1275             #IronPython can use logging.
   1276             try:
   1277                 fn, lno, func = self.findCaller()
   1278             except ValueError:
   1279                 fn, lno, func = "(unknown file)", 0, "(unknown function)"
   1280         else:
   1281             fn, lno, func = "(unknown file)", 0, "(unknown function)"
   1282         if exc_info:
   1283             if not isinstance(exc_info, tuple):
   1284                 exc_info = sys.exc_info()
   1285         record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
   1286         self.handle(record)
   1287 
   1288     def handle(self, record):
   1289         """
   1290         Call the handlers for the specified record.
   1291 
   1292         This method is used for unpickled records received from a socket, as
   1293         well as those created locally. Logger-level filtering is applied.
   1294         """
   1295         if (not self.disabled) and self.filter(record):
   1296             self.callHandlers(record)
   1297 
   1298     def addHandler(self, hdlr):
   1299         """
   1300         Add the specified handler to this logger.
   1301         """
   1302         _acquireLock()
   1303         try:
   1304             if not (hdlr in self.handlers):
   1305                 self.handlers.append(hdlr)
   1306         finally:
   1307             _releaseLock()
   1308 
   1309     def removeHandler(self, hdlr):
   1310         """
   1311         Remove the specified handler from this logger.
   1312         """
   1313         _acquireLock()
   1314         try:
   1315             if hdlr in self.handlers:
   1316                 self.handlers.remove(hdlr)
   1317         finally:
   1318             _releaseLock()
   1319 
   1320     def callHandlers(self, record):
   1321         """
   1322         Pass a record to all relevant handlers.
   1323 
   1324         Loop through all handlers for this logger and its parents in the
   1325         logger hierarchy. If no handler was found, output a one-off error
   1326         message to sys.stderr. Stop searching up the hierarchy whenever a
   1327         logger with the "propagate" attribute set to zero is found - that
   1328         will be the last logger whose handlers are called.
   1329         """
   1330         c = self
   1331         found = 0
   1332         while c:
   1333             for hdlr in c.handlers:
   1334                 found = found + 1
   1335                 if record.levelno >= hdlr.level:
   1336                     hdlr.handle(record)
   1337             if not c.propagate:
   1338                 c = None    #break out
   1339             else:
   1340                 c = c.parent
   1341         if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
   1342             sys.stderr.write("No handlers could be found for logger"
   1343                              " \"%s\"\n" % self.name)
   1344             self.manager.emittedNoHandlerWarning = 1
   1345 
   1346     def getEffectiveLevel(self):
   1347         """
   1348         Get the effective level for this logger.
   1349 
   1350         Loop through this logger and its parents in the logger hierarchy,
   1351         looking for a non-zero logging level. Return the first one found.
   1352         """
   1353         logger = self
   1354         while logger:
   1355             if logger.level:
   1356                 return logger.level
   1357             logger = logger.parent
   1358         return NOTSET
   1359 
   1360     def isEnabledFor(self, level):
   1361         """
   1362         Is this logger enabled for level 'level'?
   1363         """
   1364         if self.manager.disable >= level:
   1365             return 0
   1366         return level >= self.getEffectiveLevel()
   1367 
   1368     def getChild(self, suffix):
   1369         """
   1370         Get a logger which is a descendant to this one.
   1371 
   1372         This is a convenience method, such that
   1373 
   1374         logging.getLogger('abc').getChild('def.ghi')
   1375 
   1376         is the same as
   1377 
   1378         logging.getLogger('abc.def.ghi')
   1379 
   1380         It's useful, for example, when the parent logger is named using
   1381         __name__ rather than a literal string.
   1382         """
   1383         if self.root is not self:
   1384             suffix = '.'.join((self.name, suffix))
   1385         return self.manager.getLogger(suffix)
   1386 
   1387 class RootLogger(Logger):
   1388     """
   1389     A root logger is not that different to any other logger, except that
   1390     it must have a logging level and there is only one instance of it in
   1391     the hierarchy.
   1392     """
   1393     def __init__(self, level):
   1394         """
   1395         Initialize the logger with the name "root".
   1396         """
   1397         Logger.__init__(self, "root", level)
   1398 
   1399 _loggerClass = Logger
   1400 
   1401 class LoggerAdapter(object):
   1402     """
   1403     An adapter for loggers which makes it easier to specify contextual
   1404     information in logging output.
   1405     """
   1406 
   1407     def __init__(self, logger, extra):
   1408         """
   1409         Initialize the adapter with a logger and a dict-like object which
   1410         provides contextual information. This constructor signature allows
   1411         easy stacking of LoggerAdapters, if so desired.
   1412 
   1413         You can effectively pass keyword arguments as shown in the
   1414         following example:
   1415 
   1416         adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
   1417         """
   1418         self.logger = logger
   1419         self.extra = extra
   1420 
   1421     def process(self, msg, kwargs):
   1422         """
   1423         Process the logging message and keyword arguments passed in to
   1424         a logging call to insert contextual information. You can either
   1425         manipulate the message itself, the keyword args or both. Return
   1426         the message and kwargs modified (or not) to suit your needs.
   1427 
   1428         Normally, you'll only need to override this one method in a
   1429         LoggerAdapter subclass for your specific needs.
   1430         """
   1431         kwargs["extra"] = self.extra
   1432         return msg, kwargs
   1433 
   1434     def debug(self, msg, *args, **kwargs):
   1435         """
   1436         Delegate a debug call to the underlying logger, after adding
   1437         contextual information from this adapter instance.
   1438         """
   1439         msg, kwargs = self.process(msg, kwargs)
   1440         self.logger.debug(msg, *args, **kwargs)
   1441 
   1442     def info(self, msg, *args, **kwargs):
   1443         """
   1444         Delegate an info call to the underlying logger, after adding
   1445         contextual information from this adapter instance.
   1446         """
   1447         msg, kwargs = self.process(msg, kwargs)
   1448         self.logger.info(msg, *args, **kwargs)
   1449 
   1450     def warning(self, msg, *args, **kwargs):
   1451         """
   1452         Delegate a warning call to the underlying logger, after adding
   1453         contextual information from this adapter instance.
   1454         """
   1455         msg, kwargs = self.process(msg, kwargs)
   1456         self.logger.warning(msg, *args, **kwargs)
   1457 
   1458     def error(self, msg, *args, **kwargs):
   1459         """
   1460         Delegate an error call to the underlying logger, after adding
   1461         contextual information from this adapter instance.
   1462         """
   1463         msg, kwargs = self.process(msg, kwargs)
   1464         self.logger.error(msg, *args, **kwargs)
   1465 
   1466     def exception(self, msg, *args, **kwargs):
   1467         """
   1468         Delegate an exception call to the underlying logger, after adding
   1469         contextual information from this adapter instance.
   1470         """
   1471         msg, kwargs = self.process(msg, kwargs)
   1472         kwargs["exc_info"] = 1
   1473         self.logger.error(msg, *args, **kwargs)
   1474 
   1475     def critical(self, msg, *args, **kwargs):
   1476         """
   1477         Delegate a critical call to the underlying logger, after adding
   1478         contextual information from this adapter instance.
   1479         """
   1480         msg, kwargs = self.process(msg, kwargs)
   1481         self.logger.critical(msg, *args, **kwargs)
   1482 
   1483     def log(self, level, msg, *args, **kwargs):
   1484         """
   1485         Delegate a log call to the underlying logger, after adding
   1486         contextual information from this adapter instance.
   1487         """
   1488         msg, kwargs = self.process(msg, kwargs)
   1489         self.logger.log(level, msg, *args, **kwargs)
   1490 
   1491     def isEnabledFor(self, level):
   1492         """
   1493         See if the underlying logger is enabled for the specified level.
   1494         """
   1495         return self.logger.isEnabledFor(level)
   1496 
   1497 root = RootLogger(WARNING)
   1498 Logger.root = root
   1499 Logger.manager = Manager(Logger.root)
   1500 
   1501 #---------------------------------------------------------------------------
   1502 # Configuration classes and functions
   1503 #---------------------------------------------------------------------------
   1504 
   1505 BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
   1506 
   1507 def basicConfig(**kwargs):
   1508     """
   1509     Do basic configuration for the logging system.
   1510 
   1511     This function does nothing if the root logger already has handlers
   1512     configured. It is a convenience method intended for use by simple scripts
   1513     to do one-shot configuration of the logging package.
   1514 
   1515     The default behaviour is to create a StreamHandler which writes to
   1516     sys.stderr, set a formatter using the BASIC_FORMAT format string, and
   1517     add the handler to the root logger.
   1518 
   1519     A number of optional keyword arguments may be specified, which can alter
   1520     the default behaviour.
   1521 
   1522     filename  Specifies that a FileHandler be created, using the specified
   1523               filename, rather than a StreamHandler.
   1524     filemode  Specifies the mode to open the file, if filename is specified
   1525               (if filemode is unspecified, it defaults to 'a').
   1526     format    Use the specified format string for the handler.
   1527     datefmt   Use the specified date/time format.
   1528     level     Set the root logger level to the specified level.
   1529     stream    Use the specified stream to initialize the StreamHandler. Note
   1530               that this argument is incompatible with 'filename' - if both
   1531               are present, 'stream' is ignored.
   1532 
   1533     Note that you could specify a stream created using open(filename, mode)
   1534     rather than passing the filename and mode in. However, it should be
   1535     remembered that StreamHandler does not close its stream (since it may be
   1536     using sys.stdout or sys.stderr), whereas FileHandler closes its stream
   1537     when the handler is closed.
   1538     """
   1539     # Add thread safety in case someone mistakenly calls
   1540     # basicConfig() from multiple threads
   1541     _acquireLock()
   1542     try:
   1543         if len(root.handlers) == 0:
   1544             filename = kwargs.get("filename")
   1545             if filename:
   1546                 mode = kwargs.get("filemode", 'a')
   1547                 hdlr = FileHandler(filename, mode)
   1548             else:
   1549                 stream = kwargs.get("stream")
   1550                 hdlr = StreamHandler(stream)
   1551             fs = kwargs.get("format", BASIC_FORMAT)
   1552             dfs = kwargs.get("datefmt", None)
   1553             fmt = Formatter(fs, dfs)
   1554             hdlr.setFormatter(fmt)
   1555             root.addHandler(hdlr)
   1556             level = kwargs.get("level")
   1557             if level is not None:
   1558                 root.setLevel(level)
   1559     finally:
   1560         _releaseLock()
   1561 
   1562 #---------------------------------------------------------------------------
   1563 # Utility functions at module level.
   1564 # Basically delegate everything to the root logger.
   1565 #---------------------------------------------------------------------------
   1566 
   1567 def getLogger(name=None):
   1568     """
   1569     Return a logger with the specified name, creating it if necessary.
   1570 
   1571     If no name is specified, return the root logger.
   1572     """
   1573     if name:
   1574         return Logger.manager.getLogger(name)
   1575     else:
   1576         return root
   1577 
   1578 #def getRootLogger():
   1579 #    """
   1580 #    Return the root logger.
   1581 #
   1582 #    Note that getLogger('') now does the same thing, so this function is
   1583 #    deprecated and may disappear in the future.
   1584 #    """
   1585 #    return root
   1586 
   1587 def critical(msg, *args, **kwargs):
   1588     """
   1589     Log a message with severity 'CRITICAL' on the root logger.
   1590     """
   1591     if len(root.handlers) == 0:
   1592         basicConfig()
   1593     root.critical(msg, *args, **kwargs)
   1594 
   1595 fatal = critical
   1596 
   1597 def error(msg, *args, **kwargs):
   1598     """
   1599     Log a message with severity 'ERROR' on the root logger.
   1600     """
   1601     if len(root.handlers) == 0:
   1602         basicConfig()
   1603     root.error(msg, *args, **kwargs)
   1604 
   1605 def exception(msg, *args, **kwargs):
   1606     """
   1607     Log a message with severity 'ERROR' on the root logger,
   1608     with exception information.
   1609     """
   1610     kwargs['exc_info'] = 1
   1611     error(msg, *args, **kwargs)
   1612 
   1613 def warning(msg, *args, **kwargs):
   1614     """
   1615     Log a message with severity 'WARNING' on the root logger.
   1616     """
   1617     if len(root.handlers) == 0:
   1618         basicConfig()
   1619     root.warning(msg, *args, **kwargs)
   1620 
   1621 warn = warning
   1622 
   1623 def info(msg, *args, **kwargs):
   1624     """
   1625     Log a message with severity 'INFO' on the root logger.
   1626     """
   1627     if len(root.handlers) == 0:
   1628         basicConfig()
   1629     root.info(msg, *args, **kwargs)
   1630 
   1631 def debug(msg, *args, **kwargs):
   1632     """
   1633     Log a message with severity 'DEBUG' on the root logger.
   1634     """
   1635     if len(root.handlers) == 0:
   1636         basicConfig()
   1637     root.debug(msg, *args, **kwargs)
   1638 
   1639 def log(level, msg, *args, **kwargs):
   1640     """
   1641     Log 'msg % args' with the integer severity 'level' on the root logger.
   1642     """
   1643     if len(root.handlers) == 0:
   1644         basicConfig()
   1645     root.log(level, msg, *args, **kwargs)
   1646 
   1647 def disable(level):
   1648     """
   1649     Disable all logging calls of severity 'level' and below.
   1650     """
   1651     root.manager.disable = level
   1652 
   1653 def shutdown(handlerList=_handlerList):
   1654     """
   1655     Perform any cleanup actions in the logging system (e.g. flushing
   1656     buffers).
   1657 
   1658     Should be called at application exit.
   1659     """
   1660     for wr in reversed(handlerList[:]):
   1661         #errors might occur, for example, if files are locked
   1662         #we just ignore them if raiseExceptions is not set
   1663         try:
   1664             h = wr()
   1665             if h:
   1666                 try:
   1667                     h.acquire()
   1668                     h.flush()
   1669                     h.close()
   1670                 except (IOError, ValueError):
   1671                     # Ignore errors which might be caused
   1672                     # because handlers have been closed but
   1673                     # references to them are still around at
   1674                     # application exit.
   1675                     pass
   1676                 finally:
   1677                     h.release()
   1678         except:
   1679             if raiseExceptions:
   1680                 raise
   1681             #else, swallow
   1682 
   1683 #Let's try and shutdown automatically on application exit...
   1684 import atexit
   1685 atexit.register(shutdown)
   1686 
   1687 # Null handler
   1688 
   1689 class NullHandler(Handler):
   1690     """
   1691     This handler does nothing. It's intended to be used to avoid the
   1692     "No handlers could be found for logger XXX" one-off warning. This is
   1693     important for library code, which may contain code to log events. If a user
   1694     of the library does not configure logging, the one-off warning might be
   1695     produced; to avoid this, the library developer simply needs to instantiate
   1696     a NullHandler and add it to the top-level logger of the library module or
   1697     package.
   1698     """
   1699     def handle(self, record):
   1700         pass
   1701 
   1702     def emit(self, record):
   1703         pass
   1704 
   1705     def createLock(self):
   1706         self.lock = None
   1707 
   1708 # Warnings integration
   1709 
   1710 _warnings_showwarning = None
   1711 
   1712 def _showwarning(message, category, filename, lineno, file=None, line=None):
   1713     """
   1714     Implementation of showwarnings which redirects to logging, which will first
   1715     check to see if the file parameter is None. If a file is specified, it will
   1716     delegate to the original warnings implementation of showwarning. Otherwise,
   1717     it will call warnings.formatwarning and will log the resulting string to a
   1718     warnings logger named "py.warnings" with level logging.WARNING.
   1719     """
   1720     if file is not None:
   1721         if _warnings_showwarning is not None:
   1722             _warnings_showwarning(message, category, filename, lineno, file, line)
   1723     else:
   1724         s = warnings.formatwarning(message, category, filename, lineno, line)
   1725         logger = getLogger("py.warnings")
   1726         if not logger.handlers:
   1727             logger.addHandler(NullHandler())
   1728         logger.warning("%s", s)
   1729 
   1730 def captureWarnings(capture):
   1731     """
   1732     If capture is true, redirect all warnings to the logging package.
   1733     If capture is False, ensure that warnings are not redirected to logging
   1734     but to their original destinations.
   1735     """
   1736     global _warnings_showwarning
   1737     if capture:
   1738         if _warnings_showwarning is None:
   1739             _warnings_showwarning = warnings.showwarning
   1740             warnings.showwarning = _showwarning
   1741     else:
   1742         if _warnings_showwarning is not None:
   1743             warnings.showwarning = _warnings_showwarning
   1744             _warnings_showwarning = None
   1745