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"""
18Logging package for Python. Based on PEP 282 and comments thereto in
19comp.lang.python.
20
21Copyright (C) 2001-2014 Vinay Sajip. All Rights Reserved.
22
23To use, simply 'import logging' and log away!
24"""
25
26import 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
36try:
37    import codecs
38except ImportError:
39    codecs = None
40
41try:
42    import thread
43    import threading
44except ImportError:
45    thread = None
46
47__author__  = "Vinay Sajip <vinay_sajip@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#---------------------------------------------------------------------------
56try:
57    unicode
58    _unicode = True
59except NameError:
60    _unicode = False
61
62# next bit filched from 1.5.2's inspect.py
63def 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
70if 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#
95raiseExceptions = 1
96
97#
98# If you don't want threading information in the log, set this to zero
99#
100logThreads = 1
101
102#
103# If you don't want multiprocessing information in the log, set this to zero
104#
105logMultiprocessing = 1
106
107#
108# If you don't want process information in the log, set this to zero
109#
110logProcesses = 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
123CRITICAL = 50
124FATAL = CRITICAL
125ERROR = 40
126WARNING = 30
127WARN = WARNING
128INFO = 20
129DEBUG = 10
130NOTSET = 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
148def 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
164def 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
177def _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#
200if thread:
201    _lock = threading.RLock()
202else:
203    _lock = None
204
205def _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
214def _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
225class 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
332def 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
347class 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
503class 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
545class 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
582class 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
629def _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        try:
640            acquire()
641            try:
642                if wr in handlers:
643                    handlers.remove(wr)
644            finally:
645                release()
646        except TypeError:
647            # https://bugs.python.org/issue21149 - If the RLock object behind
648            # acquire() and release() has been partially finalized you may see
649            # an error about NoneType not being callable.  Absolutely nothing
650            # we can do in this GC during process shutdown situation.  Eat it.
651            pass
652
653def _addHandlerRef(handler):
654    """
655    Add a handler to the internal cleanup list using a weak reference.
656    """
657    _acquireLock()
658    try:
659        _handlerList.append(weakref.ref(handler, _removeHandlerRef))
660    finally:
661        _releaseLock()
662
663class Handler(Filterer):
664    """
665    Handler instances dispatch logging events to specific destinations.
666
667    The base handler class. Acts as a placeholder which defines the Handler
668    interface. Handlers can optionally use Formatter instances to format
669    records as desired. By default, no formatter is specified; in this case,
670    the 'raw' message as determined by record.message is logged.
671    """
672    def __init__(self, level=NOTSET):
673        """
674        Initializes the instance - basically setting the formatter to None
675        and the filter list to empty.
676        """
677        Filterer.__init__(self)
678        self._name = None
679        self.level = _checkLevel(level)
680        self.formatter = None
681        # Add the handler to the global _handlerList (for cleanup on shutdown)
682        _addHandlerRef(self)
683        self.createLock()
684
685    def get_name(self):
686        return self._name
687
688    def set_name(self, name):
689        _acquireLock()
690        try:
691            if self._name in _handlers:
692                del _handlers[self._name]
693            self._name = name
694            if name:
695                _handlers[name] = self
696        finally:
697            _releaseLock()
698
699    name = property(get_name, set_name)
700
701    def createLock(self):
702        """
703        Acquire a thread lock for serializing access to the underlying I/O.
704        """
705        if thread:
706            self.lock = threading.RLock()
707        else:
708            self.lock = None
709
710    def acquire(self):
711        """
712        Acquire the I/O thread lock.
713        """
714        if self.lock:
715            self.lock.acquire()
716
717    def release(self):
718        """
719        Release the I/O thread lock.
720        """
721        if self.lock:
722            self.lock.release()
723
724    def setLevel(self, level):
725        """
726        Set the logging level of this handler.
727        """
728        self.level = _checkLevel(level)
729
730    def format(self, record):
731        """
732        Format the specified record.
733
734        If a formatter is set, use it. Otherwise, use the default formatter
735        for the module.
736        """
737        if self.formatter:
738            fmt = self.formatter
739        else:
740            fmt = _defaultFormatter
741        return fmt.format(record)
742
743    def emit(self, record):
744        """
745        Do whatever it takes to actually log the specified logging record.
746
747        This version is intended to be implemented by subclasses and so
748        raises a NotImplementedError.
749        """
750        raise NotImplementedError('emit must be implemented '
751                                  'by Handler subclasses')
752
753    def handle(self, record):
754        """
755        Conditionally emit the specified logging record.
756
757        Emission depends on filters which may have been added to the handler.
758        Wrap the actual emission of the record with acquisition/release of
759        the I/O thread lock. Returns whether the filter passed the record for
760        emission.
761        """
762        rv = self.filter(record)
763        if rv:
764            self.acquire()
765            try:
766                self.emit(record)
767            finally:
768                self.release()
769        return rv
770
771    def setFormatter(self, fmt):
772        """
773        Set the formatter for this handler.
774        """
775        self.formatter = fmt
776
777    def flush(self):
778        """
779        Ensure all logging output has been flushed.
780
781        This version does nothing and is intended to be implemented by
782        subclasses.
783        """
784        pass
785
786    def close(self):
787        """
788        Tidy up any resources used by the handler.
789
790        This version removes the handler from an internal map of handlers,
791        _handlers, which is used for handler lookup by name. Subclasses
792        should ensure that this gets called from overridden close()
793        methods.
794        """
795        #get the module data lock, as we're updating a shared structure.
796        _acquireLock()
797        try:    #unlikely to raise an exception, but you never know...
798            if self._name and self._name in _handlers:
799                del _handlers[self._name]
800        finally:
801            _releaseLock()
802
803    def handleError(self, record):
804        """
805        Handle errors which occur during an emit() call.
806
807        This method should be called from handlers when an exception is
808        encountered during an emit() call. If raiseExceptions is false,
809        exceptions get silently ignored. This is what is mostly wanted
810        for a logging system - most users will not care about errors in
811        the logging system, they are more interested in application errors.
812        You could, however, replace this with a custom handler if you wish.
813        The record which was being processed is passed in to this method.
814        """
815        if raiseExceptions and sys.stderr:  # see issue 13807
816            ei = sys.exc_info()
817            try:
818                traceback.print_exception(ei[0], ei[1], ei[2],
819                                          None, sys.stderr)
820                sys.stderr.write('Logged from file %s, line %s\n' % (
821                                 record.filename, record.lineno))
822            except IOError:
823                pass    # see issue 5971
824            finally:
825                del ei
826
827class StreamHandler(Handler):
828    """
829    A handler class which writes logging records, appropriately formatted,
830    to a stream. Note that this class does not close the stream, as
831    sys.stdout or sys.stderr may be used.
832    """
833
834    def __init__(self, stream=None):
835        """
836        Initialize the handler.
837
838        If stream is not specified, sys.stderr is used.
839        """
840        Handler.__init__(self)
841        if stream is None:
842            stream = sys.stderr
843        self.stream = stream
844
845    def flush(self):
846        """
847        Flushes the stream.
848        """
849        self.acquire()
850        try:
851            if self.stream and hasattr(self.stream, "flush"):
852                self.stream.flush()
853        finally:
854            self.release()
855
856    def emit(self, record):
857        """
858        Emit a record.
859
860        If a formatter is specified, it is used to format the record.
861        The record is then written to the stream with a trailing newline.  If
862        exception information is present, it is formatted using
863        traceback.print_exception and appended to the stream.  If the stream
864        has an 'encoding' attribute, it is used to determine how to do the
865        output to the stream.
866        """
867        try:
868            msg = self.format(record)
869            stream = self.stream
870            fs = "%s\n"
871            if not _unicode: #if no unicode support...
872                stream.write(fs % msg)
873            else:
874                try:
875                    if (isinstance(msg, unicode) and
876                        getattr(stream, 'encoding', None)):
877                        ufs = u'%s\n'
878                        try:
879                            stream.write(ufs % msg)
880                        except UnicodeEncodeError:
881                            #Printing to terminals sometimes fails. For example,
882                            #with an encoding of 'cp1251', the above write will
883                            #work if written to a stream opened or wrapped by
884                            #the codecs module, but fail when writing to a
885                            #terminal even when the codepage is set to cp1251.
886                            #An extra encoding step seems to be needed.
887                            stream.write((ufs % msg).encode(stream.encoding))
888                    else:
889                        stream.write(fs % msg)
890                except UnicodeError:
891                    stream.write(fs % msg.encode("UTF-8"))
892            self.flush()
893        except (KeyboardInterrupt, SystemExit):
894            raise
895        except:
896            self.handleError(record)
897
898class FileHandler(StreamHandler):
899    """
900    A handler class which writes formatted logging records to disk files.
901    """
902    def __init__(self, filename, mode='a', encoding=None, delay=0):
903        """
904        Open the specified file and use it as the stream for logging.
905        """
906        #keep the absolute path, otherwise derived classes which use this
907        #may come a cropper when the current directory changes
908        if codecs is None:
909            encoding = None
910        self.baseFilename = os.path.abspath(filename)
911        self.mode = mode
912        self.encoding = encoding
913        self.delay = delay
914        if delay:
915            #We don't open the stream, but we still need to call the
916            #Handler constructor to set level, formatter, lock etc.
917            Handler.__init__(self)
918            self.stream = None
919        else:
920            StreamHandler.__init__(self, self._open())
921
922    def close(self):
923        """
924        Closes the stream.
925        """
926        self.acquire()
927        try:
928            try:
929                if self.stream:
930                    try:
931                        self.flush()
932                    finally:
933                        stream = self.stream
934                        self.stream = None
935                        if hasattr(stream, "close"):
936                            stream.close()
937            finally:
938                # Issue #19523: call unconditionally to
939                # prevent a handler leak when delay is set
940                StreamHandler.close(self)
941        finally:
942            self.release()
943
944    def _open(self):
945        """
946        Open the current base file with the (original) mode and encoding.
947        Return the resulting stream.
948        """
949        if self.encoding is None:
950            stream = open(self.baseFilename, self.mode)
951        else:
952            stream = codecs.open(self.baseFilename, self.mode, self.encoding)
953        return stream
954
955    def emit(self, record):
956        """
957        Emit a record.
958
959        If the stream was not opened because 'delay' was specified in the
960        constructor, open it before calling the superclass's emit.
961        """
962        if self.stream is None:
963            self.stream = self._open()
964        StreamHandler.emit(self, record)
965
966#---------------------------------------------------------------------------
967#   Manager classes and functions
968#---------------------------------------------------------------------------
969
970class PlaceHolder(object):
971    """
972    PlaceHolder instances are used in the Manager logger hierarchy to take
973    the place of nodes for which no loggers have been defined. This class is
974    intended for internal use only and not as part of the public API.
975    """
976    def __init__(self, alogger):
977        """
978        Initialize with the specified logger being a child of this placeholder.
979        """
980        #self.loggers = [alogger]
981        self.loggerMap = { alogger : None }
982
983    def append(self, alogger):
984        """
985        Add the specified logger as a child of this placeholder.
986        """
987        #if alogger not in self.loggers:
988        if alogger not in self.loggerMap:
989            #self.loggers.append(alogger)
990            self.loggerMap[alogger] = None
991
992#
993#   Determine which class to use when instantiating loggers.
994#
995_loggerClass = None
996
997def setLoggerClass(klass):
998    """
999    Set the class to be used when instantiating a logger. The class should
1000    define __init__() such that only a name argument is required, and the
1001    __init__() should call Logger.__init__()
1002    """
1003    if klass != Logger:
1004        if not issubclass(klass, Logger):
1005            raise TypeError("logger not derived from logging.Logger: "
1006                            + klass.__name__)
1007    global _loggerClass
1008    _loggerClass = klass
1009
1010def getLoggerClass():
1011    """
1012    Return the class to be used when instantiating a logger.
1013    """
1014
1015    return _loggerClass
1016
1017class Manager(object):
1018    """
1019    There is [under normal circumstances] just one Manager instance, which
1020    holds the hierarchy of loggers.
1021    """
1022    def __init__(self, rootnode):
1023        """
1024        Initialize the manager with the root node of the logger hierarchy.
1025        """
1026        self.root = rootnode
1027        self.disable = 0
1028        self.emittedNoHandlerWarning = 0
1029        self.loggerDict = {}
1030        self.loggerClass = None
1031
1032    def getLogger(self, name):
1033        """
1034        Get a logger with the specified name (channel name), creating it
1035        if it doesn't yet exist. This name is a dot-separated hierarchical
1036        name, such as "a", "a.b", "a.b.c" or similar.
1037
1038        If a PlaceHolder existed for the specified name [i.e. the logger
1039        didn't exist but a child of it did], replace it with the created
1040        logger and fix up the parent/child references which pointed to the
1041        placeholder to now point to the logger.
1042        """
1043        rv = None
1044        if not isinstance(name, basestring):
1045            raise TypeError('A logger name must be string or Unicode')
1046        if isinstance(name, unicode):
1047            name = name.encode('utf-8')
1048        _acquireLock()
1049        try:
1050            if name in self.loggerDict:
1051                rv = self.loggerDict[name]
1052                if isinstance(rv, PlaceHolder):
1053                    ph = rv
1054                    rv = (self.loggerClass or _loggerClass)(name)
1055                    rv.manager = self
1056                    self.loggerDict[name] = rv
1057                    self._fixupChildren(ph, rv)
1058                    self._fixupParents(rv)
1059            else:
1060                rv = (self.loggerClass or _loggerClass)(name)
1061                rv.manager = self
1062                self.loggerDict[name] = rv
1063                self._fixupParents(rv)
1064        finally:
1065            _releaseLock()
1066        return rv
1067
1068    def setLoggerClass(self, klass):
1069        """
1070        Set the class to be used when instantiating a logger with this Manager.
1071        """
1072        if klass != Logger:
1073            if not issubclass(klass, Logger):
1074                raise TypeError("logger not derived from logging.Logger: "
1075                                + klass.__name__)
1076        self.loggerClass = klass
1077
1078    def _fixupParents(self, alogger):
1079        """
1080        Ensure that there are either loggers or placeholders all the way
1081        from the specified logger to the root of the logger hierarchy.
1082        """
1083        name = alogger.name
1084        i = name.rfind(".")
1085        rv = None
1086        while (i > 0) and not rv:
1087            substr = name[:i]
1088            if substr not in self.loggerDict:
1089                self.loggerDict[substr] = PlaceHolder(alogger)
1090            else:
1091                obj = self.loggerDict[substr]
1092                if isinstance(obj, Logger):
1093                    rv = obj
1094                else:
1095                    assert isinstance(obj, PlaceHolder)
1096                    obj.append(alogger)
1097            i = name.rfind(".", 0, i - 1)
1098        if not rv:
1099            rv = self.root
1100        alogger.parent = rv
1101
1102    def _fixupChildren(self, ph, alogger):
1103        """
1104        Ensure that children of the placeholder ph are connected to the
1105        specified logger.
1106        """
1107        name = alogger.name
1108        namelen = len(name)
1109        for c in ph.loggerMap.keys():
1110            #The if means ... if not c.parent.name.startswith(nm)
1111            if c.parent.name[:namelen] != name:
1112                alogger.parent = c.parent
1113                c.parent = alogger
1114
1115#---------------------------------------------------------------------------
1116#   Logger classes and functions
1117#---------------------------------------------------------------------------
1118
1119class Logger(Filterer):
1120    """
1121    Instances of the Logger class represent a single logging channel. A
1122    "logging channel" indicates an area of an application. Exactly how an
1123    "area" is defined is up to the application developer. Since an
1124    application can have any number of areas, logging channels are identified
1125    by a unique string. Application areas can be nested (e.g. an area
1126    of "input processing" might include sub-areas "read CSV files", "read
1127    XLS files" and "read Gnumeric files"). To cater for this natural nesting,
1128    channel names are organized into a namespace hierarchy where levels are
1129    separated by periods, much like the Java or Python package namespace. So
1130    in the instance given above, channel names might be "input" for the upper
1131    level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
1132    There is no arbitrary limit to the depth of nesting.
1133    """
1134    def __init__(self, name, level=NOTSET):
1135        """
1136        Initialize the logger with a name and an optional level.
1137        """
1138        Filterer.__init__(self)
1139        self.name = name
1140        self.level = _checkLevel(level)
1141        self.parent = None
1142        self.propagate = 1
1143        self.handlers = []
1144        self.disabled = 0
1145
1146    def setLevel(self, level):
1147        """
1148        Set the logging level of this logger.
1149        """
1150        self.level = _checkLevel(level)
1151
1152    def debug(self, msg, *args, **kwargs):
1153        """
1154        Log 'msg % args' with severity 'DEBUG'.
1155
1156        To pass exception information, use the keyword argument exc_info with
1157        a true value, e.g.
1158
1159        logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
1160        """
1161        if self.isEnabledFor(DEBUG):
1162            self._log(DEBUG, msg, args, **kwargs)
1163
1164    def info(self, msg, *args, **kwargs):
1165        """
1166        Log 'msg % args' with severity 'INFO'.
1167
1168        To pass exception information, use the keyword argument exc_info with
1169        a true value, e.g.
1170
1171        logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
1172        """
1173        if self.isEnabledFor(INFO):
1174            self._log(INFO, msg, args, **kwargs)
1175
1176    def warning(self, msg, *args, **kwargs):
1177        """
1178        Log 'msg % args' with severity 'WARNING'.
1179
1180        To pass exception information, use the keyword argument exc_info with
1181        a true value, e.g.
1182
1183        logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
1184        """
1185        if self.isEnabledFor(WARNING):
1186            self._log(WARNING, msg, args, **kwargs)
1187
1188    warn = warning
1189
1190    def error(self, msg, *args, **kwargs):
1191        """
1192        Log 'msg % args' with severity 'ERROR'.
1193
1194        To pass exception information, use the keyword argument exc_info with
1195        a true value, e.g.
1196
1197        logger.error("Houston, we have a %s", "major problem", exc_info=1)
1198        """
1199        if self.isEnabledFor(ERROR):
1200            self._log(ERROR, msg, args, **kwargs)
1201
1202    def exception(self, msg, *args, **kwargs):
1203        """
1204        Convenience method for logging an ERROR with exception information.
1205        """
1206        kwargs['exc_info'] = 1
1207        self.error(msg, *args, **kwargs)
1208
1209    def critical(self, msg, *args, **kwargs):
1210        """
1211        Log 'msg % args' with severity 'CRITICAL'.
1212
1213        To pass exception information, use the keyword argument exc_info with
1214        a true value, e.g.
1215
1216        logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1217        """
1218        if self.isEnabledFor(CRITICAL):
1219            self._log(CRITICAL, msg, args, **kwargs)
1220
1221    fatal = critical
1222
1223    def log(self, level, msg, *args, **kwargs):
1224        """
1225        Log 'msg % args' with the integer severity 'level'.
1226
1227        To pass exception information, use the keyword argument exc_info with
1228        a true value, e.g.
1229
1230        logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1231        """
1232        if not isinstance(level, (int, long)):
1233            if raiseExceptions:
1234                raise TypeError("level must be an integer")
1235            else:
1236                return
1237        if self.isEnabledFor(level):
1238            self._log(level, msg, args, **kwargs)
1239
1240    def findCaller(self):
1241        """
1242        Find the stack frame of the caller so that we can note the source
1243        file name, line number and function name.
1244        """
1245        f = currentframe()
1246        #On some versions of IronPython, currentframe() returns None if
1247        #IronPython isn't run with -X:Frames.
1248        if f is not None:
1249            f = f.f_back
1250        rv = "(unknown file)", 0, "(unknown function)"
1251        while hasattr(f, "f_code"):
1252            co = f.f_code
1253            filename = os.path.normcase(co.co_filename)
1254            if filename == _srcfile:
1255                f = f.f_back
1256                continue
1257            rv = (co.co_filename, f.f_lineno, co.co_name)
1258            break
1259        return rv
1260
1261    def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
1262        """
1263        A factory method which can be overridden in subclasses to create
1264        specialized LogRecords.
1265        """
1266        rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
1267        if extra is not None:
1268            for key in extra:
1269                if (key in ["message", "asctime"]) or (key in rv.__dict__):
1270                    raise KeyError("Attempt to overwrite %r in LogRecord" % key)
1271                rv.__dict__[key] = extra[key]
1272        return rv
1273
1274    def _log(self, level, msg, args, exc_info=None, extra=None):
1275        """
1276        Low-level logging routine which creates a LogRecord and then calls
1277        all the handlers of this logger to handle the record.
1278        """
1279        if _srcfile:
1280            #IronPython doesn't track Python frames, so findCaller raises an
1281            #exception on some versions of IronPython. We trap it here so that
1282            #IronPython can use logging.
1283            try:
1284                fn, lno, func = self.findCaller()
1285            except ValueError:
1286                fn, lno, func = "(unknown file)", 0, "(unknown function)"
1287        else:
1288            fn, lno, func = "(unknown file)", 0, "(unknown function)"
1289        if exc_info:
1290            if not isinstance(exc_info, tuple):
1291                exc_info = sys.exc_info()
1292        record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
1293        self.handle(record)
1294
1295    def handle(self, record):
1296        """
1297        Call the handlers for the specified record.
1298
1299        This method is used for unpickled records received from a socket, as
1300        well as those created locally. Logger-level filtering is applied.
1301        """
1302        if (not self.disabled) and self.filter(record):
1303            self.callHandlers(record)
1304
1305    def addHandler(self, hdlr):
1306        """
1307        Add the specified handler to this logger.
1308        """
1309        _acquireLock()
1310        try:
1311            if not (hdlr in self.handlers):
1312                self.handlers.append(hdlr)
1313        finally:
1314            _releaseLock()
1315
1316    def removeHandler(self, hdlr):
1317        """
1318        Remove the specified handler from this logger.
1319        """
1320        _acquireLock()
1321        try:
1322            if hdlr in self.handlers:
1323                self.handlers.remove(hdlr)
1324        finally:
1325            _releaseLock()
1326
1327    def callHandlers(self, record):
1328        """
1329        Pass a record to all relevant handlers.
1330
1331        Loop through all handlers for this logger and its parents in the
1332        logger hierarchy. If no handler was found, output a one-off error
1333        message to sys.stderr. Stop searching up the hierarchy whenever a
1334        logger with the "propagate" attribute set to zero is found - that
1335        will be the last logger whose handlers are called.
1336        """
1337        c = self
1338        found = 0
1339        while c:
1340            for hdlr in c.handlers:
1341                found = found + 1
1342                if record.levelno >= hdlr.level:
1343                    hdlr.handle(record)
1344            if not c.propagate:
1345                c = None    #break out
1346            else:
1347                c = c.parent
1348        if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
1349            sys.stderr.write("No handlers could be found for logger"
1350                             " \"%s\"\n" % self.name)
1351            self.manager.emittedNoHandlerWarning = 1
1352
1353    def getEffectiveLevel(self):
1354        """
1355        Get the effective level for this logger.
1356
1357        Loop through this logger and its parents in the logger hierarchy,
1358        looking for a non-zero logging level. Return the first one found.
1359        """
1360        logger = self
1361        while logger:
1362            if logger.level:
1363                return logger.level
1364            logger = logger.parent
1365        return NOTSET
1366
1367    def isEnabledFor(self, level):
1368        """
1369        Is this logger enabled for level 'level'?
1370        """
1371        if self.manager.disable >= level:
1372            return 0
1373        return level >= self.getEffectiveLevel()
1374
1375    def getChild(self, suffix):
1376        """
1377        Get a logger which is a descendant to this one.
1378
1379        This is a convenience method, such that
1380
1381        logging.getLogger('abc').getChild('def.ghi')
1382
1383        is the same as
1384
1385        logging.getLogger('abc.def.ghi')
1386
1387        It's useful, for example, when the parent logger is named using
1388        __name__ rather than a literal string.
1389        """
1390        if self.root is not self:
1391            suffix = '.'.join((self.name, suffix))
1392        return self.manager.getLogger(suffix)
1393
1394class RootLogger(Logger):
1395    """
1396    A root logger is not that different to any other logger, except that
1397    it must have a logging level and there is only one instance of it in
1398    the hierarchy.
1399    """
1400    def __init__(self, level):
1401        """
1402        Initialize the logger with the name "root".
1403        """
1404        Logger.__init__(self, "root", level)
1405
1406_loggerClass = Logger
1407
1408class LoggerAdapter(object):
1409    """
1410    An adapter for loggers which makes it easier to specify contextual
1411    information in logging output.
1412    """
1413
1414    def __init__(self, logger, extra):
1415        """
1416        Initialize the adapter with a logger and a dict-like object which
1417        provides contextual information. This constructor signature allows
1418        easy stacking of LoggerAdapters, if so desired.
1419
1420        You can effectively pass keyword arguments as shown in the
1421        following example:
1422
1423        adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
1424        """
1425        self.logger = logger
1426        self.extra = extra
1427
1428    def process(self, msg, kwargs):
1429        """
1430        Process the logging message and keyword arguments passed in to
1431        a logging call to insert contextual information. You can either
1432        manipulate the message itself, the keyword args or both. Return
1433        the message and kwargs modified (or not) to suit your needs.
1434
1435        Normally, you'll only need to override this one method in a
1436        LoggerAdapter subclass for your specific needs.
1437        """
1438        kwargs["extra"] = self.extra
1439        return msg, kwargs
1440
1441    def debug(self, msg, *args, **kwargs):
1442        """
1443        Delegate a debug call to the underlying logger, after adding
1444        contextual information from this adapter instance.
1445        """
1446        msg, kwargs = self.process(msg, kwargs)
1447        self.logger.debug(msg, *args, **kwargs)
1448
1449    def info(self, msg, *args, **kwargs):
1450        """
1451        Delegate an info call to the underlying logger, after adding
1452        contextual information from this adapter instance.
1453        """
1454        msg, kwargs = self.process(msg, kwargs)
1455        self.logger.info(msg, *args, **kwargs)
1456
1457    def warning(self, msg, *args, **kwargs):
1458        """
1459        Delegate a warning 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.warning(msg, *args, **kwargs)
1464
1465    def error(self, msg, *args, **kwargs):
1466        """
1467        Delegate an error 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.error(msg, *args, **kwargs)
1472
1473    def exception(self, msg, *args, **kwargs):
1474        """
1475        Delegate an exception call to the underlying logger, after adding
1476        contextual information from this adapter instance.
1477        """
1478        msg, kwargs = self.process(msg, kwargs)
1479        kwargs["exc_info"] = 1
1480        self.logger.error(msg, *args, **kwargs)
1481
1482    def critical(self, msg, *args, **kwargs):
1483        """
1484        Delegate a critical call to the underlying logger, after adding
1485        contextual information from this adapter instance.
1486        """
1487        msg, kwargs = self.process(msg, kwargs)
1488        self.logger.critical(msg, *args, **kwargs)
1489
1490    def log(self, level, msg, *args, **kwargs):
1491        """
1492        Delegate a log call to the underlying logger, after adding
1493        contextual information from this adapter instance.
1494        """
1495        msg, kwargs = self.process(msg, kwargs)
1496        self.logger.log(level, msg, *args, **kwargs)
1497
1498    def isEnabledFor(self, level):
1499        """
1500        See if the underlying logger is enabled for the specified level.
1501        """
1502        return self.logger.isEnabledFor(level)
1503
1504root = RootLogger(WARNING)
1505Logger.root = root
1506Logger.manager = Manager(Logger.root)
1507
1508#---------------------------------------------------------------------------
1509# Configuration classes and functions
1510#---------------------------------------------------------------------------
1511
1512BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
1513
1514def basicConfig(**kwargs):
1515    """
1516    Do basic configuration for the logging system.
1517
1518    This function does nothing if the root logger already has handlers
1519    configured. It is a convenience method intended for use by simple scripts
1520    to do one-shot configuration of the logging package.
1521
1522    The default behaviour is to create a StreamHandler which writes to
1523    sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1524    add the handler to the root logger.
1525
1526    A number of optional keyword arguments may be specified, which can alter
1527    the default behaviour.
1528
1529    filename  Specifies that a FileHandler be created, using the specified
1530              filename, rather than a StreamHandler.
1531    filemode  Specifies the mode to open the file, if filename is specified
1532              (if filemode is unspecified, it defaults to 'a').
1533    format    Use the specified format string for the handler.
1534    datefmt   Use the specified date/time format.
1535    level     Set the root logger level to the specified level.
1536    stream    Use the specified stream to initialize the StreamHandler. Note
1537              that this argument is incompatible with 'filename' - if both
1538              are present, 'stream' is ignored.
1539
1540    Note that you could specify a stream created using open(filename, mode)
1541    rather than passing the filename and mode in. However, it should be
1542    remembered that StreamHandler does not close its stream (since it may be
1543    using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1544    when the handler is closed.
1545    """
1546    # Add thread safety in case someone mistakenly calls
1547    # basicConfig() from multiple threads
1548    _acquireLock()
1549    try:
1550        if len(root.handlers) == 0:
1551            filename = kwargs.get("filename")
1552            if filename:
1553                mode = kwargs.get("filemode", 'a')
1554                hdlr = FileHandler(filename, mode)
1555            else:
1556                stream = kwargs.get("stream")
1557                hdlr = StreamHandler(stream)
1558            fs = kwargs.get("format", BASIC_FORMAT)
1559            dfs = kwargs.get("datefmt", None)
1560            fmt = Formatter(fs, dfs)
1561            hdlr.setFormatter(fmt)
1562            root.addHandler(hdlr)
1563            level = kwargs.get("level")
1564            if level is not None:
1565                root.setLevel(level)
1566    finally:
1567        _releaseLock()
1568
1569#---------------------------------------------------------------------------
1570# Utility functions at module level.
1571# Basically delegate everything to the root logger.
1572#---------------------------------------------------------------------------
1573
1574def getLogger(name=None):
1575    """
1576    Return a logger with the specified name, creating it if necessary.
1577
1578    If no name is specified, return the root logger.
1579    """
1580    if name:
1581        return Logger.manager.getLogger(name)
1582    else:
1583        return root
1584
1585#def getRootLogger():
1586#    """
1587#    Return the root logger.
1588#
1589#    Note that getLogger('') now does the same thing, so this function is
1590#    deprecated and may disappear in the future.
1591#    """
1592#    return root
1593
1594def critical(msg, *args, **kwargs):
1595    """
1596    Log a message with severity 'CRITICAL' on the root logger.
1597    """
1598    if len(root.handlers) == 0:
1599        basicConfig()
1600    root.critical(msg, *args, **kwargs)
1601
1602fatal = critical
1603
1604def error(msg, *args, **kwargs):
1605    """
1606    Log a message with severity 'ERROR' on the root logger.
1607    """
1608    if len(root.handlers) == 0:
1609        basicConfig()
1610    root.error(msg, *args, **kwargs)
1611
1612def exception(msg, *args, **kwargs):
1613    """
1614    Log a message with severity 'ERROR' on the root logger,
1615    with exception information.
1616    """
1617    kwargs['exc_info'] = 1
1618    error(msg, *args, **kwargs)
1619
1620def warning(msg, *args, **kwargs):
1621    """
1622    Log a message with severity 'WARNING' on the root logger.
1623    """
1624    if len(root.handlers) == 0:
1625        basicConfig()
1626    root.warning(msg, *args, **kwargs)
1627
1628warn = warning
1629
1630def info(msg, *args, **kwargs):
1631    """
1632    Log a message with severity 'INFO' on the root logger.
1633    """
1634    if len(root.handlers) == 0:
1635        basicConfig()
1636    root.info(msg, *args, **kwargs)
1637
1638def debug(msg, *args, **kwargs):
1639    """
1640    Log a message with severity 'DEBUG' on the root logger.
1641    """
1642    if len(root.handlers) == 0:
1643        basicConfig()
1644    root.debug(msg, *args, **kwargs)
1645
1646def log(level, msg, *args, **kwargs):
1647    """
1648    Log 'msg % args' with the integer severity 'level' on the root logger.
1649    """
1650    if len(root.handlers) == 0:
1651        basicConfig()
1652    root.log(level, msg, *args, **kwargs)
1653
1654def disable(level):
1655    """
1656    Disable all logging calls of severity 'level' and below.
1657    """
1658    root.manager.disable = level
1659
1660def shutdown(handlerList=_handlerList):
1661    """
1662    Perform any cleanup actions in the logging system (e.g. flushing
1663    buffers).
1664
1665    Should be called at application exit.
1666    """
1667    for wr in reversed(handlerList[:]):
1668        #errors might occur, for example, if files are locked
1669        #we just ignore them if raiseExceptions is not set
1670        try:
1671            h = wr()
1672            if h:
1673                try:
1674                    h.acquire()
1675                    h.flush()
1676                    h.close()
1677                except (IOError, ValueError):
1678                    # Ignore errors which might be caused
1679                    # because handlers have been closed but
1680                    # references to them are still around at
1681                    # application exit.
1682                    pass
1683                finally:
1684                    h.release()
1685        except:
1686            if raiseExceptions:
1687                raise
1688            #else, swallow
1689
1690#Let's try and shutdown automatically on application exit...
1691import atexit
1692atexit.register(shutdown)
1693
1694# Null handler
1695
1696class NullHandler(Handler):
1697    """
1698    This handler does nothing. It's intended to be used to avoid the
1699    "No handlers could be found for logger XXX" one-off warning. This is
1700    important for library code, which may contain code to log events. If a user
1701    of the library does not configure logging, the one-off warning might be
1702    produced; to avoid this, the library developer simply needs to instantiate
1703    a NullHandler and add it to the top-level logger of the library module or
1704    package.
1705    """
1706    def handle(self, record):
1707        pass
1708
1709    def emit(self, record):
1710        pass
1711
1712    def createLock(self):
1713        self.lock = None
1714
1715# Warnings integration
1716
1717_warnings_showwarning = None
1718
1719def _showwarning(message, category, filename, lineno, file=None, line=None):
1720    """
1721    Implementation of showwarnings which redirects to logging, which will first
1722    check to see if the file parameter is None. If a file is specified, it will
1723    delegate to the original warnings implementation of showwarning. Otherwise,
1724    it will call warnings.formatwarning and will log the resulting string to a
1725    warnings logger named "py.warnings" with level logging.WARNING.
1726    """
1727    if file is not None:
1728        if _warnings_showwarning is not None:
1729            _warnings_showwarning(message, category, filename, lineno, file, line)
1730    else:
1731        s = warnings.formatwarning(message, category, filename, lineno, line)
1732        logger = getLogger("py.warnings")
1733        if not logger.handlers:
1734            logger.addHandler(NullHandler())
1735        logger.warning("%s", s)
1736
1737def captureWarnings(capture):
1738    """
1739    If capture is true, redirect all warnings to the logging package.
1740    If capture is False, ensure that warnings are not redirected to logging
1741    but to their original destinations.
1742    """
1743    global _warnings_showwarning
1744    if capture:
1745        if _warnings_showwarning is None:
1746            _warnings_showwarning = warnings.showwarning
1747            warnings.showwarning = _showwarning
1748    else:
1749        if _warnings_showwarning is not None:
1750            warnings.showwarning = _warnings_showwarning
1751            _warnings_showwarning = None
1752