• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2001-2017 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-2017 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 createLock method (logging.Handler)
238    # to be called in the child after forking.  The weakref avoids us keeping
239    # discarded Handler instances alive.  A set is used to avoid accumulating
240    # duplicate registrations as createLock() is responsible for registering
241    # a new Handler instance with this set in the first place.
242    _at_fork_reinit_lock_weakset = weakref.WeakSet()
243
244    def _register_at_fork_reinit_lock(instance):
245        _acquireLock()
246        try:
247            _at_fork_reinit_lock_weakset.add(instance)
248        finally:
249            _releaseLock()
250
251    def _after_at_fork_child_reinit_locks():
252        # _acquireLock() was called in the parent before forking.
253        for handler in _at_fork_reinit_lock_weakset:
254            try:
255                handler.createLock()
256            except Exception as err:
257                # Similar to what PyErr_WriteUnraisable does.
258                print("Ignoring exception from logging atfork", instance,
259                      "._reinit_lock() method:", err, file=sys.stderr)
260        _releaseLock()  # Acquired by os.register_at_fork(before=.
261
262
263    os.register_at_fork(before=_acquireLock,
264                        after_in_child=_after_at_fork_child_reinit_locks,
265                        after_in_parent=_releaseLock)
266
267
268#---------------------------------------------------------------------------
269#   The logging record
270#---------------------------------------------------------------------------
271
272class LogRecord(object):
273    """
274    A LogRecord instance represents an event being logged.
275
276    LogRecord instances are created every time something is logged. They
277    contain all the information pertinent to the event being logged. The
278    main information passed in is in msg and args, which are combined
279    using str(msg) % args to create the message field of the record. The
280    record also includes information such as when the record was created,
281    the source line where the logging call was made, and any exception
282    information to be logged.
283    """
284    def __init__(self, name, level, pathname, lineno,
285                 msg, args, exc_info, func=None, sinfo=None, **kwargs):
286        """
287        Initialize a logging record with interesting information.
288        """
289        ct = time.time()
290        self.name = name
291        self.msg = msg
292        #
293        # The following statement allows passing of a dictionary as a sole
294        # argument, so that you can do something like
295        #  logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
296        # Suggested by Stefan Behnel.
297        # Note that without the test for args[0], we get a problem because
298        # during formatting, we test to see if the arg is present using
299        # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
300        # and if the passed arg fails 'if self.args:' then no formatting
301        # is done. For example, logger.warning('Value is %d', 0) would log
302        # 'Value is %d' instead of 'Value is 0'.
303        # For the use case of passing a dictionary, this should not be a
304        # problem.
305        # Issue #21172: a request was made to relax the isinstance check
306        # to hasattr(args[0], '__getitem__'). However, the docs on string
307        # formatting still seem to suggest a mapping object is required.
308        # Thus, while not removing the isinstance check, it does now look
309        # for collections.abc.Mapping rather than, as before, dict.
310        if (args and len(args) == 1 and isinstance(args[0], collections.abc.Mapping)
311            and args[0]):
312            args = args[0]
313        self.args = args
314        self.levelname = getLevelName(level)
315        self.levelno = level
316        self.pathname = pathname
317        try:
318            self.filename = os.path.basename(pathname)
319            self.module = os.path.splitext(self.filename)[0]
320        except (TypeError, ValueError, AttributeError):
321            self.filename = pathname
322            self.module = "Unknown module"
323        self.exc_info = exc_info
324        self.exc_text = None      # used to cache the traceback text
325        self.stack_info = sinfo
326        self.lineno = lineno
327        self.funcName = func
328        self.created = ct
329        self.msecs = (ct - int(ct)) * 1000
330        self.relativeCreated = (self.created - _startTime) * 1000
331        if logThreads:
332            self.thread = threading.get_ident()
333            self.threadName = threading.current_thread().name
334        else: # pragma: no cover
335            self.thread = None
336            self.threadName = None
337        if not logMultiprocessing: # pragma: no cover
338            self.processName = None
339        else:
340            self.processName = 'MainProcess'
341            mp = sys.modules.get('multiprocessing')
342            if mp is not None:
343                # Errors may occur if multiprocessing has not finished loading
344                # yet - e.g. if a custom import hook causes third-party code
345                # to run when multiprocessing calls import. See issue 8200
346                # for an example
347                try:
348                    self.processName = mp.current_process().name
349                except Exception: #pragma: no cover
350                    pass
351        if logProcesses and hasattr(os, 'getpid'):
352            self.process = os.getpid()
353        else:
354            self.process = None
355
356    def __repr__(self):
357        return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
358            self.pathname, self.lineno, self.msg)
359
360    def getMessage(self):
361        """
362        Return the message for this LogRecord.
363
364        Return the message for this LogRecord after merging any user-supplied
365        arguments with the message.
366        """
367        msg = str(self.msg)
368        if self.args:
369            msg = msg % self.args
370        return msg
371
372#
373#   Determine which class to use when instantiating log records.
374#
375_logRecordFactory = LogRecord
376
377def setLogRecordFactory(factory):
378    """
379    Set the factory to be used when instantiating a log record.
380
381    :param factory: A callable which will be called to instantiate
382    a log record.
383    """
384    global _logRecordFactory
385    _logRecordFactory = factory
386
387def getLogRecordFactory():
388    """
389    Return the factory to be used when instantiating a log record.
390    """
391
392    return _logRecordFactory
393
394def makeLogRecord(dict):
395    """
396    Make a LogRecord whose attributes are defined by the specified dictionary,
397    This function is useful for converting a logging event received over
398    a socket connection (which is sent as a dictionary) into a LogRecord
399    instance.
400    """
401    rv = _logRecordFactory(None, None, "", 0, "", (), None, None)
402    rv.__dict__.update(dict)
403    return rv
404
405
406#---------------------------------------------------------------------------
407#   Formatter classes and functions
408#---------------------------------------------------------------------------
409_str_formatter = StrFormatter()
410del StrFormatter
411
412
413class PercentStyle(object):
414
415    default_format = '%(message)s'
416    asctime_format = '%(asctime)s'
417    asctime_search = '%(asctime)'
418    validation_pattern = re.compile(r'%\(\w+\)[#0+ -]*(\*|\d+)?(\.(\*|\d+))?[diouxefgcrsa%]', re.I)
419
420    def __init__(self, fmt):
421        self._fmt = fmt or self.default_format
422
423    def usesTime(self):
424        return self._fmt.find(self.asctime_search) >= 0
425
426    def validate(self):
427        """Validate the input format, ensure it matches the correct style"""
428        if not self.validation_pattern.search(self._fmt):
429            raise ValueError("Invalid format '%s' for '%s' style" % (self._fmt, self.default_format[0]))
430
431    def _format(self, record):
432        return self._fmt % record.__dict__
433
434    def format(self, record):
435        try:
436            return self._format(record)
437        except KeyError as e:
438            raise ValueError('Formatting field not found in record: %s' % e)
439
440
441class StrFormatStyle(PercentStyle):
442    default_format = '{message}'
443    asctime_format = '{asctime}'
444    asctime_search = '{asctime'
445
446    fmt_spec = re.compile(r'^(.?[<>=^])?[+ -]?#?0?(\d+|{\w+})?[,_]?(\.(\d+|{\w+}))?[bcdefgnosx%]?$', re.I)
447    field_spec = re.compile(r'^(\d+|\w+)(\.\w+|\[[^]]+\])*$')
448
449    def _format(self, record):
450        return self._fmt.format(**record.__dict__)
451
452    def validate(self):
453        """Validate the input format, ensure it is the correct string formatting style"""
454        fields = set()
455        try:
456            for _, fieldname, spec, conversion in _str_formatter.parse(self._fmt):
457                if fieldname:
458                    if not self.field_spec.match(fieldname):
459                        raise ValueError('invalid field name/expression: %r' % fieldname)
460                    fields.add(fieldname)
461                if conversion and conversion not in 'rsa':
462                    raise ValueError('invalid conversion: %r' % conversion)
463                if spec and not self.fmt_spec.match(spec):
464                    raise ValueError('bad specifier: %r' % spec)
465        except ValueError as e:
466            raise ValueError('invalid format: %s' % e)
467        if not fields:
468            raise ValueError('invalid format: no fields')
469
470
471class StringTemplateStyle(PercentStyle):
472    default_format = '${message}'
473    asctime_format = '${asctime}'
474    asctime_search = '${asctime}'
475
476    def __init__(self, fmt):
477        self._fmt = fmt or self.default_format
478        self._tpl = Template(self._fmt)
479
480    def usesTime(self):
481        fmt = self._fmt
482        return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_format) >= 0
483
484    def validate(self):
485        pattern = Template.pattern
486        fields = set()
487        for m in pattern.finditer(self._fmt):
488            d = m.groupdict()
489            if d['named']:
490                fields.add(d['named'])
491            elif d['braced']:
492                fields.add(d['braced'])
493            elif m.group(0) == '$':
494                raise ValueError('invalid format: bare \'$\' not allowed')
495        if not fields:
496            raise ValueError('invalid format: no fields')
497
498    def _format(self, record):
499        return self._tpl.substitute(**record.__dict__)
500
501
502BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
503
504_STYLES = {
505    '%': (PercentStyle, BASIC_FORMAT),
506    '{': (StrFormatStyle, '{levelname}:{name}:{message}'),
507    '$': (StringTemplateStyle, '${levelname}:${name}:${message}'),
508}
509
510class Formatter(object):
511    """
512    Formatter instances are used to convert a LogRecord to text.
513
514    Formatters need to know how a LogRecord is constructed. They are
515    responsible for converting a LogRecord to (usually) a string which can
516    be interpreted by either a human or an external system. The base Formatter
517    allows a formatting string to be specified. If none is supplied, the
518    the style-dependent default value, "%(message)s", "{message}", or
519    "${message}", is used.
520
521    The Formatter can be initialized with a format string which makes use of
522    knowledge of the LogRecord attributes - e.g. the default value mentioned
523    above makes use of the fact that the user's message and arguments are pre-
524    formatted into a LogRecord's message attribute. Currently, the useful
525    attributes in a LogRecord are described by:
526
527    %(name)s            Name of the logger (logging channel)
528    %(levelno)s         Numeric logging level for the message (DEBUG, INFO,
529                        WARNING, ERROR, CRITICAL)
530    %(levelname)s       Text logging level for the message ("DEBUG", "INFO",
531                        "WARNING", "ERROR", "CRITICAL")
532    %(pathname)s        Full pathname of the source file where the logging
533                        call was issued (if available)
534    %(filename)s        Filename portion of pathname
535    %(module)s          Module (name portion of filename)
536    %(lineno)d          Source line number where the logging call was issued
537                        (if available)
538    %(funcName)s        Function name
539    %(created)f         Time when the LogRecord was created (time.time()
540                        return value)
541    %(asctime)s         Textual time when the LogRecord was created
542    %(msecs)d           Millisecond portion of the creation time
543    %(relativeCreated)d Time in milliseconds when the LogRecord was created,
544                        relative to the time the logging module was loaded
545                        (typically at application startup time)
546    %(thread)d          Thread ID (if available)
547    %(threadName)s      Thread name (if available)
548    %(process)d         Process ID (if available)
549    %(message)s         The result of record.getMessage(), computed just as
550                        the record is emitted
551    """
552
553    converter = time.localtime
554
555    def __init__(self, fmt=None, datefmt=None, style='%', validate=True):
556        """
557        Initialize the formatter with specified format strings.
558
559        Initialize the formatter either with the specified format string, or a
560        default as described above. Allow for specialized date formatting with
561        the optional datefmt argument. If datefmt is omitted, you get an
562        ISO8601-like (or RFC 3339-like) format.
563
564        Use a style parameter of '%', '{' or '$' to specify that you want to
565        use one of %-formatting, :meth:`str.format` (``{}``) formatting or
566        :class:`string.Template` formatting in your format string.
567
568        .. versionchanged:: 3.2
569           Added the ``style`` parameter.
570        """
571        if style not in _STYLES:
572            raise ValueError('Style must be one of: %s' % ','.join(
573                             _STYLES.keys()))
574        self._style = _STYLES[style][0](fmt)
575        if validate:
576            self._style.validate()
577
578        self._fmt = self._style._fmt
579        self.datefmt = datefmt
580
581    default_time_format = '%Y-%m-%d %H:%M:%S'
582    default_msec_format = '%s,%03d'
583
584    def formatTime(self, record, datefmt=None):
585        """
586        Return the creation time of the specified LogRecord as formatted text.
587
588        This method should be called from format() by a formatter which
589        wants to make use of a formatted time. This method can be overridden
590        in formatters to provide for any specific requirement, but the
591        basic behaviour is as follows: if datefmt (a string) is specified,
592        it is used with time.strftime() to format the creation time of the
593        record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used.
594        The resulting string is returned. This function uses a user-configurable
595        function to convert the creation time to a tuple. By default,
596        time.localtime() is used; to change this for a particular formatter
597        instance, set the 'converter' attribute to a function with the same
598        signature as time.localtime() or time.gmtime(). To change it for all
599        formatters, for example if you want all logging times to be shown in GMT,
600        set the 'converter' attribute in the Formatter class.
601        """
602        ct = self.converter(record.created)
603        if datefmt:
604            s = time.strftime(datefmt, ct)
605        else:
606            t = time.strftime(self.default_time_format, ct)
607            s = self.default_msec_format % (t, record.msecs)
608        return s
609
610    def formatException(self, ei):
611        """
612        Format and return the specified exception information as a string.
613
614        This default implementation just uses
615        traceback.print_exception()
616        """
617        sio = io.StringIO()
618        tb = ei[2]
619        # See issues #9427, #1553375. Commented out for now.
620        #if getattr(self, 'fullstack', False):
621        #    traceback.print_stack(tb.tb_frame.f_back, file=sio)
622        traceback.print_exception(ei[0], ei[1], tb, None, sio)
623        s = sio.getvalue()
624        sio.close()
625        if s[-1:] == "\n":
626            s = s[:-1]
627        return s
628
629    def usesTime(self):
630        """
631        Check if the format uses the creation time of the record.
632        """
633        return self._style.usesTime()
634
635    def formatMessage(self, record):
636        return self._style.format(record)
637
638    def formatStack(self, stack_info):
639        """
640        This method is provided as an extension point for specialized
641        formatting of stack information.
642
643        The input data is a string as returned from a call to
644        :func:`traceback.print_stack`, but with the last trailing newline
645        removed.
646
647        The base implementation just returns the value passed in.
648        """
649        return stack_info
650
651    def format(self, record):
652        """
653        Format the specified record as text.
654
655        The record's attribute dictionary is used as the operand to a
656        string formatting operation which yields the returned string.
657        Before formatting the dictionary, a couple of preparatory steps
658        are carried out. The message attribute of the record is computed
659        using LogRecord.getMessage(). If the formatting string uses the
660        time (as determined by a call to usesTime(), formatTime() is
661        called to format the event time. If there is exception information,
662        it is formatted using formatException() and appended to the message.
663        """
664        record.message = record.getMessage()
665        if self.usesTime():
666            record.asctime = self.formatTime(record, self.datefmt)
667        s = self.formatMessage(record)
668        if record.exc_info:
669            # Cache the traceback text to avoid converting it multiple times
670            # (it's constant anyway)
671            if not record.exc_text:
672                record.exc_text = self.formatException(record.exc_info)
673        if record.exc_text:
674            if s[-1:] != "\n":
675                s = s + "\n"
676            s = s + record.exc_text
677        if record.stack_info:
678            if s[-1:] != "\n":
679                s = s + "\n"
680            s = s + self.formatStack(record.stack_info)
681        return s
682
683#
684#   The default formatter to use when no other is specified
685#
686_defaultFormatter = Formatter()
687
688class BufferingFormatter(object):
689    """
690    A formatter suitable for formatting a number of records.
691    """
692    def __init__(self, linefmt=None):
693        """
694        Optionally specify a formatter which will be used to format each
695        individual record.
696        """
697        if linefmt:
698            self.linefmt = linefmt
699        else:
700            self.linefmt = _defaultFormatter
701
702    def formatHeader(self, records):
703        """
704        Return the header string for the specified records.
705        """
706        return ""
707
708    def formatFooter(self, records):
709        """
710        Return the footer string for the specified records.
711        """
712        return ""
713
714    def format(self, records):
715        """
716        Format the specified records and return the result as a string.
717        """
718        rv = ""
719        if len(records) > 0:
720            rv = rv + self.formatHeader(records)
721            for record in records:
722                rv = rv + self.linefmt.format(record)
723            rv = rv + self.formatFooter(records)
724        return rv
725
726#---------------------------------------------------------------------------
727#   Filter classes and functions
728#---------------------------------------------------------------------------
729
730class Filter(object):
731    """
732    Filter instances are used to perform arbitrary filtering of LogRecords.
733
734    Loggers and Handlers can optionally use Filter instances to filter
735    records as desired. The base filter class only allows events which are
736    below a certain point in the logger hierarchy. For example, a filter
737    initialized with "A.B" will allow events logged by loggers "A.B",
738    "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
739    initialized with the empty string, all events are passed.
740    """
741    def __init__(self, name=''):
742        """
743        Initialize a filter.
744
745        Initialize with the name of the logger which, together with its
746        children, will have its events allowed through the filter. If no
747        name is specified, allow every event.
748        """
749        self.name = name
750        self.nlen = len(name)
751
752    def filter(self, record):
753        """
754        Determine if the specified record is to be logged.
755
756        Is the specified record to be logged? Returns 0 for no, nonzero for
757        yes. If deemed appropriate, the record may be modified in-place.
758        """
759        if self.nlen == 0:
760            return True
761        elif self.name == record.name:
762            return True
763        elif record.name.find(self.name, 0, self.nlen) != 0:
764            return False
765        return (record.name[self.nlen] == ".")
766
767class Filterer(object):
768    """
769    A base class for loggers and handlers which allows them to share
770    common code.
771    """
772    def __init__(self):
773        """
774        Initialize the list of filters to be an empty list.
775        """
776        self.filters = []
777
778    def addFilter(self, filter):
779        """
780        Add the specified filter to this handler.
781        """
782        if not (filter in self.filters):
783            self.filters.append(filter)
784
785    def removeFilter(self, filter):
786        """
787        Remove the specified filter from this handler.
788        """
789        if filter in self.filters:
790            self.filters.remove(filter)
791
792    def filter(self, record):
793        """
794        Determine if a record is loggable by consulting all the filters.
795
796        The default is to allow the record to be logged; any filter can veto
797        this and the record is then dropped. Returns a zero value if a record
798        is to be dropped, else non-zero.
799
800        .. versionchanged:: 3.2
801
802           Allow filters to be just callables.
803        """
804        rv = True
805        for f in self.filters:
806            if hasattr(f, 'filter'):
807                result = f.filter(record)
808            else:
809                result = f(record) # assume callable - will raise if not
810            if not result:
811                rv = False
812                break
813        return rv
814
815#---------------------------------------------------------------------------
816#   Handler classes and functions
817#---------------------------------------------------------------------------
818
819_handlers = weakref.WeakValueDictionary()  #map of handler names to handlers
820_handlerList = [] # added to allow handlers to be removed in reverse of order initialized
821
822def _removeHandlerRef(wr):
823    """
824    Remove a handler reference from the internal cleanup list.
825    """
826    # This function can be called during module teardown, when globals are
827    # set to None. It can also be called from another thread. So we need to
828    # pre-emptively grab the necessary globals and check if they're None,
829    # to prevent race conditions and failures during interpreter shutdown.
830    acquire, release, handlers = _acquireLock, _releaseLock, _handlerList
831    if acquire and release and handlers:
832        acquire()
833        try:
834            if wr in handlers:
835                handlers.remove(wr)
836        finally:
837            release()
838
839def _addHandlerRef(handler):
840    """
841    Add a handler to the internal cleanup list using a weak reference.
842    """
843    _acquireLock()
844    try:
845        _handlerList.append(weakref.ref(handler, _removeHandlerRef))
846    finally:
847        _releaseLock()
848
849class Handler(Filterer):
850    """
851    Handler instances dispatch logging events to specific destinations.
852
853    The base handler class. Acts as a placeholder which defines the Handler
854    interface. Handlers can optionally use Formatter instances to format
855    records as desired. By default, no formatter is specified; in this case,
856    the 'raw' message as determined by record.message is logged.
857    """
858    def __init__(self, level=NOTSET):
859        """
860        Initializes the instance - basically setting the formatter to None
861        and the filter list to empty.
862        """
863        Filterer.__init__(self)
864        self._name = None
865        self.level = _checkLevel(level)
866        self.formatter = None
867        # Add the handler to the global _handlerList (for cleanup on shutdown)
868        _addHandlerRef(self)
869        self.createLock()
870
871    def get_name(self):
872        return self._name
873
874    def set_name(self, name):
875        _acquireLock()
876        try:
877            if self._name in _handlers:
878                del _handlers[self._name]
879            self._name = name
880            if name:
881                _handlers[name] = self
882        finally:
883            _releaseLock()
884
885    name = property(get_name, set_name)
886
887    def createLock(self):
888        """
889        Acquire a thread lock for serializing access to the underlying I/O.
890        """
891        self.lock = threading.RLock()
892        _register_at_fork_reinit_lock(self)
893
894    def acquire(self):
895        """
896        Acquire the I/O thread lock.
897        """
898        if self.lock:
899            self.lock.acquire()
900
901    def release(self):
902        """
903        Release the I/O thread lock.
904        """
905        if self.lock:
906            self.lock.release()
907
908    def setLevel(self, level):
909        """
910        Set the logging level of this handler.  level must be an int or a str.
911        """
912        self.level = _checkLevel(level)
913
914    def format(self, record):
915        """
916        Format the specified record.
917
918        If a formatter is set, use it. Otherwise, use the default formatter
919        for the module.
920        """
921        if self.formatter:
922            fmt = self.formatter
923        else:
924            fmt = _defaultFormatter
925        return fmt.format(record)
926
927    def emit(self, record):
928        """
929        Do whatever it takes to actually log the specified logging record.
930
931        This version is intended to be implemented by subclasses and so
932        raises a NotImplementedError.
933        """
934        raise NotImplementedError('emit must be implemented '
935                                  'by Handler subclasses')
936
937    def handle(self, record):
938        """
939        Conditionally emit the specified logging record.
940
941        Emission depends on filters which may have been added to the handler.
942        Wrap the actual emission of the record with acquisition/release of
943        the I/O thread lock. Returns whether the filter passed the record for
944        emission.
945        """
946        rv = self.filter(record)
947        if rv:
948            self.acquire()
949            try:
950                self.emit(record)
951            finally:
952                self.release()
953        return rv
954
955    def setFormatter(self, fmt):
956        """
957        Set the formatter for this handler.
958        """
959        self.formatter = fmt
960
961    def flush(self):
962        """
963        Ensure all logging output has been flushed.
964
965        This version does nothing and is intended to be implemented by
966        subclasses.
967        """
968        pass
969
970    def close(self):
971        """
972        Tidy up any resources used by the handler.
973
974        This version removes the handler from an internal map of handlers,
975        _handlers, which is used for handler lookup by name. Subclasses
976        should ensure that this gets called from overridden close()
977        methods.
978        """
979        #get the module data lock, as we're updating a shared structure.
980        _acquireLock()
981        try:    #unlikely to raise an exception, but you never know...
982            if self._name and self._name in _handlers:
983                del _handlers[self._name]
984        finally:
985            _releaseLock()
986
987    def handleError(self, record):
988        """
989        Handle errors which occur during an emit() call.
990
991        This method should be called from handlers when an exception is
992        encountered during an emit() call. If raiseExceptions is false,
993        exceptions get silently ignored. This is what is mostly wanted
994        for a logging system - most users will not care about errors in
995        the logging system, they are more interested in application errors.
996        You could, however, replace this with a custom handler if you wish.
997        The record which was being processed is passed in to this method.
998        """
999        if raiseExceptions and sys.stderr:  # see issue 13807
1000            t, v, tb = sys.exc_info()
1001            try:
1002                sys.stderr.write('--- Logging error ---\n')
1003                traceback.print_exception(t, v, tb, None, sys.stderr)
1004                sys.stderr.write('Call stack:\n')
1005                # Walk the stack frame up until we're out of logging,
1006                # so as to print the calling context.
1007                frame = tb.tb_frame
1008                while (frame and os.path.dirname(frame.f_code.co_filename) ==
1009                       __path__[0]):
1010                    frame = frame.f_back
1011                if frame:
1012                    traceback.print_stack(frame, file=sys.stderr)
1013                else:
1014                    # couldn't find the right stack frame, for some reason
1015                    sys.stderr.write('Logged from file %s, line %s\n' % (
1016                                     record.filename, record.lineno))
1017                # Issue 18671: output logging message and arguments
1018                try:
1019                    sys.stderr.write('Message: %r\n'
1020                                     'Arguments: %s\n' % (record.msg,
1021                                                          record.args))
1022                except RecursionError:  # See issue 36272
1023                    raise
1024                except Exception:
1025                    sys.stderr.write('Unable to print the message and arguments'
1026                                     ' - possible formatting error.\nUse the'
1027                                     ' traceback above to help find the error.\n'
1028                                    )
1029            except OSError: #pragma: no cover
1030                pass    # see issue 5971
1031            finally:
1032                del t, v, tb
1033
1034    def __repr__(self):
1035        level = getLevelName(self.level)
1036        return '<%s (%s)>' % (self.__class__.__name__, level)
1037
1038class StreamHandler(Handler):
1039    """
1040    A handler class which writes logging records, appropriately formatted,
1041    to a stream. Note that this class does not close the stream, as
1042    sys.stdout or sys.stderr may be used.
1043    """
1044
1045    terminator = '\n'
1046
1047    def __init__(self, stream=None):
1048        """
1049        Initialize the handler.
1050
1051        If stream is not specified, sys.stderr is used.
1052        """
1053        Handler.__init__(self)
1054        if stream is None:
1055            stream = sys.stderr
1056        self.stream = stream
1057
1058    def flush(self):
1059        """
1060        Flushes the stream.
1061        """
1062        self.acquire()
1063        try:
1064            if self.stream and hasattr(self.stream, "flush"):
1065                self.stream.flush()
1066        finally:
1067            self.release()
1068
1069    def emit(self, record):
1070        """
1071        Emit a record.
1072
1073        If a formatter is specified, it is used to format the record.
1074        The record is then written to the stream with a trailing newline.  If
1075        exception information is present, it is formatted using
1076        traceback.print_exception and appended to the stream.  If the stream
1077        has an 'encoding' attribute, it is used to determine how to do the
1078        output to the stream.
1079        """
1080        try:
1081            msg = self.format(record)
1082            stream = self.stream
1083            # issue 35046: merged two stream.writes into one.
1084            stream.write(msg + self.terminator)
1085            self.flush()
1086        except RecursionError:  # See issue 36272
1087            raise
1088        except Exception:
1089            self.handleError(record)
1090
1091    def setStream(self, stream):
1092        """
1093        Sets the StreamHandler's stream to the specified value,
1094        if it is different.
1095
1096        Returns the old stream, if the stream was changed, or None
1097        if it wasn't.
1098        """
1099        if stream is self.stream:
1100            result = None
1101        else:
1102            result = self.stream
1103            self.acquire()
1104            try:
1105                self.flush()
1106                self.stream = stream
1107            finally:
1108                self.release()
1109        return result
1110
1111    def __repr__(self):
1112        level = getLevelName(self.level)
1113        name = getattr(self.stream, 'name', '')
1114        #  bpo-36015: name can be an int
1115        name = str(name)
1116        if name:
1117            name += ' '
1118        return '<%s %s(%s)>' % (self.__class__.__name__, name, level)
1119
1120
1121class FileHandler(StreamHandler):
1122    """
1123    A handler class which writes formatted logging records to disk files.
1124    """
1125    def __init__(self, filename, mode='a', encoding=None, delay=False):
1126        """
1127        Open the specified file and use it as the stream for logging.
1128        """
1129        # Issue #27493: add support for Path objects to be passed in
1130        filename = os.fspath(filename)
1131        #keep the absolute path, otherwise derived classes which use this
1132        #may come a cropper when the current directory changes
1133        self.baseFilename = os.path.abspath(filename)
1134        self.mode = mode
1135        self.encoding = encoding
1136        self.delay = delay
1137        if delay:
1138            #We don't open the stream, but we still need to call the
1139            #Handler constructor to set level, formatter, lock etc.
1140            Handler.__init__(self)
1141            self.stream = None
1142        else:
1143            StreamHandler.__init__(self, self._open())
1144
1145    def close(self):
1146        """
1147        Closes the stream.
1148        """
1149        self.acquire()
1150        try:
1151            try:
1152                if self.stream:
1153                    try:
1154                        self.flush()
1155                    finally:
1156                        stream = self.stream
1157                        self.stream = None
1158                        if hasattr(stream, "close"):
1159                            stream.close()
1160            finally:
1161                # Issue #19523: call unconditionally to
1162                # prevent a handler leak when delay is set
1163                StreamHandler.close(self)
1164        finally:
1165            self.release()
1166
1167    def _open(self):
1168        """
1169        Open the current base file with the (original) mode and encoding.
1170        Return the resulting stream.
1171        """
1172        return open(self.baseFilename, self.mode, encoding=self.encoding)
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            if self.manager.disable >= level:
1689                is_enabled = self._cache[level] = False
1690            else:
1691                is_enabled = self._cache[level] = level >= self.getEffectiveLevel()
1692            _releaseLock()
1693
1694            return is_enabled
1695
1696    def getChild(self, suffix):
1697        """
1698        Get a logger which is a descendant to this one.
1699
1700        This is a convenience method, such that
1701
1702        logging.getLogger('abc').getChild('def.ghi')
1703
1704        is the same as
1705
1706        logging.getLogger('abc.def.ghi')
1707
1708        It's useful, for example, when the parent logger is named using
1709        __name__ rather than a literal string.
1710        """
1711        if self.root is not self:
1712            suffix = '.'.join((self.name, suffix))
1713        return self.manager.getLogger(suffix)
1714
1715    def __repr__(self):
1716        level = getLevelName(self.getEffectiveLevel())
1717        return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level)
1718
1719    def __reduce__(self):
1720        # In general, only the root logger will not be accessible via its name.
1721        # However, the root logger's class has its own __reduce__ method.
1722        if getLogger(self.name) is not self:
1723            import pickle
1724            raise pickle.PicklingError('logger cannot be pickled')
1725        return getLogger, (self.name,)
1726
1727
1728class RootLogger(Logger):
1729    """
1730    A root logger is not that different to any other logger, except that
1731    it must have a logging level and there is only one instance of it in
1732    the hierarchy.
1733    """
1734    def __init__(self, level):
1735        """
1736        Initialize the logger with the name "root".
1737        """
1738        Logger.__init__(self, "root", level)
1739
1740    def __reduce__(self):
1741        return getLogger, ()
1742
1743_loggerClass = Logger
1744
1745class LoggerAdapter(object):
1746    """
1747    An adapter for loggers which makes it easier to specify contextual
1748    information in logging output.
1749    """
1750
1751    def __init__(self, logger, extra):
1752        """
1753        Initialize the adapter with a logger and a dict-like object which
1754        provides contextual information. This constructor signature allows
1755        easy stacking of LoggerAdapters, if so desired.
1756
1757        You can effectively pass keyword arguments as shown in the
1758        following example:
1759
1760        adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
1761        """
1762        self.logger = logger
1763        self.extra = extra
1764
1765    def process(self, msg, kwargs):
1766        """
1767        Process the logging message and keyword arguments passed in to
1768        a logging call to insert contextual information. You can either
1769        manipulate the message itself, the keyword args or both. Return
1770        the message and kwargs modified (or not) to suit your needs.
1771
1772        Normally, you'll only need to override this one method in a
1773        LoggerAdapter subclass for your specific needs.
1774        """
1775        kwargs["extra"] = self.extra
1776        return msg, kwargs
1777
1778    #
1779    # Boilerplate convenience methods
1780    #
1781    def debug(self, msg, *args, **kwargs):
1782        """
1783        Delegate a debug call to the underlying logger.
1784        """
1785        self.log(DEBUG, msg, *args, **kwargs)
1786
1787    def info(self, msg, *args, **kwargs):
1788        """
1789        Delegate an info call to the underlying logger.
1790        """
1791        self.log(INFO, msg, *args, **kwargs)
1792
1793    def warning(self, msg, *args, **kwargs):
1794        """
1795        Delegate a warning call to the underlying logger.
1796        """
1797        self.log(WARNING, msg, *args, **kwargs)
1798
1799    def warn(self, msg, *args, **kwargs):
1800        warnings.warn("The 'warn' method is deprecated, "
1801            "use 'warning' instead", DeprecationWarning, 2)
1802        self.warning(msg, *args, **kwargs)
1803
1804    def error(self, msg, *args, **kwargs):
1805        """
1806        Delegate an error call to the underlying logger.
1807        """
1808        self.log(ERROR, msg, *args, **kwargs)
1809
1810    def exception(self, msg, *args, exc_info=True, **kwargs):
1811        """
1812        Delegate an exception call to the underlying logger.
1813        """
1814        self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs)
1815
1816    def critical(self, msg, *args, **kwargs):
1817        """
1818        Delegate a critical call to the underlying logger.
1819        """
1820        self.log(CRITICAL, msg, *args, **kwargs)
1821
1822    def log(self, level, msg, *args, **kwargs):
1823        """
1824        Delegate a log call to the underlying logger, after adding
1825        contextual information from this adapter instance.
1826        """
1827        if self.isEnabledFor(level):
1828            msg, kwargs = self.process(msg, kwargs)
1829            self.logger.log(level, msg, *args, **kwargs)
1830
1831    def isEnabledFor(self, level):
1832        """
1833        Is this logger enabled for level 'level'?
1834        """
1835        return self.logger.isEnabledFor(level)
1836
1837    def setLevel(self, level):
1838        """
1839        Set the specified level on the underlying logger.
1840        """
1841        self.logger.setLevel(level)
1842
1843    def getEffectiveLevel(self):
1844        """
1845        Get the effective level for the underlying logger.
1846        """
1847        return self.logger.getEffectiveLevel()
1848
1849    def hasHandlers(self):
1850        """
1851        See if the underlying logger has any handlers.
1852        """
1853        return self.logger.hasHandlers()
1854
1855    def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False):
1856        """
1857        Low-level log implementation, proxied to allow nested logger adapters.
1858        """
1859        return self.logger._log(
1860            level,
1861            msg,
1862            args,
1863            exc_info=exc_info,
1864            extra=extra,
1865            stack_info=stack_info,
1866        )
1867
1868    @property
1869    def manager(self):
1870        return self.logger.manager
1871
1872    @manager.setter
1873    def manager(self, value):
1874        self.logger.manager = value
1875
1876    @property
1877    def name(self):
1878        return self.logger.name
1879
1880    def __repr__(self):
1881        logger = self.logger
1882        level = getLevelName(logger.getEffectiveLevel())
1883        return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level)
1884
1885root = RootLogger(WARNING)
1886Logger.root = root
1887Logger.manager = Manager(Logger.root)
1888
1889#---------------------------------------------------------------------------
1890# Configuration classes and functions
1891#---------------------------------------------------------------------------
1892
1893def basicConfig(**kwargs):
1894    """
1895    Do basic configuration for the logging system.
1896
1897    This function does nothing if the root logger already has handlers
1898    configured, unless the keyword argument *force* is set to ``True``.
1899    It is a convenience method intended for use by simple scripts
1900    to do one-shot configuration of the logging package.
1901
1902    The default behaviour is to create a StreamHandler which writes to
1903    sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1904    add the handler to the root logger.
1905
1906    A number of optional keyword arguments may be specified, which can alter
1907    the default behaviour.
1908
1909    filename  Specifies that a FileHandler be created, using the specified
1910              filename, rather than a StreamHandler.
1911    filemode  Specifies the mode to open the file, if filename is specified
1912              (if filemode is unspecified, it defaults to 'a').
1913    format    Use the specified format string for the handler.
1914    datefmt   Use the specified date/time format.
1915    style     If a format string is specified, use this to specify the
1916              type of format string (possible values '%', '{', '$', for
1917              %-formatting, :meth:`str.format` and :class:`string.Template`
1918              - defaults to '%').
1919    level     Set the root logger level to the specified level.
1920    stream    Use the specified stream to initialize the StreamHandler. Note
1921              that this argument is incompatible with 'filename' - if both
1922              are present, 'stream' is ignored.
1923    handlers  If specified, this should be an iterable of already created
1924              handlers, which will be added to the root handler. Any handler
1925              in the list which does not have a formatter assigned will be
1926              assigned the formatter created in this function.
1927    force     If this keyword  is specified as true, any existing handlers
1928              attached to the root logger are removed and closed, before
1929              carrying out the configuration as specified by the other
1930              arguments.
1931    Note that you could specify a stream created using open(filename, mode)
1932    rather than passing the filename and mode in. However, it should be
1933    remembered that StreamHandler does not close its stream (since it may be
1934    using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1935    when the handler is closed.
1936
1937    .. versionchanged:: 3.8
1938       Added the ``force`` parameter.
1939
1940    .. versionchanged:: 3.2
1941       Added the ``style`` parameter.
1942
1943    .. versionchanged:: 3.3
1944       Added the ``handlers`` parameter. A ``ValueError`` is now thrown for
1945       incompatible arguments (e.g. ``handlers`` specified together with
1946       ``filename``/``filemode``, or ``filename``/``filemode`` specified
1947       together with ``stream``, or ``handlers`` specified together with
1948       ``stream``.
1949    """
1950    # Add thread safety in case someone mistakenly calls
1951    # basicConfig() from multiple threads
1952    _acquireLock()
1953    try:
1954        force = kwargs.pop('force', False)
1955        if force:
1956            for h in root.handlers[:]:
1957                root.removeHandler(h)
1958                h.close()
1959        if len(root.handlers) == 0:
1960            handlers = kwargs.pop("handlers", None)
1961            if handlers is None:
1962                if "stream" in kwargs and "filename" in kwargs:
1963                    raise ValueError("'stream' and 'filename' should not be "
1964                                     "specified together")
1965            else:
1966                if "stream" in kwargs or "filename" in kwargs:
1967                    raise ValueError("'stream' or 'filename' should not be "
1968                                     "specified together with 'handlers'")
1969            if handlers is None:
1970                filename = kwargs.pop("filename", None)
1971                mode = kwargs.pop("filemode", 'a')
1972                if filename:
1973                    h = FileHandler(filename, mode)
1974                else:
1975                    stream = kwargs.pop("stream", None)
1976                    h = StreamHandler(stream)
1977                handlers = [h]
1978            dfs = kwargs.pop("datefmt", None)
1979            style = kwargs.pop("style", '%')
1980            if style not in _STYLES:
1981                raise ValueError('Style must be one of: %s' % ','.join(
1982                                 _STYLES.keys()))
1983            fs = kwargs.pop("format", _STYLES[style][1])
1984            fmt = Formatter(fs, dfs, style)
1985            for h in handlers:
1986                if h.formatter is None:
1987                    h.setFormatter(fmt)
1988                root.addHandler(h)
1989            level = kwargs.pop("level", None)
1990            if level is not None:
1991                root.setLevel(level)
1992            if kwargs:
1993                keys = ', '.join(kwargs.keys())
1994                raise ValueError('Unrecognised argument(s): %s' % keys)
1995    finally:
1996        _releaseLock()
1997
1998#---------------------------------------------------------------------------
1999# Utility functions at module level.
2000# Basically delegate everything to the root logger.
2001#---------------------------------------------------------------------------
2002
2003def getLogger(name=None):
2004    """
2005    Return a logger with the specified name, creating it if necessary.
2006
2007    If no name is specified, return the root logger.
2008    """
2009    if name:
2010        return Logger.manager.getLogger(name)
2011    else:
2012        return root
2013
2014def critical(msg, *args, **kwargs):
2015    """
2016    Log a message with severity 'CRITICAL' on the root logger. If the logger
2017    has no handlers, call basicConfig() to add a console handler with a
2018    pre-defined format.
2019    """
2020    if len(root.handlers) == 0:
2021        basicConfig()
2022    root.critical(msg, *args, **kwargs)
2023
2024fatal = critical
2025
2026def error(msg, *args, **kwargs):
2027    """
2028    Log a message with severity 'ERROR' on the root logger. If the logger has
2029    no handlers, call basicConfig() to add a console handler with a pre-defined
2030    format.
2031    """
2032    if len(root.handlers) == 0:
2033        basicConfig()
2034    root.error(msg, *args, **kwargs)
2035
2036def exception(msg, *args, exc_info=True, **kwargs):
2037    """
2038    Log a message with severity 'ERROR' on the root logger, with exception
2039    information. If the logger has no handlers, basicConfig() is called to add
2040    a console handler with a pre-defined format.
2041    """
2042    error(msg, *args, exc_info=exc_info, **kwargs)
2043
2044def warning(msg, *args, **kwargs):
2045    """
2046    Log a message with severity 'WARNING' 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.warning(msg, *args, **kwargs)
2053
2054def warn(msg, *args, **kwargs):
2055    warnings.warn("The 'warn' function is deprecated, "
2056        "use 'warning' instead", DeprecationWarning, 2)
2057    warning(msg, *args, **kwargs)
2058
2059def info(msg, *args, **kwargs):
2060    """
2061    Log a message with severity 'INFO' on the root logger. If the logger has
2062    no handlers, call basicConfig() to add a console handler with a pre-defined
2063    format.
2064    """
2065    if len(root.handlers) == 0:
2066        basicConfig()
2067    root.info(msg, *args, **kwargs)
2068
2069def debug(msg, *args, **kwargs):
2070    """
2071    Log a message with severity 'DEBUG' on the root logger. If the logger has
2072    no handlers, call basicConfig() to add a console handler with a pre-defined
2073    format.
2074    """
2075    if len(root.handlers) == 0:
2076        basicConfig()
2077    root.debug(msg, *args, **kwargs)
2078
2079def log(level, msg, *args, **kwargs):
2080    """
2081    Log 'msg % args' with the integer severity 'level' on the root logger. If
2082    the logger has no handlers, call basicConfig() to add a console handler
2083    with a pre-defined format.
2084    """
2085    if len(root.handlers) == 0:
2086        basicConfig()
2087    root.log(level, msg, *args, **kwargs)
2088
2089def disable(level=CRITICAL):
2090    """
2091    Disable all logging calls of severity 'level' and below.
2092    """
2093    root.manager.disable = level
2094    root.manager._clear_cache()
2095
2096def shutdown(handlerList=_handlerList):
2097    """
2098    Perform any cleanup actions in the logging system (e.g. flushing
2099    buffers).
2100
2101    Should be called at application exit.
2102    """
2103    for wr in reversed(handlerList[:]):
2104        #errors might occur, for example, if files are locked
2105        #we just ignore them if raiseExceptions is not set
2106        try:
2107            h = wr()
2108            if h:
2109                try:
2110                    h.acquire()
2111                    h.flush()
2112                    h.close()
2113                except (OSError, ValueError):
2114                    # Ignore errors which might be caused
2115                    # because handlers have been closed but
2116                    # references to them are still around at
2117                    # application exit.
2118                    pass
2119                finally:
2120                    h.release()
2121        except: # ignore everything, as we're shutting down
2122            if raiseExceptions:
2123                raise
2124            #else, swallow
2125
2126#Let's try and shutdown automatically on application exit...
2127import atexit
2128atexit.register(shutdown)
2129
2130# Null handler
2131
2132class NullHandler(Handler):
2133    """
2134    This handler does nothing. It's intended to be used to avoid the
2135    "No handlers could be found for logger XXX" one-off warning. This is
2136    important for library code, which may contain code to log events. If a user
2137    of the library does not configure logging, the one-off warning might be
2138    produced; to avoid this, the library developer simply needs to instantiate
2139    a NullHandler and add it to the top-level logger of the library module or
2140    package.
2141    """
2142    def handle(self, record):
2143        """Stub."""
2144
2145    def emit(self, record):
2146        """Stub."""
2147
2148    def createLock(self):
2149        self.lock = None
2150
2151# Warnings integration
2152
2153_warnings_showwarning = None
2154
2155def _showwarning(message, category, filename, lineno, file=None, line=None):
2156    """
2157    Implementation of showwarnings which redirects to logging, which will first
2158    check to see if the file parameter is None. If a file is specified, it will
2159    delegate to the original warnings implementation of showwarning. Otherwise,
2160    it will call warnings.formatwarning and will log the resulting string to a
2161    warnings logger named "py.warnings" with level logging.WARNING.
2162    """
2163    if file is not None:
2164        if _warnings_showwarning is not None:
2165            _warnings_showwarning(message, category, filename, lineno, file, line)
2166    else:
2167        s = warnings.formatwarning(message, category, filename, lineno, line)
2168        logger = getLogger("py.warnings")
2169        if not logger.handlers:
2170            logger.addHandler(NullHandler())
2171        logger.warning("%s", s)
2172
2173def captureWarnings(capture):
2174    """
2175    If capture is true, redirect all warnings to the logging package.
2176    If capture is False, ensure that warnings are not redirected to logging
2177    but to their original destinations.
2178    """
2179    global _warnings_showwarning
2180    if capture:
2181        if _warnings_showwarning is None:
2182            _warnings_showwarning = warnings.showwarning
2183            warnings.showwarning = _showwarning
2184    else:
2185        if _warnings_showwarning is not None:
2186            warnings.showwarning = _warnings_showwarning
2187            _warnings_showwarning = None
2188