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