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