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