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