• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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    @property
1273    def disable(self):
1274        return self._disable
1275
1276    @disable.setter
1277    def disable(self, value):
1278        self._disable = _checkLevel(value)
1279
1280    def getLogger(self, name):
1281        """
1282        Get a logger with the specified name (channel name), creating it
1283        if it doesn't yet exist. This name is a dot-separated hierarchical
1284        name, such as "a", "a.b", "a.b.c" or similar.
1285
1286        If a PlaceHolder existed for the specified name [i.e. the logger
1287        didn't exist but a child of it did], replace it with the created
1288        logger and fix up the parent/child references which pointed to the
1289        placeholder to now point to the logger.
1290        """
1291        rv = None
1292        if not isinstance(name, str):
1293            raise TypeError('A logger name must be a string')
1294        _acquireLock()
1295        try:
1296            if name in self.loggerDict:
1297                rv = self.loggerDict[name]
1298                if isinstance(rv, PlaceHolder):
1299                    ph = rv
1300                    rv = (self.loggerClass or _loggerClass)(name)
1301                    rv.manager = self
1302                    self.loggerDict[name] = rv
1303                    self._fixupChildren(ph, rv)
1304                    self._fixupParents(rv)
1305            else:
1306                rv = (self.loggerClass or _loggerClass)(name)
1307                rv.manager = self
1308                self.loggerDict[name] = rv
1309                self._fixupParents(rv)
1310        finally:
1311            _releaseLock()
1312        return rv
1313
1314    def setLoggerClass(self, klass):
1315        """
1316        Set the class to be used when instantiating a logger with this Manager.
1317        """
1318        if klass != Logger:
1319            if not issubclass(klass, Logger):
1320                raise TypeError("logger not derived from logging.Logger: "
1321                                + klass.__name__)
1322        self.loggerClass = klass
1323
1324    def setLogRecordFactory(self, factory):
1325        """
1326        Set the factory to be used when instantiating a log record with this
1327        Manager.
1328        """
1329        self.logRecordFactory = factory
1330
1331    def _fixupParents(self, alogger):
1332        """
1333        Ensure that there are either loggers or placeholders all the way
1334        from the specified logger to the root of the logger hierarchy.
1335        """
1336        name = alogger.name
1337        i = name.rfind(".")
1338        rv = None
1339        while (i > 0) and not rv:
1340            substr = name[:i]
1341            if substr not in self.loggerDict:
1342                self.loggerDict[substr] = PlaceHolder(alogger)
1343            else:
1344                obj = self.loggerDict[substr]
1345                if isinstance(obj, Logger):
1346                    rv = obj
1347                else:
1348                    assert isinstance(obj, PlaceHolder)
1349                    obj.append(alogger)
1350            i = name.rfind(".", 0, i - 1)
1351        if not rv:
1352            rv = self.root
1353        alogger.parent = rv
1354
1355    def _fixupChildren(self, ph, alogger):
1356        """
1357        Ensure that children of the placeholder ph are connected to the
1358        specified logger.
1359        """
1360        name = alogger.name
1361        namelen = len(name)
1362        for c in ph.loggerMap.keys():
1363            #The if means ... if not c.parent.name.startswith(nm)
1364            if c.parent.name[:namelen] != name:
1365                alogger.parent = c.parent
1366                c.parent = alogger
1367
1368    def _clear_cache(self):
1369        """
1370        Clear the cache for all loggers in loggerDict
1371        Called when level changes are made
1372        """
1373
1374        _acquireLock()
1375        for logger in self.loggerDict.values():
1376            if isinstance(logger, Logger):
1377                logger._cache.clear()
1378        self.root._cache.clear()
1379        _releaseLock()
1380
1381#---------------------------------------------------------------------------
1382#   Logger classes and functions
1383#---------------------------------------------------------------------------
1384
1385class Logger(Filterer):
1386    """
1387    Instances of the Logger class represent a single logging channel. A
1388    "logging channel" indicates an area of an application. Exactly how an
1389    "area" is defined is up to the application developer. Since an
1390    application can have any number of areas, logging channels are identified
1391    by a unique string. Application areas can be nested (e.g. an area
1392    of "input processing" might include sub-areas "read CSV files", "read
1393    XLS files" and "read Gnumeric files"). To cater for this natural nesting,
1394    channel names are organized into a namespace hierarchy where levels are
1395    separated by periods, much like the Java or Python package namespace. So
1396    in the instance given above, channel names might be "input" for the upper
1397    level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
1398    There is no arbitrary limit to the depth of nesting.
1399    """
1400    def __init__(self, name, level=NOTSET):
1401        """
1402        Initialize the logger with a name and an optional level.
1403        """
1404        Filterer.__init__(self)
1405        self.name = name
1406        self.level = _checkLevel(level)
1407        self.parent = None
1408        self.propagate = True
1409        self.handlers = []
1410        self.disabled = False
1411        self._cache = {}
1412
1413    def setLevel(self, level):
1414        """
1415        Set the logging level of this logger.  level must be an int or a str.
1416        """
1417        self.level = _checkLevel(level)
1418        self.manager._clear_cache()
1419
1420    def debug(self, msg, *args, **kwargs):
1421        """
1422        Log 'msg % args' with severity 'DEBUG'.
1423
1424        To pass exception information, use the keyword argument exc_info with
1425        a true value, e.g.
1426
1427        logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
1428        """
1429        if self.isEnabledFor(DEBUG):
1430            self._log(DEBUG, msg, args, **kwargs)
1431
1432    def info(self, msg, *args, **kwargs):
1433        """
1434        Log 'msg % args' with severity 'INFO'.
1435
1436        To pass exception information, use the keyword argument exc_info with
1437        a true value, e.g.
1438
1439        logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
1440        """
1441        if self.isEnabledFor(INFO):
1442            self._log(INFO, msg, args, **kwargs)
1443
1444    def warning(self, msg, *args, **kwargs):
1445        """
1446        Log 'msg % args' with severity 'WARNING'.
1447
1448        To pass exception information, use the keyword argument exc_info with
1449        a true value, e.g.
1450
1451        logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
1452        """
1453        if self.isEnabledFor(WARNING):
1454            self._log(WARNING, msg, args, **kwargs)
1455
1456    def warn(self, msg, *args, **kwargs):
1457        warnings.warn("The 'warn' method is deprecated, "
1458            "use 'warning' instead", DeprecationWarning, 2)
1459        self.warning(msg, *args, **kwargs)
1460
1461    def error(self, msg, *args, **kwargs):
1462        """
1463        Log 'msg % args' with severity 'ERROR'.
1464
1465        To pass exception information, use the keyword argument exc_info with
1466        a true value, e.g.
1467
1468        logger.error("Houston, we have a %s", "major problem", exc_info=1)
1469        """
1470        if self.isEnabledFor(ERROR):
1471            self._log(ERROR, msg, args, **kwargs)
1472
1473    def exception(self, msg, *args, exc_info=True, **kwargs):
1474        """
1475        Convenience method for logging an ERROR with exception information.
1476        """
1477        self.error(msg, *args, exc_info=exc_info, **kwargs)
1478
1479    def critical(self, msg, *args, **kwargs):
1480        """
1481        Log 'msg % args' with severity 'CRITICAL'.
1482
1483        To pass exception information, use the keyword argument exc_info with
1484        a true value, e.g.
1485
1486        logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1487        """
1488        if self.isEnabledFor(CRITICAL):
1489            self._log(CRITICAL, msg, args, **kwargs)
1490
1491    fatal = critical
1492
1493    def log(self, level, msg, *args, **kwargs):
1494        """
1495        Log 'msg % args' with the integer severity 'level'.
1496
1497        To pass exception information, use the keyword argument exc_info with
1498        a true value, e.g.
1499
1500        logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1501        """
1502        if not isinstance(level, int):
1503            if raiseExceptions:
1504                raise TypeError("level must be an integer")
1505            else:
1506                return
1507        if self.isEnabledFor(level):
1508            self._log(level, msg, args, **kwargs)
1509
1510    def findCaller(self, stack_info=False, stacklevel=1):
1511        """
1512        Find the stack frame of the caller so that we can note the source
1513        file name, line number and function name.
1514        """
1515        f = currentframe()
1516        #On some versions of IronPython, currentframe() returns None if
1517        #IronPython isn't run with -X:Frames.
1518        if f is not None:
1519            f = f.f_back
1520        orig_f = f
1521        while f and stacklevel > 1:
1522            f = f.f_back
1523            stacklevel -= 1
1524        if not f:
1525            f = orig_f
1526        rv = "(unknown file)", 0, "(unknown function)", None
1527        while hasattr(f, "f_code"):
1528            co = f.f_code
1529            filename = os.path.normcase(co.co_filename)
1530            if filename == _srcfile:
1531                f = f.f_back
1532                continue
1533            sinfo = None
1534            if stack_info:
1535                sio = io.StringIO()
1536                sio.write('Stack (most recent call last):\n')
1537                traceback.print_stack(f, file=sio)
1538                sinfo = sio.getvalue()
1539                if sinfo[-1] == '\n':
1540                    sinfo = sinfo[:-1]
1541                sio.close()
1542            rv = (co.co_filename, f.f_lineno, co.co_name, sinfo)
1543            break
1544        return rv
1545
1546    def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
1547                   func=None, extra=None, sinfo=None):
1548        """
1549        A factory method which can be overridden in subclasses to create
1550        specialized LogRecords.
1551        """
1552        rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func,
1553                             sinfo)
1554        if extra is not None:
1555            for key in extra:
1556                if (key in ["message", "asctime"]) or (key in rv.__dict__):
1557                    raise KeyError("Attempt to overwrite %r in LogRecord" % key)
1558                rv.__dict__[key] = extra[key]
1559        return rv
1560
1561    def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False,
1562             stacklevel=1):
1563        """
1564        Low-level logging routine which creates a LogRecord and then calls
1565        all the handlers of this logger to handle the record.
1566        """
1567        sinfo = None
1568        if _srcfile:
1569            #IronPython doesn't track Python frames, so findCaller raises an
1570            #exception on some versions of IronPython. We trap it here so that
1571            #IronPython can use logging.
1572            try:
1573                fn, lno, func, sinfo = self.findCaller(stack_info, stacklevel)
1574            except ValueError: # pragma: no cover
1575                fn, lno, func = "(unknown file)", 0, "(unknown function)"
1576        else: # pragma: no cover
1577            fn, lno, func = "(unknown file)", 0, "(unknown function)"
1578        if exc_info:
1579            if isinstance(exc_info, BaseException):
1580                exc_info = (type(exc_info), exc_info, exc_info.__traceback__)
1581            elif not isinstance(exc_info, tuple):
1582                exc_info = sys.exc_info()
1583        record = self.makeRecord(self.name, level, fn, lno, msg, args,
1584                                 exc_info, func, extra, sinfo)
1585        self.handle(record)
1586
1587    def handle(self, record):
1588        """
1589        Call the handlers for the specified record.
1590
1591        This method is used for unpickled records received from a socket, as
1592        well as those created locally. Logger-level filtering is applied.
1593        """
1594        if (not self.disabled) and self.filter(record):
1595            self.callHandlers(record)
1596
1597    def addHandler(self, hdlr):
1598        """
1599        Add the specified handler to this logger.
1600        """
1601        _acquireLock()
1602        try:
1603            if not (hdlr in self.handlers):
1604                self.handlers.append(hdlr)
1605        finally:
1606            _releaseLock()
1607
1608    def removeHandler(self, hdlr):
1609        """
1610        Remove the specified handler from this logger.
1611        """
1612        _acquireLock()
1613        try:
1614            if hdlr in self.handlers:
1615                self.handlers.remove(hdlr)
1616        finally:
1617            _releaseLock()
1618
1619    def hasHandlers(self):
1620        """
1621        See if this logger has any handlers configured.
1622
1623        Loop through all handlers for this logger and its parents in the
1624        logger hierarchy. Return True if a handler was found, else False.
1625        Stop searching up the hierarchy whenever a logger with the "propagate"
1626        attribute set to zero is found - that will be the last logger which
1627        is checked for the existence of handlers.
1628        """
1629        c = self
1630        rv = False
1631        while c:
1632            if c.handlers:
1633                rv = True
1634                break
1635            if not c.propagate:
1636                break
1637            else:
1638                c = c.parent
1639        return rv
1640
1641    def callHandlers(self, record):
1642        """
1643        Pass a record to all relevant handlers.
1644
1645        Loop through all handlers for this logger and its parents in the
1646        logger hierarchy. If no handler was found, output a one-off error
1647        message to sys.stderr. Stop searching up the hierarchy whenever a
1648        logger with the "propagate" attribute set to zero is found - that
1649        will be the last logger whose handlers are called.
1650        """
1651        c = self
1652        found = 0
1653        while c:
1654            for hdlr in c.handlers:
1655                found = found + 1
1656                if record.levelno >= hdlr.level:
1657                    hdlr.handle(record)
1658            if not c.propagate:
1659                c = None    #break out
1660            else:
1661                c = c.parent
1662        if (found == 0):
1663            if lastResort:
1664                if record.levelno >= lastResort.level:
1665                    lastResort.handle(record)
1666            elif raiseExceptions and not self.manager.emittedNoHandlerWarning:
1667                sys.stderr.write("No handlers could be found for logger"
1668                                 " \"%s\"\n" % self.name)
1669                self.manager.emittedNoHandlerWarning = True
1670
1671    def getEffectiveLevel(self):
1672        """
1673        Get the effective level for this logger.
1674
1675        Loop through this logger and its parents in the logger hierarchy,
1676        looking for a non-zero logging level. Return the first one found.
1677        """
1678        logger = self
1679        while logger:
1680            if logger.level:
1681                return logger.level
1682            logger = logger.parent
1683        return NOTSET
1684
1685    def isEnabledFor(self, level):
1686        """
1687        Is this logger enabled for level 'level'?
1688        """
1689        if self.disabled:
1690            return False
1691
1692        try:
1693            return self._cache[level]
1694        except KeyError:
1695            _acquireLock()
1696            try:
1697                if self.manager.disable >= level:
1698                    is_enabled = self._cache[level] = False
1699                else:
1700                    is_enabled = self._cache[level] = (
1701                        level >= self.getEffectiveLevel()
1702                    )
1703            finally:
1704                _releaseLock()
1705            return is_enabled
1706
1707    def getChild(self, suffix):
1708        """
1709        Get a logger which is a descendant to this one.
1710
1711        This is a convenience method, such that
1712
1713        logging.getLogger('abc').getChild('def.ghi')
1714
1715        is the same as
1716
1717        logging.getLogger('abc.def.ghi')
1718
1719        It's useful, for example, when the parent logger is named using
1720        __name__ rather than a literal string.
1721        """
1722        if self.root is not self:
1723            suffix = '.'.join((self.name, suffix))
1724        return self.manager.getLogger(suffix)
1725
1726    def __repr__(self):
1727        level = getLevelName(self.getEffectiveLevel())
1728        return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level)
1729
1730    def __reduce__(self):
1731        # In general, only the root logger will not be accessible via its name.
1732        # However, the root logger's class has its own __reduce__ method.
1733        if getLogger(self.name) is not self:
1734            import pickle
1735            raise pickle.PicklingError('logger cannot be pickled')
1736        return getLogger, (self.name,)
1737
1738
1739class RootLogger(Logger):
1740    """
1741    A root logger is not that different to any other logger, except that
1742    it must have a logging level and there is only one instance of it in
1743    the hierarchy.
1744    """
1745    def __init__(self, level):
1746        """
1747        Initialize the logger with the name "root".
1748        """
1749        Logger.__init__(self, "root", level)
1750
1751    def __reduce__(self):
1752        return getLogger, ()
1753
1754_loggerClass = Logger
1755
1756class LoggerAdapter(object):
1757    """
1758    An adapter for loggers which makes it easier to specify contextual
1759    information in logging output.
1760    """
1761
1762    def __init__(self, logger, extra):
1763        """
1764        Initialize the adapter with a logger and a dict-like object which
1765        provides contextual information. This constructor signature allows
1766        easy stacking of LoggerAdapters, if so desired.
1767
1768        You can effectively pass keyword arguments as shown in the
1769        following example:
1770
1771        adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
1772        """
1773        self.logger = logger
1774        self.extra = extra
1775
1776    def process(self, msg, kwargs):
1777        """
1778        Process the logging message and keyword arguments passed in to
1779        a logging call to insert contextual information. You can either
1780        manipulate the message itself, the keyword args or both. Return
1781        the message and kwargs modified (or not) to suit your needs.
1782
1783        Normally, you'll only need to override this one method in a
1784        LoggerAdapter subclass for your specific needs.
1785        """
1786        kwargs["extra"] = self.extra
1787        return msg, kwargs
1788
1789    #
1790    # Boilerplate convenience methods
1791    #
1792    def debug(self, msg, *args, **kwargs):
1793        """
1794        Delegate a debug call to the underlying logger.
1795        """
1796        self.log(DEBUG, msg, *args, **kwargs)
1797
1798    def info(self, msg, *args, **kwargs):
1799        """
1800        Delegate an info call to the underlying logger.
1801        """
1802        self.log(INFO, msg, *args, **kwargs)
1803
1804    def warning(self, msg, *args, **kwargs):
1805        """
1806        Delegate a warning call to the underlying logger.
1807        """
1808        self.log(WARNING, msg, *args, **kwargs)
1809
1810    def warn(self, msg, *args, **kwargs):
1811        warnings.warn("The 'warn' method is deprecated, "
1812            "use 'warning' instead", DeprecationWarning, 2)
1813        self.warning(msg, *args, **kwargs)
1814
1815    def error(self, msg, *args, **kwargs):
1816        """
1817        Delegate an error call to the underlying logger.
1818        """
1819        self.log(ERROR, msg, *args, **kwargs)
1820
1821    def exception(self, msg, *args, exc_info=True, **kwargs):
1822        """
1823        Delegate an exception call to the underlying logger.
1824        """
1825        self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs)
1826
1827    def critical(self, msg, *args, **kwargs):
1828        """
1829        Delegate a critical call to the underlying logger.
1830        """
1831        self.log(CRITICAL, msg, *args, **kwargs)
1832
1833    def log(self, level, msg, *args, **kwargs):
1834        """
1835        Delegate a log call to the underlying logger, after adding
1836        contextual information from this adapter instance.
1837        """
1838        if self.isEnabledFor(level):
1839            msg, kwargs = self.process(msg, kwargs)
1840            self.logger.log(level, msg, *args, **kwargs)
1841
1842    def isEnabledFor(self, level):
1843        """
1844        Is this logger enabled for level 'level'?
1845        """
1846        return self.logger.isEnabledFor(level)
1847
1848    def setLevel(self, level):
1849        """
1850        Set the specified level on the underlying logger.
1851        """
1852        self.logger.setLevel(level)
1853
1854    def getEffectiveLevel(self):
1855        """
1856        Get the effective level for the underlying logger.
1857        """
1858        return self.logger.getEffectiveLevel()
1859
1860    def hasHandlers(self):
1861        """
1862        See if the underlying logger has any handlers.
1863        """
1864        return self.logger.hasHandlers()
1865
1866    def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False):
1867        """
1868        Low-level log implementation, proxied to allow nested logger adapters.
1869        """
1870        return self.logger._log(
1871            level,
1872            msg,
1873            args,
1874            exc_info=exc_info,
1875            extra=extra,
1876            stack_info=stack_info,
1877        )
1878
1879    @property
1880    def manager(self):
1881        return self.logger.manager
1882
1883    @manager.setter
1884    def manager(self, value):
1885        self.logger.manager = value
1886
1887    @property
1888    def name(self):
1889        return self.logger.name
1890
1891    def __repr__(self):
1892        logger = self.logger
1893        level = getLevelName(logger.getEffectiveLevel())
1894        return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level)
1895
1896root = RootLogger(WARNING)
1897Logger.root = root
1898Logger.manager = Manager(Logger.root)
1899
1900#---------------------------------------------------------------------------
1901# Configuration classes and functions
1902#---------------------------------------------------------------------------
1903
1904def basicConfig(**kwargs):
1905    """
1906    Do basic configuration for the logging system.
1907
1908    This function does nothing if the root logger already has handlers
1909    configured, unless the keyword argument *force* is set to ``True``.
1910    It is a convenience method intended for use by simple scripts
1911    to do one-shot configuration of the logging package.
1912
1913    The default behaviour is to create a StreamHandler which writes to
1914    sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1915    add the handler to the root logger.
1916
1917    A number of optional keyword arguments may be specified, which can alter
1918    the default behaviour.
1919
1920    filename  Specifies that a FileHandler be created, using the specified
1921              filename, rather than a StreamHandler.
1922    filemode  Specifies the mode to open the file, if filename is specified
1923              (if filemode is unspecified, it defaults to 'a').
1924    format    Use the specified format string for the handler.
1925    datefmt   Use the specified date/time format.
1926    style     If a format string is specified, use this to specify the
1927              type of format string (possible values '%', '{', '$', for
1928              %-formatting, :meth:`str.format` and :class:`string.Template`
1929              - defaults to '%').
1930    level     Set the root logger level to the specified level.
1931    stream    Use the specified stream to initialize the StreamHandler. Note
1932              that this argument is incompatible with 'filename' - if both
1933              are present, 'stream' is ignored.
1934    handlers  If specified, this should be an iterable of already created
1935              handlers, which will be added to the root handler. Any handler
1936              in the list which does not have a formatter assigned will be
1937              assigned the formatter created in this function.
1938    force     If this keyword  is specified as true, any existing handlers
1939              attached to the root logger are removed and closed, before
1940              carrying out the configuration as specified by the other
1941              arguments.
1942    encoding  If specified together with a filename, this encoding is passed to
1943              the created FileHandler, causing it to be used when the file is
1944              opened.
1945    errors    If specified together with a filename, this value is passed to the
1946              created FileHandler, causing it to be used when the file is
1947              opened in text mode. If not specified, the default value is
1948              `backslashreplace`.
1949
1950    Note that you could specify a stream created using open(filename, mode)
1951    rather than passing the filename and mode in. However, it should be
1952    remembered that StreamHandler does not close its stream (since it may be
1953    using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1954    when the handler is closed.
1955
1956    .. versionchanged:: 3.2
1957       Added the ``style`` parameter.
1958
1959    .. versionchanged:: 3.3
1960       Added the ``handlers`` parameter. A ``ValueError`` is now thrown for
1961       incompatible arguments (e.g. ``handlers`` specified together with
1962       ``filename``/``filemode``, or ``filename``/``filemode`` specified
1963       together with ``stream``, or ``handlers`` specified together with
1964       ``stream``.
1965
1966    .. versionchanged:: 3.8
1967       Added the ``force`` parameter.
1968
1969    .. versionchanged:: 3.9
1970       Added the ``encoding`` and ``errors`` parameters.
1971    """
1972    # Add thread safety in case someone mistakenly calls
1973    # basicConfig() from multiple threads
1974    _acquireLock()
1975    try:
1976        force = kwargs.pop('force', False)
1977        encoding = kwargs.pop('encoding', None)
1978        errors = kwargs.pop('errors', 'backslashreplace')
1979        if force:
1980            for h in root.handlers[:]:
1981                root.removeHandler(h)
1982                h.close()
1983        if len(root.handlers) == 0:
1984            handlers = kwargs.pop("handlers", None)
1985            if handlers is None:
1986                if "stream" in kwargs and "filename" in kwargs:
1987                    raise ValueError("'stream' and 'filename' should not be "
1988                                     "specified together")
1989            else:
1990                if "stream" in kwargs or "filename" in kwargs:
1991                    raise ValueError("'stream' or 'filename' should not be "
1992                                     "specified together with 'handlers'")
1993            if handlers is None:
1994                filename = kwargs.pop("filename", None)
1995                mode = kwargs.pop("filemode", 'a')
1996                if filename:
1997                    if 'b'in mode:
1998                        errors = None
1999                    h = FileHandler(filename, mode,
2000                                    encoding=encoding, errors=errors)
2001                else:
2002                    stream = kwargs.pop("stream", None)
2003                    h = StreamHandler(stream)
2004                handlers = [h]
2005            dfs = kwargs.pop("datefmt", None)
2006            style = kwargs.pop("style", '%')
2007            if style not in _STYLES:
2008                raise ValueError('Style must be one of: %s' % ','.join(
2009                                 _STYLES.keys()))
2010            fs = kwargs.pop("format", _STYLES[style][1])
2011            fmt = Formatter(fs, dfs, style)
2012            for h in handlers:
2013                if h.formatter is None:
2014                    h.setFormatter(fmt)
2015                root.addHandler(h)
2016            level = kwargs.pop("level", None)
2017            if level is not None:
2018                root.setLevel(level)
2019            if kwargs:
2020                keys = ', '.join(kwargs.keys())
2021                raise ValueError('Unrecognised argument(s): %s' % keys)
2022    finally:
2023        _releaseLock()
2024
2025#---------------------------------------------------------------------------
2026# Utility functions at module level.
2027# Basically delegate everything to the root logger.
2028#---------------------------------------------------------------------------
2029
2030def getLogger(name=None):
2031    """
2032    Return a logger with the specified name, creating it if necessary.
2033
2034    If no name is specified, return the root logger.
2035    """
2036    if not name or isinstance(name, str) and name == root.name:
2037        return root
2038    return Logger.manager.getLogger(name)
2039
2040def critical(msg, *args, **kwargs):
2041    """
2042    Log a message with severity 'CRITICAL' on the root logger. If the logger
2043    has no handlers, call basicConfig() to add a console handler with a
2044    pre-defined format.
2045    """
2046    if len(root.handlers) == 0:
2047        basicConfig()
2048    root.critical(msg, *args, **kwargs)
2049
2050fatal = critical
2051
2052def error(msg, *args, **kwargs):
2053    """
2054    Log a message with severity 'ERROR' on the root logger. If the logger has
2055    no handlers, call basicConfig() to add a console handler with a pre-defined
2056    format.
2057    """
2058    if len(root.handlers) == 0:
2059        basicConfig()
2060    root.error(msg, *args, **kwargs)
2061
2062def exception(msg, *args, exc_info=True, **kwargs):
2063    """
2064    Log a message with severity 'ERROR' on the root logger, with exception
2065    information. If the logger has no handlers, basicConfig() is called to add
2066    a console handler with a pre-defined format.
2067    """
2068    error(msg, *args, exc_info=exc_info, **kwargs)
2069
2070def warning(msg, *args, **kwargs):
2071    """
2072    Log a message with severity 'WARNING' on the root logger. If the logger has
2073    no handlers, call basicConfig() to add a console handler with a pre-defined
2074    format.
2075    """
2076    if len(root.handlers) == 0:
2077        basicConfig()
2078    root.warning(msg, *args, **kwargs)
2079
2080def warn(msg, *args, **kwargs):
2081    warnings.warn("The 'warn' function is deprecated, "
2082        "use 'warning' instead", DeprecationWarning, 2)
2083    warning(msg, *args, **kwargs)
2084
2085def info(msg, *args, **kwargs):
2086    """
2087    Log a message with severity 'INFO' on the root logger. If the logger has
2088    no handlers, call basicConfig() to add a console handler with a pre-defined
2089    format.
2090    """
2091    if len(root.handlers) == 0:
2092        basicConfig()
2093    root.info(msg, *args, **kwargs)
2094
2095def debug(msg, *args, **kwargs):
2096    """
2097    Log a message with severity 'DEBUG' on the root logger. If the logger has
2098    no handlers, call basicConfig() to add a console handler with a pre-defined
2099    format.
2100    """
2101    if len(root.handlers) == 0:
2102        basicConfig()
2103    root.debug(msg, *args, **kwargs)
2104
2105def log(level, msg, *args, **kwargs):
2106    """
2107    Log 'msg % args' with the integer severity 'level' on the root logger. If
2108    the logger has no handlers, call basicConfig() to add a console handler
2109    with a pre-defined format.
2110    """
2111    if len(root.handlers) == 0:
2112        basicConfig()
2113    root.log(level, msg, *args, **kwargs)
2114
2115def disable(level=CRITICAL):
2116    """
2117    Disable all logging calls of severity 'level' and below.
2118    """
2119    root.manager.disable = level
2120    root.manager._clear_cache()
2121
2122def shutdown(handlerList=_handlerList):
2123    """
2124    Perform any cleanup actions in the logging system (e.g. flushing
2125    buffers).
2126
2127    Should be called at application exit.
2128    """
2129    for wr in reversed(handlerList[:]):
2130        #errors might occur, for example, if files are locked
2131        #we just ignore them if raiseExceptions is not set
2132        try:
2133            h = wr()
2134            if h:
2135                try:
2136                    h.acquire()
2137                    h.flush()
2138                    h.close()
2139                except (OSError, ValueError):
2140                    # Ignore errors which might be caused
2141                    # because handlers have been closed but
2142                    # references to them are still around at
2143                    # application exit.
2144                    pass
2145                finally:
2146                    h.release()
2147        except: # ignore everything, as we're shutting down
2148            if raiseExceptions:
2149                raise
2150            #else, swallow
2151
2152#Let's try and shutdown automatically on application exit...
2153import atexit
2154atexit.register(shutdown)
2155
2156# Null handler
2157
2158class NullHandler(Handler):
2159    """
2160    This handler does nothing. It's intended to be used to avoid the
2161    "No handlers could be found for logger XXX" one-off warning. This is
2162    important for library code, which may contain code to log events. If a user
2163    of the library does not configure logging, the one-off warning might be
2164    produced; to avoid this, the library developer simply needs to instantiate
2165    a NullHandler and add it to the top-level logger of the library module or
2166    package.
2167    """
2168    def handle(self, record):
2169        """Stub."""
2170
2171    def emit(self, record):
2172        """Stub."""
2173
2174    def createLock(self):
2175        self.lock = None
2176
2177    def _at_fork_reinit(self):
2178        pass
2179
2180# Warnings integration
2181
2182_warnings_showwarning = None
2183
2184def _showwarning(message, category, filename, lineno, file=None, line=None):
2185    """
2186    Implementation of showwarnings which redirects to logging, which will first
2187    check to see if the file parameter is None. If a file is specified, it will
2188    delegate to the original warnings implementation of showwarning. Otherwise,
2189    it will call warnings.formatwarning and will log the resulting string to a
2190    warnings logger named "py.warnings" with level logging.WARNING.
2191    """
2192    if file is not None:
2193        if _warnings_showwarning is not None:
2194            _warnings_showwarning(message, category, filename, lineno, file, line)
2195    else:
2196        s = warnings.formatwarning(message, category, filename, lineno, line)
2197        logger = getLogger("py.warnings")
2198        if not logger.handlers:
2199            logger.addHandler(NullHandler())
2200        logger.warning("%s", s)
2201
2202def captureWarnings(capture):
2203    """
2204    If capture is true, redirect all warnings to the logging package.
2205    If capture is False, ensure that warnings are not redirected to logging
2206    but to their original destinations.
2207    """
2208    global _warnings_showwarning
2209    if capture:
2210        if _warnings_showwarning is None:
2211            _warnings_showwarning = warnings.showwarning
2212            warnings.showwarning = _showwarning
2213    else:
2214        if _warnings_showwarning is not None:
2215            warnings.showwarning = _warnings_showwarning
2216            _warnings_showwarning = None
2217