logging

Logging package for Python. Based on PEP 282 and comments thereto in comp.lang.python.

Copyright (C) 2001-2022 Vinay Sajip. All Rights Reserved.

To use, simply 'import logging' and log away!

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

A formatter suitable for formatting a number of records.

BufferingFormatter(linefmt=None)
732    def __init__(self, linefmt=None):
733        """
734        Optionally specify a formatter which will be used to format each
735        individual record.
736        """
737        if linefmt:
738            self.linefmt = linefmt
739        else:
740            self.linefmt = _defaultFormatter

Optionally specify a formatter which will be used to format each individual record.

def formatHeader(self, records):
742    def formatHeader(self, records):
743        """
744        Return the header string for the specified records.
745        """
746        return ""

Return the header string for the specified records.

def formatFooter(self, records):
748    def formatFooter(self, records):
749        """
750        Return the footer string for the specified records.
751        """
752        return ""

Return the footer string for the specified records.

def format(self, records):
754    def format(self, records):
755        """
756        Format the specified records and return the result as a string.
757        """
758        rv = ""
759        if len(records) > 0:
760            rv = rv + self.formatHeader(records)
761            for record in records:
762                rv = rv + self.linefmt.format(record)
763            rv = rv + self.formatFooter(records)
764        return rv

Format the specified records and return the result as a string.

CRITICAL = 50
DEBUG = 10
ERROR = 40
FATAL = 50
class FileHandler(StreamHandler):
1203class FileHandler(StreamHandler):
1204    """
1205    A handler class which writes formatted logging records to disk files.
1206    """
1207    def __init__(self, filename, mode='a', encoding=None, delay=False, errors=None):
1208        """
1209        Open the specified file and use it as the stream for logging.
1210        """
1211        # Issue #27493: add support for Path objects to be passed in
1212        filename = os.fspath(filename)
1213        #keep the absolute path, otherwise derived classes which use this
1214        #may come a cropper when the current directory changes
1215        self.baseFilename = os.path.abspath(filename)
1216        self.mode = mode
1217        self.encoding = encoding
1218        if "b" not in mode:
1219            self.encoding = io.text_encoding(encoding)
1220        self.errors = errors
1221        self.delay = delay
1222        # bpo-26789: FileHandler keeps a reference to the builtin open()
1223        # function to be able to open or reopen the file during Python
1224        # finalization.
1225        self._builtin_open = open
1226        if delay:
1227            #We don't open the stream, but we still need to call the
1228            #Handler constructor to set level, formatter, lock etc.
1229            Handler.__init__(self)
1230            self.stream = None
1231        else:
1232            StreamHandler.__init__(self, self._open())
1233
1234    def close(self):
1235        """
1236        Closes the stream.
1237        """
1238        self.acquire()
1239        try:
1240            try:
1241                if self.stream:
1242                    try:
1243                        self.flush()
1244                    finally:
1245                        stream = self.stream
1246                        self.stream = None
1247                        if hasattr(stream, "close"):
1248                            stream.close()
1249            finally:
1250                # Issue #19523: call unconditionally to
1251                # prevent a handler leak when delay is set
1252                # Also see Issue #42378: we also rely on
1253                # self._closed being set to True there
1254                StreamHandler.close(self)
1255        finally:
1256            self.release()
1257
1258    def _open(self):
1259        """
1260        Open the current base file with the (original) mode and encoding.
1261        Return the resulting stream.
1262        """
1263        open_func = self._builtin_open
1264        return open_func(self.baseFilename, self.mode,
1265                         encoding=self.encoding, errors=self.errors)
1266
1267    def emit(self, record):
1268        """
1269        Emit a record.
1270
1271        If the stream was not opened because 'delay' was specified in the
1272        constructor, open it before calling the superclass's emit.
1273
1274        If stream is not open, current mode is 'w' and `_closed=True`, record
1275        will not be emitted (see Issue #42378).
1276        """
1277        if self.stream is None:
1278            if self.mode != 'w' or not self._closed:
1279                self.stream = self._open()
1280        if self.stream:
1281            StreamHandler.emit(self, record)
1282
1283    def __repr__(self):
1284        level = getLevelName(self.level)
1285        return '<%s %s (%s)>' % (self.__class__.__name__, self.baseFilename, level)

A handler class which writes formatted logging records to disk files.

FileHandler(filename, mode='a', encoding=None, delay=False, errors=None)
1207    def __init__(self, filename, mode='a', encoding=None, delay=False, errors=None):
1208        """
1209        Open the specified file and use it as the stream for logging.
1210        """
1211        # Issue #27493: add support for Path objects to be passed in
1212        filename = os.fspath(filename)
1213        #keep the absolute path, otherwise derived classes which use this
1214        #may come a cropper when the current directory changes
1215        self.baseFilename = os.path.abspath(filename)
1216        self.mode = mode
1217        self.encoding = encoding
1218        if "b" not in mode:
1219            self.encoding = io.text_encoding(encoding)
1220        self.errors = errors
1221        self.delay = delay
1222        # bpo-26789: FileHandler keeps a reference to the builtin open()
1223        # function to be able to open or reopen the file during Python
1224        # finalization.
1225        self._builtin_open = open
1226        if delay:
1227            #We don't open the stream, but we still need to call the
1228            #Handler constructor to set level, formatter, lock etc.
1229            Handler.__init__(self)
1230            self.stream = None
1231        else:
1232            StreamHandler.__init__(self, self._open())

Open the specified file and use it as the stream for logging.

baseFilename
mode
encoding
errors
delay
def close(self):
1234    def close(self):
1235        """
1236        Closes the stream.
1237        """
1238        self.acquire()
1239        try:
1240            try:
1241                if self.stream:
1242                    try:
1243                        self.flush()
1244                    finally:
1245                        stream = self.stream
1246                        self.stream = None
1247                        if hasattr(stream, "close"):
1248                            stream.close()
1249            finally:
1250                # Issue #19523: call unconditionally to
1251                # prevent a handler leak when delay is set
1252                # Also see Issue #42378: we also rely on
1253                # self._closed being set to True there
1254                StreamHandler.close(self)
1255        finally:
1256            self.release()

Closes the stream.

def emit(self, record):
1267    def emit(self, record):
1268        """
1269        Emit a record.
1270
1271        If the stream was not opened because 'delay' was specified in the
1272        constructor, open it before calling the superclass's emit.
1273
1274        If stream is not open, current mode is 'w' and `_closed=True`, record
1275        will not be emitted (see Issue #42378).
1276        """
1277        if self.stream is None:
1278            if self.mode != 'w' or not self._closed:
1279                self.stream = self._open()
1280        if self.stream:
1281            StreamHandler.emit(self, record)

Emit a record.

If the stream was not opened because 'delay' was specified in the constructor, open it before calling the superclass's emit.

If stream is not open, current mode is 'w' and _closed=True, record will not be emitted (see Issue #42378).

class Filter:
770class Filter(object):
771    """
772    Filter instances are used to perform arbitrary filtering of LogRecords.
773
774    Loggers and Handlers can optionally use Filter instances to filter
775    records as desired. The base filter class only allows events which are
776    below a certain point in the logger hierarchy. For example, a filter
777    initialized with "A.B" will allow events logged by loggers "A.B",
778    "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
779    initialized with the empty string, all events are passed.
780    """
781    def __init__(self, name=''):
782        """
783        Initialize a filter.
784
785        Initialize with the name of the logger which, together with its
786        children, will have its events allowed through the filter. If no
787        name is specified, allow every event.
788        """
789        self.name = name
790        self.nlen = len(name)
791
792    def filter(self, record):
793        """
794        Determine if the specified record is to be logged.
795
796        Returns True if the record should be logged, or False otherwise.
797        If deemed appropriate, the record may be modified in-place.
798        """
799        if self.nlen == 0:
800            return True
801        elif self.name == record.name:
802            return True
803        elif record.name.find(self.name, 0, self.nlen) != 0:
804            return False
805        return (record.name[self.nlen] == ".")

Filter instances are used to perform arbitrary filtering of LogRecords.

Loggers and Handlers can optionally use Filter instances to filter records as desired. The base filter class only allows events which are below a certain point in the logger hierarchy. For example, a filter initialized with "A.B" will allow events logged by loggers "A.B", "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If initialized with the empty string, all events are passed.

Filter(name='')
781    def __init__(self, name=''):
782        """
783        Initialize a filter.
784
785        Initialize with the name of the logger which, together with its
786        children, will have its events allowed through the filter. If no
787        name is specified, allow every event.
788        """
789        self.name = name
790        self.nlen = len(name)

Initialize a filter.

Initialize with the name of the logger which, together with its children, will have its events allowed through the filter. If no name is specified, allow every event.

name
nlen
def filter(self, record):
792    def filter(self, record):
793        """
794        Determine if the specified record is to be logged.
795
796        Returns True if the record should be logged, or False otherwise.
797        If deemed appropriate, the record may be modified in-place.
798        """
799        if self.nlen == 0:
800            return True
801        elif self.name == record.name:
802            return True
803        elif record.name.find(self.name, 0, self.nlen) != 0:
804            return False
805        return (record.name[self.nlen] == ".")

Determine if the specified record is to be logged.

Returns True if the record should be logged, or False otherwise. If deemed appropriate, the record may be modified in-place.

class Formatter:
547class Formatter(object):
548    """
549    Formatter instances are used to convert a LogRecord to text.
550
551    Formatters need to know how a LogRecord is constructed. They are
552    responsible for converting a LogRecord to (usually) a string which can
553    be interpreted by either a human or an external system. The base Formatter
554    allows a formatting string to be specified. If none is supplied, the
555    style-dependent default value, "%(message)s", "{message}", or
556    "${message}", is used.
557
558    The Formatter can be initialized with a format string which makes use of
559    knowledge of the LogRecord attributes - e.g. the default value mentioned
560    above makes use of the fact that the user's message and arguments are pre-
561    formatted into a LogRecord's message attribute. Currently, the useful
562    attributes in a LogRecord are described by:
563
564    %(name)s            Name of the logger (logging channel)
565    %(levelno)s         Numeric logging level for the message (DEBUG, INFO,
566                        WARNING, ERROR, CRITICAL)
567    %(levelname)s       Text logging level for the message ("DEBUG", "INFO",
568                        "WARNING", "ERROR", "CRITICAL")
569    %(pathname)s        Full pathname of the source file where the logging
570                        call was issued (if available)
571    %(filename)s        Filename portion of pathname
572    %(module)s          Module (name portion of filename)
573    %(lineno)d          Source line number where the logging call was issued
574                        (if available)
575    %(funcName)s        Function name
576    %(created)f         Time when the LogRecord was created (time.time()
577                        return value)
578    %(asctime)s         Textual time when the LogRecord was created
579    %(msecs)d           Millisecond portion of the creation time
580    %(relativeCreated)d Time in milliseconds when the LogRecord was created,
581                        relative to the time the logging module was loaded
582                        (typically at application startup time)
583    %(thread)d          Thread ID (if available)
584    %(threadName)s      Thread name (if available)
585    %(taskName)s        Task name (if available)
586    %(process)d         Process ID (if available)
587    %(message)s         The result of record.getMessage(), computed just as
588                        the record is emitted
589    """
590
591    converter = time.localtime
592
593    def __init__(self, fmt=None, datefmt=None, style='%', validate=True, *,
594                 defaults=None):
595        """
596        Initialize the formatter with specified format strings.
597
598        Initialize the formatter either with the specified format string, or a
599        default as described above. Allow for specialized date formatting with
600        the optional datefmt argument. If datefmt is omitted, you get an
601        ISO8601-like (or RFC 3339-like) format.
602
603        Use a style parameter of '%', '{' or '$' to specify that you want to
604        use one of %-formatting, :meth:`str.format` (``{}``) formatting or
605        :class:`string.Template` formatting in your format string.
606
607        .. versionchanged:: 3.2
608           Added the ``style`` parameter.
609        """
610        if style not in _STYLES:
611            raise ValueError('Style must be one of: %s' % ','.join(
612                             _STYLES.keys()))
613        self._style = _STYLES[style][0](fmt, defaults=defaults)
614        if validate:
615            self._style.validate()
616
617        self._fmt = self._style._fmt
618        self.datefmt = datefmt
619
620    default_time_format = '%Y-%m-%d %H:%M:%S'
621    default_msec_format = '%s,%03d'
622
623    def formatTime(self, record, datefmt=None):
624        """
625        Return the creation time of the specified LogRecord as formatted text.
626
627        This method should be called from format() by a formatter which
628        wants to make use of a formatted time. This method can be overridden
629        in formatters to provide for any specific requirement, but the
630        basic behaviour is as follows: if datefmt (a string) is specified,
631        it is used with time.strftime() to format the creation time of the
632        record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used.
633        The resulting string is returned. This function uses a user-configurable
634        function to convert the creation time to a tuple. By default,
635        time.localtime() is used; to change this for a particular formatter
636        instance, set the 'converter' attribute to a function with the same
637        signature as time.localtime() or time.gmtime(). To change it for all
638        formatters, for example if you want all logging times to be shown in GMT,
639        set the 'converter' attribute in the Formatter class.
640        """
641        ct = self.converter(record.created)
642        if datefmt:
643            s = time.strftime(datefmt, ct)
644        else:
645            s = time.strftime(self.default_time_format, ct)
646            if self.default_msec_format:
647                s = self.default_msec_format % (s, record.msecs)
648        return s
649
650    def formatException(self, ei):
651        """
652        Format and return the specified exception information as a string.
653
654        This default implementation just uses
655        traceback.print_exception()
656        """
657        sio = io.StringIO()
658        tb = ei[2]
659        # See issues #9427, #1553375. Commented out for now.
660        #if getattr(self, 'fullstack', False):
661        #    traceback.print_stack(tb.tb_frame.f_back, file=sio)
662        traceback.print_exception(ei[0], ei[1], tb, None, sio)
663        s = sio.getvalue()
664        sio.close()
665        if s[-1:] == "\n":
666            s = s[:-1]
667        return s
668
669    def usesTime(self):
670        """
671        Check if the format uses the creation time of the record.
672        """
673        return self._style.usesTime()
674
675    def formatMessage(self, record):
676        return self._style.format(record)
677
678    def formatStack(self, stack_info):
679        """
680        This method is provided as an extension point for specialized
681        formatting of stack information.
682
683        The input data is a string as returned from a call to
684        :func:`traceback.print_stack`, but with the last trailing newline
685        removed.
686
687        The base implementation just returns the value passed in.
688        """
689        return stack_info
690
691    def format(self, record):
692        """
693        Format the specified record as text.
694
695        The record's attribute dictionary is used as the operand to a
696        string formatting operation which yields the returned string.
697        Before formatting the dictionary, a couple of preparatory steps
698        are carried out. The message attribute of the record is computed
699        using LogRecord.getMessage(). If the formatting string uses the
700        time (as determined by a call to usesTime(), formatTime() is
701        called to format the event time. If there is exception information,
702        it is formatted using formatException() and appended to the message.
703        """
704        record.message = record.getMessage()
705        if self.usesTime():
706            record.asctime = self.formatTime(record, self.datefmt)
707        s = self.formatMessage(record)
708        if record.exc_info:
709            # Cache the traceback text to avoid converting it multiple times
710            # (it's constant anyway)
711            if not record.exc_text:
712                record.exc_text = self.formatException(record.exc_info)
713        if record.exc_text:
714            if s[-1:] != "\n":
715                s = s + "\n"
716            s = s + record.exc_text
717        if record.stack_info:
718            if s[-1:] != "\n":
719                s = s + "\n"
720            s = s + self.formatStack(record.stack_info)
721        return s

Formatter instances are used to convert a LogRecord to text.

Formatters need to know how a LogRecord is constructed. They are responsible for converting a LogRecord to (usually) a string which can be interpreted by either a human or an external system. The base Formatter allows a formatting string to be specified. If none is supplied, the style-dependent default value, "%(message)s", "{message}", or "${message}", is used.

The Formatter can be initialized with a format string which makes use of knowledge of the LogRecord attributes - e.g. the default value mentioned above makes use of the fact that the user's message and arguments are pre- formatted into a LogRecord's message attribute. Currently, the useful attributes in a LogRecord are described by:

%(name)s Name of the logger (logging channel) %(levelno)s Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL) %(levelname)s Text logging level for the message ("DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL") %(pathname)s Full pathname of the source file where the logging call was issued (if available) %(filename)s Filename portion of pathname %(module)s Module (name portion of filename) %(lineno)d Source line number where the logging call was issued (if available) %(funcName)s Function name %(created)f Time when the LogRecord was created (time.time() return value) %(asctime)s Textual time when the LogRecord was created %(msecs)d Millisecond portion of the creation time %(relativeCreated)d Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded (typically at application startup time) %(thread)d Thread ID (if available) %(threadName)s Thread name (if available) %(taskName)s Task name (if available) %(process)d Process ID (if available) %(message)s The result of record.getMessage(), computed just as the record is emitted

Formatter(fmt=None, datefmt=None, style='%', validate=True, *, defaults=None)
593    def __init__(self, fmt=None, datefmt=None, style='%', validate=True, *,
594                 defaults=None):
595        """
596        Initialize the formatter with specified format strings.
597
598        Initialize the formatter either with the specified format string, or a
599        default as described above. Allow for specialized date formatting with
600        the optional datefmt argument. If datefmt is omitted, you get an
601        ISO8601-like (or RFC 3339-like) format.
602
603        Use a style parameter of '%', '{' or '$' to specify that you want to
604        use one of %-formatting, :meth:`str.format` (``{}``) formatting or
605        :class:`string.Template` formatting in your format string.
606
607        .. versionchanged:: 3.2
608           Added the ``style`` parameter.
609        """
610        if style not in _STYLES:
611            raise ValueError('Style must be one of: %s' % ','.join(
612                             _STYLES.keys()))
613        self._style = _STYLES[style][0](fmt, defaults=defaults)
614        if validate:
615            self._style.validate()
616
617        self._fmt = self._style._fmt
618        self.datefmt = datefmt

Initialize the formatter with specified format strings.

Initialize the formatter either with the specified format string, or a default as described above. Allow for specialized date formatting with the optional datefmt argument. If datefmt is omitted, you get an ISO8601-like (or RFC 3339-like) format.

Use a style parameter of '%', '{' or '$' to specify that you want to use one of %-formatting, str.format() ({}) formatting or string.Template formatting in your format string.

Changed in version 3.2: Added the style parameter.

def converter(unknown):

localtime([seconds]) -> (tm_year,tm_mon,tm_mday,tm_hour,tm_min, tm_sec,tm_wday,tm_yday,tm_isdst)

Convert seconds since the Epoch to a time tuple expressing local time. When 'seconds' is not passed in, convert the current time instead.

datefmt
default_time_format = '%Y-%m-%d %H:%M:%S'
default_msec_format = '%s,%03d'
def formatTime(self, record, datefmt=None):
623    def formatTime(self, record, datefmt=None):
624        """
625        Return the creation time of the specified LogRecord as formatted text.
626
627        This method should be called from format() by a formatter which
628        wants to make use of a formatted time. This method can be overridden
629        in formatters to provide for any specific requirement, but the
630        basic behaviour is as follows: if datefmt (a string) is specified,
631        it is used with time.strftime() to format the creation time of the
632        record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used.
633        The resulting string is returned. This function uses a user-configurable
634        function to convert the creation time to a tuple. By default,
635        time.localtime() is used; to change this for a particular formatter
636        instance, set the 'converter' attribute to a function with the same
637        signature as time.localtime() or time.gmtime(). To change it for all
638        formatters, for example if you want all logging times to be shown in GMT,
639        set the 'converter' attribute in the Formatter class.
640        """
641        ct = self.converter(record.created)
642        if datefmt:
643            s = time.strftime(datefmt, ct)
644        else:
645            s = time.strftime(self.default_time_format, ct)
646            if self.default_msec_format:
647                s = self.default_msec_format % (s, record.msecs)
648        return s

Return the creation time of the specified LogRecord as formatted text.

This method should be called from format() by a formatter which wants to make use of a formatted time. This method can be overridden in formatters to provide for any specific requirement, but the basic behaviour is as follows: if datefmt (a string) is specified, it is used with time.strftime() to format the creation time of the record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used. The resulting string is returned. This function uses a user-configurable function to convert the creation time to a tuple. By default, time.localtime() is used; to change this for a particular formatter instance, set the 'converter' attribute to a function with the same signature as time.localtime() or time.gmtime(). To change it for all formatters, for example if you want all logging times to be shown in GMT, set the 'converter' attribute in the Formatter class.

def formatException(self, ei):
650    def formatException(self, ei):
651        """
652        Format and return the specified exception information as a string.
653
654        This default implementation just uses
655        traceback.print_exception()
656        """
657        sio = io.StringIO()
658        tb = ei[2]
659        # See issues #9427, #1553375. Commented out for now.
660        #if getattr(self, 'fullstack', False):
661        #    traceback.print_stack(tb.tb_frame.f_back, file=sio)
662        traceback.print_exception(ei[0], ei[1], tb, None, sio)
663        s = sio.getvalue()
664        sio.close()
665        if s[-1:] == "\n":
666            s = s[:-1]
667        return s

Format and return the specified exception information as a string.

This default implementation just uses traceback.print_exception()

def usesTime(self):
669    def usesTime(self):
670        """
671        Check if the format uses the creation time of the record.
672        """
673        return self._style.usesTime()

Check if the format uses the creation time of the record.

def formatMessage(self, record):
675    def formatMessage(self, record):
676        return self._style.format(record)
def formatStack(self, stack_info):
678    def formatStack(self, stack_info):
679        """
680        This method is provided as an extension point for specialized
681        formatting of stack information.
682
683        The input data is a string as returned from a call to
684        :func:`traceback.print_stack`, but with the last trailing newline
685        removed.
686
687        The base implementation just returns the value passed in.
688        """
689        return stack_info

This method is provided as an extension point for specialized formatting of stack information.

The input data is a string as returned from a call to traceback.print_stack(), but with the last trailing newline removed.

The base implementation just returns the value passed in.

def format(self, record):
691    def format(self, record):
692        """
693        Format the specified record as text.
694
695        The record's attribute dictionary is used as the operand to a
696        string formatting operation which yields the returned string.
697        Before formatting the dictionary, a couple of preparatory steps
698        are carried out. The message attribute of the record is computed
699        using LogRecord.getMessage(). If the formatting string uses the
700        time (as determined by a call to usesTime(), formatTime() is
701        called to format the event time. If there is exception information,
702        it is formatted using formatException() and appended to the message.
703        """
704        record.message = record.getMessage()
705        if self.usesTime():
706            record.asctime = self.formatTime(record, self.datefmt)
707        s = self.formatMessage(record)
708        if record.exc_info:
709            # Cache the traceback text to avoid converting it multiple times
710            # (it's constant anyway)
711            if not record.exc_text:
712                record.exc_text = self.formatException(record.exc_info)
713        if record.exc_text:
714            if s[-1:] != "\n":
715                s = s + "\n"
716            s = s + record.exc_text
717        if record.stack_info:
718            if s[-1:] != "\n":
719                s = s + "\n"
720            s = s + self.formatStack(record.stack_info)
721        return s

Format the specified record as text.

The record's attribute dictionary is used as the operand to a string formatting operation which yields the returned string. Before formatting the dictionary, a couple of preparatory steps are carried out. The message attribute of the record is computed using LogRecord.getMessage(). If the formatting string uses the time (as determined by a call to usesTime(), formatTime() is called to format the event time. If there is exception information, it is formatted using formatException() and appended to the message.

class Handler(Filterer):
 920class Handler(Filterer):
 921    """
 922    Handler instances dispatch logging events to specific destinations.
 923
 924    The base handler class. Acts as a placeholder which defines the Handler
 925    interface. Handlers can optionally use Formatter instances to format
 926    records as desired. By default, no formatter is specified; in this case,
 927    the 'raw' message as determined by record.message is logged.
 928    """
 929    def __init__(self, level=NOTSET):
 930        """
 931        Initializes the instance - basically setting the formatter to None
 932        and the filter list to empty.
 933        """
 934        Filterer.__init__(self)
 935        self._name = None
 936        self.level = _checkLevel(level)
 937        self.formatter = None
 938        self._closed = False
 939        # Add the handler to the global _handlerList (for cleanup on shutdown)
 940        _addHandlerRef(self)
 941        self.createLock()
 942
 943    def get_name(self):
 944        return self._name
 945
 946    def set_name(self, name):
 947        _acquireLock()
 948        try:
 949            if self._name in _handlers:
 950                del _handlers[self._name]
 951            self._name = name
 952            if name:
 953                _handlers[name] = self
 954        finally:
 955            _releaseLock()
 956
 957    name = property(get_name, set_name)
 958
 959    def createLock(self):
 960        """
 961        Acquire a thread lock for serializing access to the underlying I/O.
 962        """
 963        self.lock = threading.RLock()
 964        _register_at_fork_reinit_lock(self)
 965
 966    def _at_fork_reinit(self):
 967        self.lock._at_fork_reinit()
 968
 969    def acquire(self):
 970        """
 971        Acquire the I/O thread lock.
 972        """
 973        if self.lock:
 974            self.lock.acquire()
 975
 976    def release(self):
 977        """
 978        Release the I/O thread lock.
 979        """
 980        if self.lock:
 981            self.lock.release()
 982
 983    def setLevel(self, level):
 984        """
 985        Set the logging level of this handler.  level must be an int or a str.
 986        """
 987        self.level = _checkLevel(level)
 988
 989    def format(self, record):
 990        """
 991        Format the specified record.
 992
 993        If a formatter is set, use it. Otherwise, use the default formatter
 994        for the module.
 995        """
 996        if self.formatter:
 997            fmt = self.formatter
 998        else:
 999            fmt = _defaultFormatter
1000        return fmt.format(record)
1001
1002    def emit(self, record):
1003        """
1004        Do whatever it takes to actually log the specified logging record.
1005
1006        This version is intended to be implemented by subclasses and so
1007        raises a NotImplementedError.
1008        """
1009        raise NotImplementedError('emit must be implemented '
1010                                  'by Handler subclasses')
1011
1012    def handle(self, record):
1013        """
1014        Conditionally emit the specified logging record.
1015
1016        Emission depends on filters which may have been added to the handler.
1017        Wrap the actual emission of the record with acquisition/release of
1018        the I/O thread lock.
1019
1020        Returns an instance of the log record that was emitted
1021        if it passed all filters, otherwise a false value is returned.
1022        """
1023        rv = self.filter(record)
1024        if isinstance(rv, LogRecord):
1025            record = rv
1026        if rv:
1027            self.acquire()
1028            try:
1029                self.emit(record)
1030            finally:
1031                self.release()
1032        return rv
1033
1034    def setFormatter(self, fmt):
1035        """
1036        Set the formatter for this handler.
1037        """
1038        self.formatter = fmt
1039
1040    def flush(self):
1041        """
1042        Ensure all logging output has been flushed.
1043
1044        This version does nothing and is intended to be implemented by
1045        subclasses.
1046        """
1047        pass
1048
1049    def close(self):
1050        """
1051        Tidy up any resources used by the handler.
1052
1053        This version removes the handler from an internal map of handlers,
1054        _handlers, which is used for handler lookup by name. Subclasses
1055        should ensure that this gets called from overridden close()
1056        methods.
1057        """
1058        #get the module data lock, as we're updating a shared structure.
1059        _acquireLock()
1060        try:    #unlikely to raise an exception, but you never know...
1061            self._closed = True
1062            if self._name and self._name in _handlers:
1063                del _handlers[self._name]
1064        finally:
1065            _releaseLock()
1066
1067    def handleError(self, record):
1068        """
1069        Handle errors which occur during an emit() call.
1070
1071        This method should be called from handlers when an exception is
1072        encountered during an emit() call. If raiseExceptions is false,
1073        exceptions get silently ignored. This is what is mostly wanted
1074        for a logging system - most users will not care about errors in
1075        the logging system, they are more interested in application errors.
1076        You could, however, replace this with a custom handler if you wish.
1077        The record which was being processed is passed in to this method.
1078        """
1079        if raiseExceptions and sys.stderr:  # see issue 13807
1080            t, v, tb = sys.exc_info()
1081            try:
1082                sys.stderr.write('--- Logging error ---\n')
1083                traceback.print_exception(t, v, tb, None, sys.stderr)
1084                sys.stderr.write('Call stack:\n')
1085                # Walk the stack frame up until we're out of logging,
1086                # so as to print the calling context.
1087                frame = tb.tb_frame
1088                while (frame and os.path.dirname(frame.f_code.co_filename) ==
1089                       __path__[0]):
1090                    frame = frame.f_back
1091                if frame:
1092                    traceback.print_stack(frame, file=sys.stderr)
1093                else:
1094                    # couldn't find the right stack frame, for some reason
1095                    sys.stderr.write('Logged from file %s, line %s\n' % (
1096                                     record.filename, record.lineno))
1097                # Issue 18671: output logging message and arguments
1098                try:
1099                    sys.stderr.write('Message: %r\n'
1100                                     'Arguments: %s\n' % (record.msg,
1101                                                          record.args))
1102                except RecursionError:  # See issue 36272
1103                    raise
1104                except Exception:
1105                    sys.stderr.write('Unable to print the message and arguments'
1106                                     ' - possible formatting error.\nUse the'
1107                                     ' traceback above to help find the error.\n'
1108                                    )
1109            except OSError: #pragma: no cover
1110                pass    # see issue 5971
1111            finally:
1112                del t, v, tb
1113
1114    def __repr__(self):
1115        level = getLevelName(self.level)
1116        return '<%s (%s)>' % (self.__class__.__name__, level)

Handler instances dispatch logging events to specific destinations.

The base handler class. Acts as a placeholder which defines the Handler interface. Handlers can optionally use Formatter instances to format records as desired. By default, no formatter is specified; in this case, the 'raw' message as determined by record.message is logged.

Handler(level=0)
929    def __init__(self, level=NOTSET):
930        """
931        Initializes the instance - basically setting the formatter to None
932        and the filter list to empty.
933        """
934        Filterer.__init__(self)
935        self._name = None
936        self.level = _checkLevel(level)
937        self.formatter = None
938        self._closed = False
939        # Add the handler to the global _handlerList (for cleanup on shutdown)
940        _addHandlerRef(self)
941        self.createLock()

Initializes the instance - basically setting the formatter to None and the filter list to empty.

level
formatter
def get_name(self):
943    def get_name(self):
944        return self._name
def set_name(self, name):
946    def set_name(self, name):
947        _acquireLock()
948        try:
949            if self._name in _handlers:
950                del _handlers[self._name]
951            self._name = name
952            if name:
953                _handlers[name] = self
954        finally:
955            _releaseLock()
name
943    def get_name(self):
944        return self._name
def createLock(self):
959    def createLock(self):
960        """
961        Acquire a thread lock for serializing access to the underlying I/O.
962        """
963        self.lock = threading.RLock()
964        _register_at_fork_reinit_lock(self)

Acquire a thread lock for serializing access to the underlying I/O.

def acquire(self):
969    def acquire(self):
970        """
971        Acquire the I/O thread lock.
972        """
973        if self.lock:
974            self.lock.acquire()

Acquire the I/O thread lock.

def release(self):
976    def release(self):
977        """
978        Release the I/O thread lock.
979        """
980        if self.lock:
981            self.lock.release()

Release the I/O thread lock.

def setLevel(self, level):
983    def setLevel(self, level):
984        """
985        Set the logging level of this handler.  level must be an int or a str.
986        """
987        self.level = _checkLevel(level)

Set the logging level of this handler. level must be an int or a str.

def format(self, record):
 989    def format(self, record):
 990        """
 991        Format the specified record.
 992
 993        If a formatter is set, use it. Otherwise, use the default formatter
 994        for the module.
 995        """
 996        if self.formatter:
 997            fmt = self.formatter
 998        else:
 999            fmt = _defaultFormatter
1000        return fmt.format(record)

Format the specified record.

If a formatter is set, use it. Otherwise, use the default formatter for the module.

def emit(self, record):
1002    def emit(self, record):
1003        """
1004        Do whatever it takes to actually log the specified logging record.
1005
1006        This version is intended to be implemented by subclasses and so
1007        raises a NotImplementedError.
1008        """
1009        raise NotImplementedError('emit must be implemented '
1010                                  'by Handler subclasses')

Do whatever it takes to actually log the specified logging record.

This version is intended to be implemented by subclasses and so raises a NotImplementedError.

def handle(self, record):
1012    def handle(self, record):
1013        """
1014        Conditionally emit the specified logging record.
1015
1016        Emission depends on filters which may have been added to the handler.
1017        Wrap the actual emission of the record with acquisition/release of
1018        the I/O thread lock.
1019
1020        Returns an instance of the log record that was emitted
1021        if it passed all filters, otherwise a false value is returned.
1022        """
1023        rv = self.filter(record)
1024        if isinstance(rv, LogRecord):
1025            record = rv
1026        if rv:
1027            self.acquire()
1028            try:
1029                self.emit(record)
1030            finally:
1031                self.release()
1032        return rv

Conditionally emit the specified logging record.

Emission depends on filters which may have been added to the handler. Wrap the actual emission of the record with acquisition/release of the I/O thread lock.

Returns an instance of the log record that was emitted if it passed all filters, otherwise a false value is returned.

def setFormatter(self, fmt):
1034    def setFormatter(self, fmt):
1035        """
1036        Set the formatter for this handler.
1037        """
1038        self.formatter = fmt

Set the formatter for this handler.

def flush(self):
1040    def flush(self):
1041        """
1042        Ensure all logging output has been flushed.
1043
1044        This version does nothing and is intended to be implemented by
1045        subclasses.
1046        """
1047        pass

Ensure all logging output has been flushed.

This version does nothing and is intended to be implemented by subclasses.

def close(self):
1049    def close(self):
1050        """
1051        Tidy up any resources used by the handler.
1052
1053        This version removes the handler from an internal map of handlers,
1054        _handlers, which is used for handler lookup by name. Subclasses
1055        should ensure that this gets called from overridden close()
1056        methods.
1057        """
1058        #get the module data lock, as we're updating a shared structure.
1059        _acquireLock()
1060        try:    #unlikely to raise an exception, but you never know...
1061            self._closed = True
1062            if self._name and self._name in _handlers:
1063                del _handlers[self._name]
1064        finally:
1065            _releaseLock()

Tidy up any resources used by the handler.

This version removes the handler from an internal map of handlers, _handlers, which is used for handler lookup by name. Subclasses should ensure that this gets called from overridden close() methods.

def handleError(self, record):
1067    def handleError(self, record):
1068        """
1069        Handle errors which occur during an emit() call.
1070
1071        This method should be called from handlers when an exception is
1072        encountered during an emit() call. If raiseExceptions is false,
1073        exceptions get silently ignored. This is what is mostly wanted
1074        for a logging system - most users will not care about errors in
1075        the logging system, they are more interested in application errors.
1076        You could, however, replace this with a custom handler if you wish.
1077        The record which was being processed is passed in to this method.
1078        """
1079        if raiseExceptions and sys.stderr:  # see issue 13807
1080            t, v, tb = sys.exc_info()
1081            try:
1082                sys.stderr.write('--- Logging error ---\n')
1083                traceback.print_exception(t, v, tb, None, sys.stderr)
1084                sys.stderr.write('Call stack:\n')
1085                # Walk the stack frame up until we're out of logging,
1086                # so as to print the calling context.
1087                frame = tb.tb_frame
1088                while (frame and os.path.dirname(frame.f_code.co_filename) ==
1089                       __path__[0]):
1090                    frame = frame.f_back
1091                if frame:
1092                    traceback.print_stack(frame, file=sys.stderr)
1093                else:
1094                    # couldn't find the right stack frame, for some reason
1095                    sys.stderr.write('Logged from file %s, line %s\n' % (
1096                                     record.filename, record.lineno))
1097                # Issue 18671: output logging message and arguments
1098                try:
1099                    sys.stderr.write('Message: %r\n'
1100                                     'Arguments: %s\n' % (record.msg,
1101                                                          record.args))
1102                except RecursionError:  # See issue 36272
1103                    raise
1104                except Exception:
1105                    sys.stderr.write('Unable to print the message and arguments'
1106                                     ' - possible formatting error.\nUse the'
1107                                     ' traceback above to help find the error.\n'
1108                                    )
1109            except OSError: #pragma: no cover
1110                pass    # see issue 5971
1111            finally:
1112                del t, v, tb

Handle errors which occur during an emit() call.

This method should be called from handlers when an exception is encountered during an emit() call. If raiseExceptions is false, exceptions get silently ignored. This is what is mostly wanted for a logging system - most users will not care about errors in the logging system, they are more interested in application errors. You could, however, replace this with a custom handler if you wish. The record which was being processed is passed in to this method.

INFO = 20
class LogRecord:
287class LogRecord(object):
288    """
289    A LogRecord instance represents an event being logged.
290
291    LogRecord instances are created every time something is logged. They
292    contain all the information pertinent to the event being logged. The
293    main information passed in is in msg and args, which are combined
294    using str(msg) % args to create the message field of the record. The
295    record also includes information such as when the record was created,
296    the source line where the logging call was made, and any exception
297    information to be logged.
298    """
299    def __init__(self, name, level, pathname, lineno,
300                 msg, args, exc_info, func=None, sinfo=None, **kwargs):
301        """
302        Initialize a logging record with interesting information.
303        """
304        ct = time.time()
305        self.name = name
306        self.msg = msg
307        #
308        # The following statement allows passing of a dictionary as a sole
309        # argument, so that you can do something like
310        #  logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
311        # Suggested by Stefan Behnel.
312        # Note that without the test for args[0], we get a problem because
313        # during formatting, we test to see if the arg is present using
314        # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
315        # and if the passed arg fails 'if self.args:' then no formatting
316        # is done. For example, logger.warning('Value is %d', 0) would log
317        # 'Value is %d' instead of 'Value is 0'.
318        # For the use case of passing a dictionary, this should not be a
319        # problem.
320        # Issue #21172: a request was made to relax the isinstance check
321        # to hasattr(args[0], '__getitem__'). However, the docs on string
322        # formatting still seem to suggest a mapping object is required.
323        # Thus, while not removing the isinstance check, it does now look
324        # for collections.abc.Mapping rather than, as before, dict.
325        if (args and len(args) == 1 and isinstance(args[0], collections.abc.Mapping)
326            and args[0]):
327            args = args[0]
328        self.args = args
329        self.levelname = getLevelName(level)
330        self.levelno = level
331        self.pathname = pathname
332        try:
333            self.filename = os.path.basename(pathname)
334            self.module = os.path.splitext(self.filename)[0]
335        except (TypeError, ValueError, AttributeError):
336            self.filename = pathname
337            self.module = "Unknown module"
338        self.exc_info = exc_info
339        self.exc_text = None      # used to cache the traceback text
340        self.stack_info = sinfo
341        self.lineno = lineno
342        self.funcName = func
343        self.created = ct
344        self.msecs = int((ct - int(ct)) * 1000) + 0.0  # see gh-89047
345        self.relativeCreated = (self.created - _startTime) * 1000
346        if logThreads:
347            self.thread = threading.get_ident()
348            self.threadName = threading.current_thread().name
349        else: # pragma: no cover
350            self.thread = None
351            self.threadName = None
352        if not logMultiprocessing: # pragma: no cover
353            self.processName = None
354        else:
355            self.processName = 'MainProcess'
356            mp = sys.modules.get('multiprocessing')
357            if mp is not None:
358                # Errors may occur if multiprocessing has not finished loading
359                # yet - e.g. if a custom import hook causes third-party code
360                # to run when multiprocessing calls import. See issue 8200
361                # for an example
362                try:
363                    self.processName = mp.current_process().name
364                except Exception: #pragma: no cover
365                    pass
366        if logProcesses and hasattr(os, 'getpid'):
367            self.process = os.getpid()
368        else:
369            self.process = None
370
371        self.taskName = None
372        if logAsyncioTasks:
373            asyncio = sys.modules.get('asyncio')
374            if asyncio:
375                try:
376                    self.taskName = asyncio.current_task().get_name()
377                except Exception:
378                    pass
379
380    def __repr__(self):
381        return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
382            self.pathname, self.lineno, self.msg)
383
384    def getMessage(self):
385        """
386        Return the message for this LogRecord.
387
388        Return the message for this LogRecord after merging any user-supplied
389        arguments with the message.
390        """
391        msg = str(self.msg)
392        if self.args:
393            msg = msg % self.args
394        return msg

A LogRecord instance represents an event being logged.

LogRecord instances are created every time something is logged. They contain all the information pertinent to the event being logged. The main information passed in is in msg and args, which are combined using str(msg) % args to create the message field of the record. The record also includes information such as when the record was created, the source line where the logging call was made, and any exception information to be logged.

LogRecord( name, level, pathname, lineno, msg, args, exc_info, func=None, sinfo=None, **kwargs)
299    def __init__(self, name, level, pathname, lineno,
300                 msg, args, exc_info, func=None, sinfo=None, **kwargs):
301        """
302        Initialize a logging record with interesting information.
303        """
304        ct = time.time()
305        self.name = name
306        self.msg = msg
307        #
308        # The following statement allows passing of a dictionary as a sole
309        # argument, so that you can do something like
310        #  logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
311        # Suggested by Stefan Behnel.
312        # Note that without the test for args[0], we get a problem because
313        # during formatting, we test to see if the arg is present using
314        # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
315        # and if the passed arg fails 'if self.args:' then no formatting
316        # is done. For example, logger.warning('Value is %d', 0) would log
317        # 'Value is %d' instead of 'Value is 0'.
318        # For the use case of passing a dictionary, this should not be a
319        # problem.
320        # Issue #21172: a request was made to relax the isinstance check
321        # to hasattr(args[0], '__getitem__'). However, the docs on string
322        # formatting still seem to suggest a mapping object is required.
323        # Thus, while not removing the isinstance check, it does now look
324        # for collections.abc.Mapping rather than, as before, dict.
325        if (args and len(args) == 1 and isinstance(args[0], collections.abc.Mapping)
326            and args[0]):
327            args = args[0]
328        self.args = args
329        self.levelname = getLevelName(level)
330        self.levelno = level
331        self.pathname = pathname
332        try:
333            self.filename = os.path.basename(pathname)
334            self.module = os.path.splitext(self.filename)[0]
335        except (TypeError, ValueError, AttributeError):
336            self.filename = pathname
337            self.module = "Unknown module"
338        self.exc_info = exc_info
339        self.exc_text = None      # used to cache the traceback text
340        self.stack_info = sinfo
341        self.lineno = lineno
342        self.funcName = func
343        self.created = ct
344        self.msecs = int((ct - int(ct)) * 1000) + 0.0  # see gh-89047
345        self.relativeCreated = (self.created - _startTime) * 1000
346        if logThreads:
347            self.thread = threading.get_ident()
348            self.threadName = threading.current_thread().name
349        else: # pragma: no cover
350            self.thread = None
351            self.threadName = None
352        if not logMultiprocessing: # pragma: no cover
353            self.processName = None
354        else:
355            self.processName = 'MainProcess'
356            mp = sys.modules.get('multiprocessing')
357            if mp is not None:
358                # Errors may occur if multiprocessing has not finished loading
359                # yet - e.g. if a custom import hook causes third-party code
360                # to run when multiprocessing calls import. See issue 8200
361                # for an example
362                try:
363                    self.processName = mp.current_process().name
364                except Exception: #pragma: no cover
365                    pass
366        if logProcesses and hasattr(os, 'getpid'):
367            self.process = os.getpid()
368        else:
369            self.process = None
370
371        self.taskName = None
372        if logAsyncioTasks:
373            asyncio = sys.modules.get('asyncio')
374            if asyncio:
375                try:
376                    self.taskName = asyncio.current_task().get_name()
377                except Exception:
378                    pass

Initialize a logging record with interesting information.

name
msg
args
levelname
levelno
pathname
exc_info
exc_text
stack_info
lineno
funcName
created
msecs
relativeCreated
taskName
def getMessage(self):
384    def getMessage(self):
385        """
386        Return the message for this LogRecord.
387
388        Return the message for this LogRecord after merging any user-supplied
389        arguments with the message.
390        """
391        msg = str(self.msg)
392        if self.args:
393            msg = msg % self.args
394        return msg

Return the message for this LogRecord.

Return the message for this LogRecord after merging any user-supplied arguments with the message.

class Logger(Filterer):
1483class Logger(Filterer):
1484    """
1485    Instances of the Logger class represent a single logging channel. A
1486    "logging channel" indicates an area of an application. Exactly how an
1487    "area" is defined is up to the application developer. Since an
1488    application can have any number of areas, logging channels are identified
1489    by a unique string. Application areas can be nested (e.g. an area
1490    of "input processing" might include sub-areas "read CSV files", "read
1491    XLS files" and "read Gnumeric files"). To cater for this natural nesting,
1492    channel names are organized into a namespace hierarchy where levels are
1493    separated by periods, much like the Java or Python package namespace. So
1494    in the instance given above, channel names might be "input" for the upper
1495    level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
1496    There is no arbitrary limit to the depth of nesting.
1497    """
1498    def __init__(self, name, level=NOTSET):
1499        """
1500        Initialize the logger with a name and an optional level.
1501        """
1502        Filterer.__init__(self)
1503        self.name = name
1504        self.level = _checkLevel(level)
1505        self.parent = None
1506        self.propagate = True
1507        self.handlers = []
1508        self.disabled = False
1509        self._cache = {}
1510
1511    def setLevel(self, level):
1512        """
1513        Set the logging level of this logger.  level must be an int or a str.
1514        """
1515        self.level = _checkLevel(level)
1516        self.manager._clear_cache()
1517
1518    def debug(self, msg, *args, **kwargs):
1519        """
1520        Log 'msg % args' with severity 'DEBUG'.
1521
1522        To pass exception information, use the keyword argument exc_info with
1523        a true value, e.g.
1524
1525        logger.debug("Houston, we have a %s", "thorny problem", exc_info=True)
1526        """
1527        if self.isEnabledFor(DEBUG):
1528            self._log(DEBUG, msg, args, **kwargs)
1529
1530    def info(self, msg, *args, **kwargs):
1531        """
1532        Log 'msg % args' with severity 'INFO'.
1533
1534        To pass exception information, use the keyword argument exc_info with
1535        a true value, e.g.
1536
1537        logger.info("Houston, we have a %s", "notable problem", exc_info=True)
1538        """
1539        if self.isEnabledFor(INFO):
1540            self._log(INFO, msg, args, **kwargs)
1541
1542    def warning(self, msg, *args, **kwargs):
1543        """
1544        Log 'msg % args' with severity 'WARNING'.
1545
1546        To pass exception information, use the keyword argument exc_info with
1547        a true value, e.g.
1548
1549        logger.warning("Houston, we have a %s", "bit of a problem", exc_info=True)
1550        """
1551        if self.isEnabledFor(WARNING):
1552            self._log(WARNING, msg, args, **kwargs)
1553
1554    def warn(self, msg, *args, **kwargs):
1555        warnings.warn("The 'warn' method is deprecated, "
1556            "use 'warning' instead", DeprecationWarning, 2)
1557        self.warning(msg, *args, **kwargs)
1558
1559    def error(self, msg, *args, **kwargs):
1560        """
1561        Log 'msg % args' with severity 'ERROR'.
1562
1563        To pass exception information, use the keyword argument exc_info with
1564        a true value, e.g.
1565
1566        logger.error("Houston, we have a %s", "major problem", exc_info=True)
1567        """
1568        if self.isEnabledFor(ERROR):
1569            self._log(ERROR, msg, args, **kwargs)
1570
1571    def exception(self, msg, *args, exc_info=True, **kwargs):
1572        """
1573        Convenience method for logging an ERROR with exception information.
1574        """
1575        self.error(msg, *args, exc_info=exc_info, **kwargs)
1576
1577    def critical(self, msg, *args, **kwargs):
1578        """
1579        Log 'msg % args' with severity 'CRITICAL'.
1580
1581        To pass exception information, use the keyword argument exc_info with
1582        a true value, e.g.
1583
1584        logger.critical("Houston, we have a %s", "major disaster", exc_info=True)
1585        """
1586        if self.isEnabledFor(CRITICAL):
1587            self._log(CRITICAL, msg, args, **kwargs)
1588
1589    def fatal(self, msg, *args, **kwargs):
1590        """
1591        Don't use this method, use critical() instead.
1592        """
1593        self.critical(msg, *args, **kwargs)
1594
1595    def log(self, level, msg, *args, **kwargs):
1596        """
1597        Log 'msg % args' with the integer severity 'level'.
1598
1599        To pass exception information, use the keyword argument exc_info with
1600        a true value, e.g.
1601
1602        logger.log(level, "We have a %s", "mysterious problem", exc_info=True)
1603        """
1604        if not isinstance(level, int):
1605            if raiseExceptions:
1606                raise TypeError("level must be an integer")
1607            else:
1608                return
1609        if self.isEnabledFor(level):
1610            self._log(level, msg, args, **kwargs)
1611
1612    def findCaller(self, stack_info=False, stacklevel=1):
1613        """
1614        Find the stack frame of the caller so that we can note the source
1615        file name, line number and function name.
1616        """
1617        f = currentframe()
1618        #On some versions of IronPython, currentframe() returns None if
1619        #IronPython isn't run with -X:Frames.
1620        if f is None:
1621            return "(unknown file)", 0, "(unknown function)", None
1622        while stacklevel > 0:
1623            next_f = f.f_back
1624            if next_f is None:
1625                ## We've got options here.
1626                ## If we want to use the last (deepest) frame:
1627                break
1628                ## If we want to mimic the warnings module:
1629                #return ("sys", 1, "(unknown function)", None)
1630                ## If we want to be pedantic:
1631                #raise ValueError("call stack is not deep enough")
1632            f = next_f
1633            if not _is_internal_frame(f):
1634                stacklevel -= 1
1635        co = f.f_code
1636        sinfo = None
1637        if stack_info:
1638            with io.StringIO() as sio:
1639                sio.write("Stack (most recent call last):\n")
1640                traceback.print_stack(f, file=sio)
1641                sinfo = sio.getvalue()
1642                if sinfo[-1] == '\n':
1643                    sinfo = sinfo[:-1]
1644        return co.co_filename, f.f_lineno, co.co_name, sinfo
1645
1646    def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
1647                   func=None, extra=None, sinfo=None):
1648        """
1649        A factory method which can be overridden in subclasses to create
1650        specialized LogRecords.
1651        """
1652        rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func,
1653                             sinfo)
1654        if extra is not None:
1655            for key in extra:
1656                if (key in ["message", "asctime"]) or (key in rv.__dict__):
1657                    raise KeyError("Attempt to overwrite %r in LogRecord" % key)
1658                rv.__dict__[key] = extra[key]
1659        return rv
1660
1661    def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False,
1662             stacklevel=1):
1663        """
1664        Low-level logging routine which creates a LogRecord and then calls
1665        all the handlers of this logger to handle the record.
1666        """
1667        sinfo = None
1668        if _srcfile:
1669            #IronPython doesn't track Python frames, so findCaller raises an
1670            #exception on some versions of IronPython. We trap it here so that
1671            #IronPython can use logging.
1672            try:
1673                fn, lno, func, sinfo = self.findCaller(stack_info, stacklevel)
1674            except ValueError: # pragma: no cover
1675                fn, lno, func = "(unknown file)", 0, "(unknown function)"
1676        else: # pragma: no cover
1677            fn, lno, func = "(unknown file)", 0, "(unknown function)"
1678        if exc_info:
1679            if isinstance(exc_info, BaseException):
1680                exc_info = (type(exc_info), exc_info, exc_info.__traceback__)
1681            elif not isinstance(exc_info, tuple):
1682                exc_info = sys.exc_info()
1683        record = self.makeRecord(self.name, level, fn, lno, msg, args,
1684                                 exc_info, func, extra, sinfo)
1685        self.handle(record)
1686
1687    def handle(self, record):
1688        """
1689        Call the handlers for the specified record.
1690
1691        This method is used for unpickled records received from a socket, as
1692        well as those created locally. Logger-level filtering is applied.
1693        """
1694        if self.disabled:
1695            return
1696        maybe_record = self.filter(record)
1697        if not maybe_record:
1698            return
1699        if isinstance(maybe_record, LogRecord):
1700            record = maybe_record
1701        self.callHandlers(record)
1702
1703    def addHandler(self, hdlr):
1704        """
1705        Add the specified handler to this logger.
1706        """
1707        _acquireLock()
1708        try:
1709            if not (hdlr in self.handlers):
1710                self.handlers.append(hdlr)
1711        finally:
1712            _releaseLock()
1713
1714    def removeHandler(self, hdlr):
1715        """
1716        Remove the specified handler from this logger.
1717        """
1718        _acquireLock()
1719        try:
1720            if hdlr in self.handlers:
1721                self.handlers.remove(hdlr)
1722        finally:
1723            _releaseLock()
1724
1725    def hasHandlers(self):
1726        """
1727        See if this logger has any handlers configured.
1728
1729        Loop through all handlers for this logger and its parents in the
1730        logger hierarchy. Return True if a handler was found, else False.
1731        Stop searching up the hierarchy whenever a logger with the "propagate"
1732        attribute set to zero is found - that will be the last logger which
1733        is checked for the existence of handlers.
1734        """
1735        c = self
1736        rv = False
1737        while c:
1738            if c.handlers:
1739                rv = True
1740                break
1741            if not c.propagate:
1742                break
1743            else:
1744                c = c.parent
1745        return rv
1746
1747    def callHandlers(self, record):
1748        """
1749        Pass a record to all relevant handlers.
1750
1751        Loop through all handlers for this logger and its parents in the
1752        logger hierarchy. If no handler was found, output a one-off error
1753        message to sys.stderr. Stop searching up the hierarchy whenever a
1754        logger with the "propagate" attribute set to zero is found - that
1755        will be the last logger whose handlers are called.
1756        """
1757        c = self
1758        found = 0
1759        while c:
1760            for hdlr in c.handlers:
1761                found = found + 1
1762                if record.levelno >= hdlr.level:
1763                    hdlr.handle(record)
1764            if not c.propagate:
1765                c = None    #break out
1766            else:
1767                c = c.parent
1768        if (found == 0):
1769            if lastResort:
1770                if record.levelno >= lastResort.level:
1771                    lastResort.handle(record)
1772            elif raiseExceptions and not self.manager.emittedNoHandlerWarning:
1773                sys.stderr.write("No handlers could be found for logger"
1774                                 " \"%s\"\n" % self.name)
1775                self.manager.emittedNoHandlerWarning = True
1776
1777    def getEffectiveLevel(self):
1778        """
1779        Get the effective level for this logger.
1780
1781        Loop through this logger and its parents in the logger hierarchy,
1782        looking for a non-zero logging level. Return the first one found.
1783        """
1784        logger = self
1785        while logger:
1786            if logger.level:
1787                return logger.level
1788            logger = logger.parent
1789        return NOTSET
1790
1791    def isEnabledFor(self, level):
1792        """
1793        Is this logger enabled for level 'level'?
1794        """
1795        if self.disabled:
1796            return False
1797
1798        try:
1799            return self._cache[level]
1800        except KeyError:
1801            _acquireLock()
1802            try:
1803                if self.manager.disable >= level:
1804                    is_enabled = self._cache[level] = False
1805                else:
1806                    is_enabled = self._cache[level] = (
1807                        level >= self.getEffectiveLevel()
1808                    )
1809            finally:
1810                _releaseLock()
1811            return is_enabled
1812
1813    def getChild(self, suffix):
1814        """
1815        Get a logger which is a descendant to this one.
1816
1817        This is a convenience method, such that
1818
1819        logging.getLogger('abc').getChild('def.ghi')
1820
1821        is the same as
1822
1823        logging.getLogger('abc.def.ghi')
1824
1825        It's useful, for example, when the parent logger is named using
1826        __name__ rather than a literal string.
1827        """
1828        if self.root is not self:
1829            suffix = '.'.join((self.name, suffix))
1830        return self.manager.getLogger(suffix)
1831
1832    def getChildren(self):
1833
1834        def _hierlevel(logger):
1835            if logger is logger.manager.root:
1836                return 0
1837            return 1 + logger.name.count('.')
1838
1839        d = self.manager.loggerDict
1840        _acquireLock()
1841        try:
1842            # exclude PlaceHolders - the last check is to ensure that lower-level
1843            # descendants aren't returned - if there are placeholders, a logger's
1844            # parent field might point to a grandparent or ancestor thereof.
1845            return set(item for item in d.values()
1846                       if isinstance(item, Logger) and item.parent is self and
1847                       _hierlevel(item) == 1 + _hierlevel(item.parent))
1848        finally:
1849            _releaseLock()
1850
1851    def __repr__(self):
1852        level = getLevelName(self.getEffectiveLevel())
1853        return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level)
1854
1855    def __reduce__(self):
1856        if getLogger(self.name) is not self:
1857            import pickle
1858            raise pickle.PicklingError('logger cannot be pickled')
1859        return getLogger, (self.name,)

Instances of the Logger class represent a single logging channel. A "logging channel" indicates an area of an application. Exactly how an "area" is defined is up to the application developer. Since an application can have any number of areas, logging channels are identified by a unique string. Application areas can be nested (e.g. an area of "input processing" might include sub-areas "read CSV files", "read XLS files" and "read Gnumeric files"). To cater for this natural nesting, channel names are organized into a namespace hierarchy where levels are separated by periods, much like the Java or Python package namespace. So in the instance given above, channel names might be "input" for the upper level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels. There is no arbitrary limit to the depth of nesting.

Logger(name, level=0)
1498    def __init__(self, name, level=NOTSET):
1499        """
1500        Initialize the logger with a name and an optional level.
1501        """
1502        Filterer.__init__(self)
1503        self.name = name
1504        self.level = _checkLevel(level)
1505        self.parent = None
1506        self.propagate = True
1507        self.handlers = []
1508        self.disabled = False
1509        self._cache = {}

Initialize the logger with a name and an optional level.

name
level
parent
propagate
handlers
disabled
def setLevel(self, level):
1511    def setLevel(self, level):
1512        """
1513        Set the logging level of this logger.  level must be an int or a str.
1514        """
1515        self.level = _checkLevel(level)
1516        self.manager._clear_cache()

Set the logging level of this logger. level must be an int or a str.

def debug(self, msg, *args, **kwargs):
1518    def debug(self, msg, *args, **kwargs):
1519        """
1520        Log 'msg % args' with severity 'DEBUG'.
1521
1522        To pass exception information, use the keyword argument exc_info with
1523        a true value, e.g.
1524
1525        logger.debug("Houston, we have a %s", "thorny problem", exc_info=True)
1526        """
1527        if self.isEnabledFor(DEBUG):
1528            self._log(DEBUG, msg, args, **kwargs)

Log 'msg % args' with severity 'DEBUG'.

To pass exception information, use the keyword argument exc_info with a true value, e.g.

logger.debug("Houston, we have a %s", "thorny problem", exc_info=True)

def info(self, msg, *args, **kwargs):
1530    def info(self, msg, *args, **kwargs):
1531        """
1532        Log 'msg % args' with severity 'INFO'.
1533
1534        To pass exception information, use the keyword argument exc_info with
1535        a true value, e.g.
1536
1537        logger.info("Houston, we have a %s", "notable problem", exc_info=True)
1538        """
1539        if self.isEnabledFor(INFO):
1540            self._log(INFO, msg, args, **kwargs)

Log 'msg % args' with severity 'INFO'.

To pass exception information, use the keyword argument exc_info with a true value, e.g.

logger.info("Houston, we have a %s", "notable problem", exc_info=True)

def warning(self, msg, *args, **kwargs):
1542    def warning(self, msg, *args, **kwargs):
1543        """
1544        Log 'msg % args' with severity 'WARNING'.
1545
1546        To pass exception information, use the keyword argument exc_info with
1547        a true value, e.g.
1548
1549        logger.warning("Houston, we have a %s", "bit of a problem", exc_info=True)
1550        """
1551        if self.isEnabledFor(WARNING):
1552            self._log(WARNING, msg, args, **kwargs)

Log 'msg % args' with severity 'WARNING'.

To pass exception information, use the keyword argument exc_info with a true value, e.g.

logger.warning("Houston, we have a %s", "bit of a problem", exc_info=True)

def warn(self, msg, *args, **kwargs):
1554    def warn(self, msg, *args, **kwargs):
1555        warnings.warn("The 'warn' method is deprecated, "
1556            "use 'warning' instead", DeprecationWarning, 2)
1557        self.warning(msg, *args, **kwargs)
def error(self, msg, *args, **kwargs):
1559    def error(self, msg, *args, **kwargs):
1560        """
1561        Log 'msg % args' with severity 'ERROR'.
1562
1563        To pass exception information, use the keyword argument exc_info with
1564        a true value, e.g.
1565
1566        logger.error("Houston, we have a %s", "major problem", exc_info=True)
1567        """
1568        if self.isEnabledFor(ERROR):
1569            self._log(ERROR, msg, args, **kwargs)

Log 'msg % args' with severity 'ERROR'.

To pass exception information, use the keyword argument exc_info with a true value, e.g.

logger.error("Houston, we have a %s", "major problem", exc_info=True)

def exception(self, msg, *args, exc_info=True, **kwargs):
1571    def exception(self, msg, *args, exc_info=True, **kwargs):
1572        """
1573        Convenience method for logging an ERROR with exception information.
1574        """
1575        self.error(msg, *args, exc_info=exc_info, **kwargs)

Convenience method for logging an ERROR with exception information.

def critical(self, msg, *args, **kwargs):
1577    def critical(self, msg, *args, **kwargs):
1578        """
1579        Log 'msg % args' with severity 'CRITICAL'.
1580
1581        To pass exception information, use the keyword argument exc_info with
1582        a true value, e.g.
1583
1584        logger.critical("Houston, we have a %s", "major disaster", exc_info=True)
1585        """
1586        if self.isEnabledFor(CRITICAL):
1587            self._log(CRITICAL, msg, args, **kwargs)

Log 'msg % args' with severity 'CRITICAL'.

To pass exception information, use the keyword argument exc_info with a true value, e.g.

logger.critical("Houston, we have a %s", "major disaster", exc_info=True)

def fatal(self, msg, *args, **kwargs):
1589    def fatal(self, msg, *args, **kwargs):
1590        """
1591        Don't use this method, use critical() instead.
1592        """
1593        self.critical(msg, *args, **kwargs)

Don't use this method, use critical() instead.

def log(self, level, msg, *args, **kwargs):
1595    def log(self, level, msg, *args, **kwargs):
1596        """
1597        Log 'msg % args' with the integer severity 'level'.
1598
1599        To pass exception information, use the keyword argument exc_info with
1600        a true value, e.g.
1601
1602        logger.log(level, "We have a %s", "mysterious problem", exc_info=True)
1603        """
1604        if not isinstance(level, int):
1605            if raiseExceptions:
1606                raise TypeError("level must be an integer")
1607            else:
1608                return
1609        if self.isEnabledFor(level):
1610            self._log(level, msg, args, **kwargs)

Log 'msg % args' with the integer severity 'level'.

To pass exception information, use the keyword argument exc_info with a true value, e.g.

logger.log(level, "We have a %s", "mysterious problem", exc_info=True)

def findCaller(self, stack_info=False, stacklevel=1):
1612    def findCaller(self, stack_info=False, stacklevel=1):
1613        """
1614        Find the stack frame of the caller so that we can note the source
1615        file name, line number and function name.
1616        """
1617        f = currentframe()
1618        #On some versions of IronPython, currentframe() returns None if
1619        #IronPython isn't run with -X:Frames.
1620        if f is None:
1621            return "(unknown file)", 0, "(unknown function)", None
1622        while stacklevel > 0:
1623            next_f = f.f_back
1624            if next_f is None:
1625                ## We've got options here.
1626                ## If we want to use the last (deepest) frame:
1627                break
1628                ## If we want to mimic the warnings module:
1629                #return ("sys", 1, "(unknown function)", None)
1630                ## If we want to be pedantic:
1631                #raise ValueError("call stack is not deep enough")
1632            f = next_f
1633            if not _is_internal_frame(f):
1634                stacklevel -= 1
1635        co = f.f_code
1636        sinfo = None
1637        if stack_info:
1638            with io.StringIO() as sio:
1639                sio.write("Stack (most recent call last):\n")
1640                traceback.print_stack(f, file=sio)
1641                sinfo = sio.getvalue()
1642                if sinfo[-1] == '\n':
1643                    sinfo = sinfo[:-1]
1644        return co.co_filename, f.f_lineno, co.co_name, sinfo

Find the stack frame of the caller so that we can note the source file name, line number and function name.

def makeRecord( self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None, sinfo=None):
1646    def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
1647                   func=None, extra=None, sinfo=None):
1648        """
1649        A factory method which can be overridden in subclasses to create
1650        specialized LogRecords.
1651        """
1652        rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func,
1653                             sinfo)
1654        if extra is not None:
1655            for key in extra:
1656                if (key in ["message", "asctime"]) or (key in rv.__dict__):
1657                    raise KeyError("Attempt to overwrite %r in LogRecord" % key)
1658                rv.__dict__[key] = extra[key]
1659        return rv

A factory method which can be overridden in subclasses to create specialized LogRecords.

def handle(self, record):
1687    def handle(self, record):
1688        """
1689        Call the handlers for the specified record.
1690
1691        This method is used for unpickled records received from a socket, as
1692        well as those created locally. Logger-level filtering is applied.
1693        """
1694        if self.disabled:
1695            return
1696        maybe_record = self.filter(record)
1697        if not maybe_record:
1698            return
1699        if isinstance(maybe_record, LogRecord):
1700            record = maybe_record
1701        self.callHandlers(record)

Call the handlers for the specified record.

This method is used for unpickled records received from a socket, as well as those created locally. Logger-level filtering is applied.

def addHandler(self, hdlr):
1703    def addHandler(self, hdlr):
1704        """
1705        Add the specified handler to this logger.
1706        """
1707        _acquireLock()
1708        try:
1709            if not (hdlr in self.handlers):
1710                self.handlers.append(hdlr)
1711        finally:
1712            _releaseLock()

Add the specified handler to this logger.

def removeHandler(self, hdlr):
1714    def removeHandler(self, hdlr):
1715        """
1716        Remove the specified handler from this logger.
1717        """
1718        _acquireLock()
1719        try:
1720            if hdlr in self.handlers:
1721                self.handlers.remove(hdlr)
1722        finally:
1723            _releaseLock()

Remove the specified handler from this logger.

def hasHandlers(self):
1725    def hasHandlers(self):
1726        """
1727        See if this logger has any handlers configured.
1728
1729        Loop through all handlers for this logger and its parents in the
1730        logger hierarchy. Return True if a handler was found, else False.
1731        Stop searching up the hierarchy whenever a logger with the "propagate"
1732        attribute set to zero is found - that will be the last logger which
1733        is checked for the existence of handlers.
1734        """
1735        c = self
1736        rv = False
1737        while c:
1738            if c.handlers:
1739                rv = True
1740                break
1741            if not c.propagate:
1742                break
1743            else:
1744                c = c.parent
1745        return rv

See if this logger has any handlers configured.

Loop through all handlers for this logger and its parents in the logger hierarchy. Return True if a handler was found, else False. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger which is checked for the existence of handlers.

def callHandlers(self, record):
1747    def callHandlers(self, record):
1748        """
1749        Pass a record to all relevant handlers.
1750
1751        Loop through all handlers for this logger and its parents in the
1752        logger hierarchy. If no handler was found, output a one-off error
1753        message to sys.stderr. Stop searching up the hierarchy whenever a
1754        logger with the "propagate" attribute set to zero is found - that
1755        will be the last logger whose handlers are called.
1756        """
1757        c = self
1758        found = 0
1759        while c:
1760            for hdlr in c.handlers:
1761                found = found + 1
1762                if record.levelno >= hdlr.level:
1763                    hdlr.handle(record)
1764            if not c.propagate:
1765                c = None    #break out
1766            else:
1767                c = c.parent
1768        if (found == 0):
1769            if lastResort:
1770                if record.levelno >= lastResort.level:
1771                    lastResort.handle(record)
1772            elif raiseExceptions and not self.manager.emittedNoHandlerWarning:
1773                sys.stderr.write("No handlers could be found for logger"
1774                                 " \"%s\"\n" % self.name)
1775                self.manager.emittedNoHandlerWarning = True

Pass a record to all relevant handlers.

Loop through all handlers for this logger and its parents in the logger hierarchy. If no handler was found, output a one-off error message to sys.stderr. Stop searching up the hierarchy whenever a logger with the "propagate" attribute set to zero is found - that will be the last logger whose handlers are called.

def getEffectiveLevel(self):
1777    def getEffectiveLevel(self):
1778        """
1779        Get the effective level for this logger.
1780
1781        Loop through this logger and its parents in the logger hierarchy,
1782        looking for a non-zero logging level. Return the first one found.
1783        """
1784        logger = self
1785        while logger:
1786            if logger.level:
1787                return logger.level
1788            logger = logger.parent
1789        return NOTSET

Get the effective level for this logger.

Loop through this logger and its parents in the logger hierarchy, looking for a non-zero logging level. Return the first one found.

def isEnabledFor(self, level):
1791    def isEnabledFor(self, level):
1792        """
1793        Is this logger enabled for level 'level'?
1794        """
1795        if self.disabled:
1796            return False
1797
1798        try:
1799            return self._cache[level]
1800        except KeyError:
1801            _acquireLock()
1802            try:
1803                if self.manager.disable >= level:
1804                    is_enabled = self._cache[level] = False
1805                else:
1806                    is_enabled = self._cache[level] = (
1807                        level >= self.getEffectiveLevel()
1808                    )
1809            finally:
1810                _releaseLock()
1811            return is_enabled

Is this logger enabled for level 'level'?

def getChild(self, suffix):
1813    def getChild(self, suffix):
1814        """
1815        Get a logger which is a descendant to this one.
1816
1817        This is a convenience method, such that
1818
1819        logging.getLogger('abc').getChild('def.ghi')
1820
1821        is the same as
1822
1823        logging.getLogger('abc.def.ghi')
1824
1825        It's useful, for example, when the parent logger is named using
1826        __name__ rather than a literal string.
1827        """
1828        if self.root is not self:
1829            suffix = '.'.join((self.name, suffix))
1830        return self.manager.getLogger(suffix)

Get a logger which is a descendant to this one.

This is a convenience method, such that

logging.getLogger('abc').getChild('def.ghi')

is the same as

logging.getLogger('abc.def.ghi')

It's useful, for example, when the parent logger is named using __name__ rather than a literal string.

def getChildren(self):
1832    def getChildren(self):
1833
1834        def _hierlevel(logger):
1835            if logger is logger.manager.root:
1836                return 0
1837            return 1 + logger.name.count('.')
1838
1839        d = self.manager.loggerDict
1840        _acquireLock()
1841        try:
1842            # exclude PlaceHolders - the last check is to ensure that lower-level
1843            # descendants aren't returned - if there are placeholders, a logger's
1844            # parent field might point to a grandparent or ancestor thereof.
1845            return set(item for item in d.values()
1846                       if isinstance(item, Logger) and item.parent is self and
1847                       _hierlevel(item) == 1 + _hierlevel(item.parent))
1848        finally:
1849            _releaseLock()
root = <RootLogger root (WARNING)>
manager = <logging.Manager object>
class LoggerAdapter:
1879class LoggerAdapter(object):
1880    """
1881    An adapter for loggers which makes it easier to specify contextual
1882    information in logging output.
1883    """
1884
1885    def __init__(self, logger, extra=None):
1886        """
1887        Initialize the adapter with a logger and a dict-like object which
1888        provides contextual information. This constructor signature allows
1889        easy stacking of LoggerAdapters, if so desired.
1890
1891        You can effectively pass keyword arguments as shown in the
1892        following example:
1893
1894        adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
1895        """
1896        self.logger = logger
1897        self.extra = extra
1898
1899    def process(self, msg, kwargs):
1900        """
1901        Process the logging message and keyword arguments passed in to
1902        a logging call to insert contextual information. You can either
1903        manipulate the message itself, the keyword args or both. Return
1904        the message and kwargs modified (or not) to suit your needs.
1905
1906        Normally, you'll only need to override this one method in a
1907        LoggerAdapter subclass for your specific needs.
1908        """
1909        kwargs["extra"] = self.extra
1910        return msg, kwargs
1911
1912    #
1913    # Boilerplate convenience methods
1914    #
1915    def debug(self, msg, *args, **kwargs):
1916        """
1917        Delegate a debug call to the underlying logger.
1918        """
1919        self.log(DEBUG, msg, *args, **kwargs)
1920
1921    def info(self, msg, *args, **kwargs):
1922        """
1923        Delegate an info call to the underlying logger.
1924        """
1925        self.log(INFO, msg, *args, **kwargs)
1926
1927    def warning(self, msg, *args, **kwargs):
1928        """
1929        Delegate a warning call to the underlying logger.
1930        """
1931        self.log(WARNING, msg, *args, **kwargs)
1932
1933    def warn(self, msg, *args, **kwargs):
1934        warnings.warn("The 'warn' method is deprecated, "
1935            "use 'warning' instead", DeprecationWarning, 2)
1936        self.warning(msg, *args, **kwargs)
1937
1938    def error(self, msg, *args, **kwargs):
1939        """
1940        Delegate an error call to the underlying logger.
1941        """
1942        self.log(ERROR, msg, *args, **kwargs)
1943
1944    def exception(self, msg, *args, exc_info=True, **kwargs):
1945        """
1946        Delegate an exception call to the underlying logger.
1947        """
1948        self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs)
1949
1950    def critical(self, msg, *args, **kwargs):
1951        """
1952        Delegate a critical call to the underlying logger.
1953        """
1954        self.log(CRITICAL, msg, *args, **kwargs)
1955
1956    def log(self, level, msg, *args, **kwargs):
1957        """
1958        Delegate a log call to the underlying logger, after adding
1959        contextual information from this adapter instance.
1960        """
1961        if self.isEnabledFor(level):
1962            msg, kwargs = self.process(msg, kwargs)
1963            self.logger.log(level, msg, *args, **kwargs)
1964
1965    def isEnabledFor(self, level):
1966        """
1967        Is this logger enabled for level 'level'?
1968        """
1969        return self.logger.isEnabledFor(level)
1970
1971    def setLevel(self, level):
1972        """
1973        Set the specified level on the underlying logger.
1974        """
1975        self.logger.setLevel(level)
1976
1977    def getEffectiveLevel(self):
1978        """
1979        Get the effective level for the underlying logger.
1980        """
1981        return self.logger.getEffectiveLevel()
1982
1983    def hasHandlers(self):
1984        """
1985        See if the underlying logger has any handlers.
1986        """
1987        return self.logger.hasHandlers()
1988
1989    def _log(self, level, msg, args, **kwargs):
1990        """
1991        Low-level log implementation, proxied to allow nested logger adapters.
1992        """
1993        return self.logger._log(level, msg, args, **kwargs)
1994
1995    @property
1996    def manager(self):
1997        return self.logger.manager
1998
1999    @manager.setter
2000    def manager(self, value):
2001        self.logger.manager = value
2002
2003    @property
2004    def name(self):
2005        return self.logger.name
2006
2007    def __repr__(self):
2008        logger = self.logger
2009        level = getLevelName(logger.getEffectiveLevel())
2010        return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level)
2011
2012    __class_getitem__ = classmethod(GenericAlias)

An adapter for loggers which makes it easier to specify contextual information in logging output.

LoggerAdapter(logger, extra=None)
1885    def __init__(self, logger, extra=None):
1886        """
1887        Initialize the adapter with a logger and a dict-like object which
1888        provides contextual information. This constructor signature allows
1889        easy stacking of LoggerAdapters, if so desired.
1890
1891        You can effectively pass keyword arguments as shown in the
1892        following example:
1893
1894        adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
1895        """
1896        self.logger = logger
1897        self.extra = extra

Initialize the adapter with a logger and a dict-like object which provides contextual information. This constructor signature allows easy stacking of LoggerAdapters, if so desired.

You can effectively pass keyword arguments as shown in the following example:

adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))

logger
extra
def process(self, msg, kwargs):
1899    def process(self, msg, kwargs):
1900        """
1901        Process the logging message and keyword arguments passed in to
1902        a logging call to insert contextual information. You can either
1903        manipulate the message itself, the keyword args or both. Return
1904        the message and kwargs modified (or not) to suit your needs.
1905
1906        Normally, you'll only need to override this one method in a
1907        LoggerAdapter subclass for your specific needs.
1908        """
1909        kwargs["extra"] = self.extra
1910        return msg, kwargs

Process the logging message and keyword arguments passed in to a logging call to insert contextual information. You can either manipulate the message itself, the keyword args or both. Return the message and kwargs modified (or not) to suit your needs.

Normally, you'll only need to override this one method in a LoggerAdapter subclass for your specific needs.

def debug(self, msg, *args, **kwargs):
1915    def debug(self, msg, *args, **kwargs):
1916        """
1917        Delegate a debug call to the underlying logger.
1918        """
1919        self.log(DEBUG, msg, *args, **kwargs)

Delegate a debug call to the underlying logger.

def info(self, msg, *args, **kwargs):
1921    def info(self, msg, *args, **kwargs):
1922        """
1923        Delegate an info call to the underlying logger.
1924        """
1925        self.log(INFO, msg, *args, **kwargs)

Delegate an info call to the underlying logger.

def warning(self, msg, *args, **kwargs):
1927    def warning(self, msg, *args, **kwargs):
1928        """
1929        Delegate a warning call to the underlying logger.
1930        """
1931        self.log(WARNING, msg, *args, **kwargs)

Delegate a warning call to the underlying logger.

def warn(self, msg, *args, **kwargs):
1933    def warn(self, msg, *args, **kwargs):
1934        warnings.warn("The 'warn' method is deprecated, "
1935            "use 'warning' instead", DeprecationWarning, 2)
1936        self.warning(msg, *args, **kwargs)
def error(self, msg, *args, **kwargs):
1938    def error(self, msg, *args, **kwargs):
1939        """
1940        Delegate an error call to the underlying logger.
1941        """
1942        self.log(ERROR, msg, *args, **kwargs)

Delegate an error call to the underlying logger.

def exception(self, msg, *args, exc_info=True, **kwargs):
1944    def exception(self, msg, *args, exc_info=True, **kwargs):
1945        """
1946        Delegate an exception call to the underlying logger.
1947        """
1948        self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs)

Delegate an exception call to the underlying logger.

def critical(self, msg, *args, **kwargs):
1950    def critical(self, msg, *args, **kwargs):
1951        """
1952        Delegate a critical call to the underlying logger.
1953        """
1954        self.log(CRITICAL, msg, *args, **kwargs)

Delegate a critical call to the underlying logger.

def log(self, level, msg, *args, **kwargs):
1956    def log(self, level, msg, *args, **kwargs):
1957        """
1958        Delegate a log call to the underlying logger, after adding
1959        contextual information from this adapter instance.
1960        """
1961        if self.isEnabledFor(level):
1962            msg, kwargs = self.process(msg, kwargs)
1963            self.logger.log(level, msg, *args, **kwargs)

Delegate a log call to the underlying logger, after adding contextual information from this adapter instance.

def isEnabledFor(self, level):
1965    def isEnabledFor(self, level):
1966        """
1967        Is this logger enabled for level 'level'?
1968        """
1969        return self.logger.isEnabledFor(level)

Is this logger enabled for level 'level'?

def setLevel(self, level):
1971    def setLevel(self, level):
1972        """
1973        Set the specified level on the underlying logger.
1974        """
1975        self.logger.setLevel(level)

Set the specified level on the underlying logger.

def getEffectiveLevel(self):
1977    def getEffectiveLevel(self):
1978        """
1979        Get the effective level for the underlying logger.
1980        """
1981        return self.logger.getEffectiveLevel()

Get the effective level for the underlying logger.

def hasHandlers(self):
1983    def hasHandlers(self):
1984        """
1985        See if the underlying logger has any handlers.
1986        """
1987        return self.logger.hasHandlers()

See if the underlying logger has any handlers.

manager
1995    @property
1996    def manager(self):
1997        return self.logger.manager
name
2003    @property
2004    def name(self):
2005        return self.logger.name
NOTSET = 0
class NullHandler(Handler):
2286class NullHandler(Handler):
2287    """
2288    This handler does nothing. It's intended to be used to avoid the
2289    "No handlers could be found for logger XXX" one-off warning. This is
2290    important for library code, which may contain code to log events. If a user
2291    of the library does not configure logging, the one-off warning might be
2292    produced; to avoid this, the library developer simply needs to instantiate
2293    a NullHandler and add it to the top-level logger of the library module or
2294    package.
2295    """
2296    def handle(self, record):
2297        """Stub."""
2298
2299    def emit(self, record):
2300        """Stub."""
2301
2302    def createLock(self):
2303        self.lock = None
2304
2305    def _at_fork_reinit(self):
2306        pass

This handler does nothing. It's intended to be used to avoid the "No handlers could be found for logger XXX" one-off warning. This is important for library code, which may contain code to log events. If a user of the library does not configure logging, the one-off warning might be produced; to avoid this, the library developer simply needs to instantiate a NullHandler and add it to the top-level logger of the library module or package.

def handle(self, record):
2296    def handle(self, record):
2297        """Stub."""

Stub.

def emit(self, record):
2299    def emit(self, record):
2300        """Stub."""

Stub.

def createLock(self):
2302    def createLock(self):
2303        self.lock = None

Acquire a thread lock for serializing access to the underlying I/O.

class StreamHandler(Handler):
1118class StreamHandler(Handler):
1119    """
1120    A handler class which writes logging records, appropriately formatted,
1121    to a stream. Note that this class does not close the stream, as
1122    sys.stdout or sys.stderr may be used.
1123    """
1124
1125    terminator = '\n'
1126
1127    def __init__(self, stream=None):
1128        """
1129        Initialize the handler.
1130
1131        If stream is not specified, sys.stderr is used.
1132        """
1133        Handler.__init__(self)
1134        if stream is None:
1135            stream = sys.stderr
1136        self.stream = stream
1137
1138    def flush(self):
1139        """
1140        Flushes the stream.
1141        """
1142        self.acquire()
1143        try:
1144            if self.stream and hasattr(self.stream, "flush"):
1145                self.stream.flush()
1146        finally:
1147            self.release()
1148
1149    def emit(self, record):
1150        """
1151        Emit a record.
1152
1153        If a formatter is specified, it is used to format the record.
1154        The record is then written to the stream with a trailing newline.  If
1155        exception information is present, it is formatted using
1156        traceback.print_exception and appended to the stream.  If the stream
1157        has an 'encoding' attribute, it is used to determine how to do the
1158        output to the stream.
1159        """
1160        try:
1161            msg = self.format(record)
1162            stream = self.stream
1163            # issue 35046: merged two stream.writes into one.
1164            stream.write(msg + self.terminator)
1165            self.flush()
1166        except RecursionError:  # See issue 36272
1167            raise
1168        except Exception:
1169            self.handleError(record)
1170
1171    def setStream(self, stream):
1172        """
1173        Sets the StreamHandler's stream to the specified value,
1174        if it is different.
1175
1176        Returns the old stream, if the stream was changed, or None
1177        if it wasn't.
1178        """
1179        if stream is self.stream:
1180            result = None
1181        else:
1182            result = self.stream
1183            self.acquire()
1184            try:
1185                self.flush()
1186                self.stream = stream
1187            finally:
1188                self.release()
1189        return result
1190
1191    def __repr__(self):
1192        level = getLevelName(self.level)
1193        name = getattr(self.stream, 'name', '')
1194        #  bpo-36015: name can be an int
1195        name = str(name)
1196        if name:
1197            name += ' '
1198        return '<%s %s(%s)>' % (self.__class__.__name__, name, level)
1199
1200    __class_getitem__ = classmethod(GenericAlias)

A handler class which writes logging records, appropriately formatted, to a stream. Note that this class does not close the stream, as sys.stdout or sys.stderr may be used.

StreamHandler(stream=None)
1127    def __init__(self, stream=None):
1128        """
1129        Initialize the handler.
1130
1131        If stream is not specified, sys.stderr is used.
1132        """
1133        Handler.__init__(self)
1134        if stream is None:
1135            stream = sys.stderr
1136        self.stream = stream

Initialize the handler.

If stream is not specified, sys.stderr is used.

terminator = '\n'
stream
def flush(self):
1138    def flush(self):
1139        """
1140        Flushes the stream.
1141        """
1142        self.acquire()
1143        try:
1144            if self.stream and hasattr(self.stream, "flush"):
1145                self.stream.flush()
1146        finally:
1147            self.release()

Flushes the stream.

def emit(self, record):
1149    def emit(self, record):
1150        """
1151        Emit a record.
1152
1153        If a formatter is specified, it is used to format the record.
1154        The record is then written to the stream with a trailing newline.  If
1155        exception information is present, it is formatted using
1156        traceback.print_exception and appended to the stream.  If the stream
1157        has an 'encoding' attribute, it is used to determine how to do the
1158        output to the stream.
1159        """
1160        try:
1161            msg = self.format(record)
1162            stream = self.stream
1163            # issue 35046: merged two stream.writes into one.
1164            stream.write(msg + self.terminator)
1165            self.flush()
1166        except RecursionError:  # See issue 36272
1167            raise
1168        except Exception:
1169            self.handleError(record)

Emit a record.

If a formatter is specified, it is used to format the record. The record is then written to the stream with a trailing newline. If exception information is present, it is formatted using traceback.print_exception and appended to the stream. If the stream has an 'encoding' attribute, it is used to determine how to do the output to the stream.

def setStream(self, stream):
1171    def setStream(self, stream):
1172        """
1173        Sets the StreamHandler's stream to the specified value,
1174        if it is different.
1175
1176        Returns the old stream, if the stream was changed, or None
1177        if it wasn't.
1178        """
1179        if stream is self.stream:
1180            result = None
1181        else:
1182            result = self.stream
1183            self.acquire()
1184            try:
1185                self.flush()
1186                self.stream = stream
1187            finally:
1188                self.release()
1189        return result

Sets the StreamHandler's stream to the specified value, if it is different.

Returns the old stream, if the stream was changed, or None if it wasn't.

WARN = 30
WARNING = 30
def addLevelName(level, levelName):
157def addLevelName(level, levelName):
158    """
159    Associate 'levelName' with 'level'.
160
161    This is used when converting levels to text during message formatting.
162    """
163    _acquireLock()
164    try:    #unlikely to cause an exception, but you never know...
165        _levelToName[level] = levelName
166        _nameToLevel[levelName] = level
167    finally:
168        _releaseLock()

Associate 'levelName' with 'level'.

This is used when converting levels to text during message formatting.

def basicConfig(**kwargs):
2022def basicConfig(**kwargs):
2023    """
2024    Do basic configuration for the logging system.
2025
2026    This function does nothing if the root logger already has handlers
2027    configured, unless the keyword argument *force* is set to ``True``.
2028    It is a convenience method intended for use by simple scripts
2029    to do one-shot configuration of the logging package.
2030
2031    The default behaviour is to create a StreamHandler which writes to
2032    sys.stderr, set a formatter using the BASIC_FORMAT format string, and
2033    add the handler to the root logger.
2034
2035    A number of optional keyword arguments may be specified, which can alter
2036    the default behaviour.
2037
2038    filename  Specifies that a FileHandler be created, using the specified
2039              filename, rather than a StreamHandler.
2040    filemode  Specifies the mode to open the file, if filename is specified
2041              (if filemode is unspecified, it defaults to 'a').
2042    format    Use the specified format string for the handler.
2043    datefmt   Use the specified date/time format.
2044    style     If a format string is specified, use this to specify the
2045              type of format string (possible values '%', '{', '$', for
2046              %-formatting, :meth:`str.format` and :class:`string.Template`
2047              - defaults to '%').
2048    level     Set the root logger level to the specified level.
2049    stream    Use the specified stream to initialize the StreamHandler. Note
2050              that this argument is incompatible with 'filename' - if both
2051              are present, 'stream' is ignored.
2052    handlers  If specified, this should be an iterable of already created
2053              handlers, which will be added to the root logger. Any handler
2054              in the list which does not have a formatter assigned will be
2055              assigned the formatter created in this function.
2056    force     If this keyword  is specified as true, any existing handlers
2057              attached to the root logger are removed and closed, before
2058              carrying out the configuration as specified by the other
2059              arguments.
2060    encoding  If specified together with a filename, this encoding is passed to
2061              the created FileHandler, causing it to be used when the file is
2062              opened.
2063    errors    If specified together with a filename, this value is passed to the
2064              created FileHandler, causing it to be used when the file is
2065              opened in text mode. If not specified, the default value is
2066              `backslashreplace`.
2067
2068    Note that you could specify a stream created using open(filename, mode)
2069    rather than passing the filename and mode in. However, it should be
2070    remembered that StreamHandler does not close its stream (since it may be
2071    using sys.stdout or sys.stderr), whereas FileHandler closes its stream
2072    when the handler is closed.
2073
2074    .. versionchanged:: 3.2
2075       Added the ``style`` parameter.
2076
2077    .. versionchanged:: 3.3
2078       Added the ``handlers`` parameter. A ``ValueError`` is now thrown for
2079       incompatible arguments (e.g. ``handlers`` specified together with
2080       ``filename``/``filemode``, or ``filename``/``filemode`` specified
2081       together with ``stream``, or ``handlers`` specified together with
2082       ``stream``.
2083
2084    .. versionchanged:: 3.8
2085       Added the ``force`` parameter.
2086
2087    .. versionchanged:: 3.9
2088       Added the ``encoding`` and ``errors`` parameters.
2089    """
2090    # Add thread safety in case someone mistakenly calls
2091    # basicConfig() from multiple threads
2092    _acquireLock()
2093    try:
2094        force = kwargs.pop('force', False)
2095        encoding = kwargs.pop('encoding', None)
2096        errors = kwargs.pop('errors', 'backslashreplace')
2097        if force:
2098            for h in root.handlers[:]:
2099                root.removeHandler(h)
2100                h.close()
2101        if len(root.handlers) == 0:
2102            handlers = kwargs.pop("handlers", None)
2103            if handlers is None:
2104                if "stream" in kwargs and "filename" in kwargs:
2105                    raise ValueError("'stream' and 'filename' should not be "
2106                                     "specified together")
2107            else:
2108                if "stream" in kwargs or "filename" in kwargs:
2109                    raise ValueError("'stream' or 'filename' should not be "
2110                                     "specified together with 'handlers'")
2111            if handlers is None:
2112                filename = kwargs.pop("filename", None)
2113                mode = kwargs.pop("filemode", 'a')
2114                if filename:
2115                    if 'b' in mode:
2116                        errors = None
2117                    else:
2118                        encoding = io.text_encoding(encoding)
2119                    h = FileHandler(filename, mode,
2120                                    encoding=encoding, errors=errors)
2121                else:
2122                    stream = kwargs.pop("stream", None)
2123                    h = StreamHandler(stream)
2124                handlers = [h]
2125            dfs = kwargs.pop("datefmt", None)
2126            style = kwargs.pop("style", '%')
2127            if style not in _STYLES:
2128                raise ValueError('Style must be one of: %s' % ','.join(
2129                                 _STYLES.keys()))
2130            fs = kwargs.pop("format", _STYLES[style][1])
2131            fmt = Formatter(fs, dfs, style)
2132            for h in handlers:
2133                if h.formatter is None:
2134                    h.setFormatter(fmt)
2135                root.addHandler(h)
2136            level = kwargs.pop("level", None)
2137            if level is not None:
2138                root.setLevel(level)
2139            if kwargs:
2140                keys = ', '.join(kwargs.keys())
2141                raise ValueError('Unrecognised argument(s): %s' % keys)
2142    finally:
2143        _releaseLock()

Do basic configuration for the logging system.

This function does nothing if the root logger already has handlers configured, unless the keyword argument force is set to True. It is a convenience method intended for use by simple scripts to do one-shot configuration of the logging package.

The default behaviour is to create a StreamHandler which writes to sys.stderr, set a formatter using the BASIC_FORMAT format string, and add the handler to the root logger.

A number of optional keyword arguments may be specified, which can alter the default behaviour.

filename Specifies that a FileHandler be created, using the specified filename, rather than a StreamHandler. filemode Specifies the mode to open the file, if filename is specified (if filemode is unspecified, it defaults to 'a'). format Use the specified format string for the handler. datefmt Use the specified date/time format. style If a format string is specified, use this to specify the type of format string (possible values '%', '{', '$', for %-formatting, str.format() and string.Template - defaults to '%'). level Set the root logger level to the specified level. stream Use the specified stream to initialize the StreamHandler. Note that this argument is incompatible with 'filename' - if both are present, 'stream' is ignored. handlers If specified, this should be an iterable of already created handlers, which will be added to the root logger. Any handler in the list which does not have a formatter assigned will be assigned the formatter created in this function. force If this keyword is specified as true, any existing handlers attached to the root logger are removed and closed, before carrying out the configuration as specified by the other arguments. encoding If specified together with a filename, this encoding is passed to the created FileHandler, causing it to be used when the file is opened. errors If specified together with a filename, this value is passed to the created FileHandler, causing it to be used when the file is opened in text mode. If not specified, the default value is backslashreplace.

Note that you could specify a stream created using open(filename, mode) rather than passing the filename and mode in. However, it should be remembered that StreamHandler does not close its stream (since it may be using sys.stdout or sys.stderr), whereas FileHandler closes its stream when the handler is closed.

Changed in version 3.2: Added the style parameter.

Changed in version 3.3: Added the handlers parameter. A ValueError is now thrown for incompatible arguments (e.g. handlers specified together with filename/filemode, or filename/filemode specified together with stream, or handlers specified together with stream.

Changed in version 3.8: Added the force parameter.

Changed in version 3.9: Added the encoding and errors parameters.

def captureWarnings(capture):
2332def captureWarnings(capture):
2333    """
2334    If capture is true, redirect all warnings to the logging package.
2335    If capture is False, ensure that warnings are not redirected to logging
2336    but to their original destinations.
2337    """
2338    global _warnings_showwarning
2339    if capture:
2340        if _warnings_showwarning is None:
2341            _warnings_showwarning = warnings.showwarning
2342            warnings.showwarning = _showwarning
2343    else:
2344        if _warnings_showwarning is not None:
2345            warnings.showwarning = _warnings_showwarning
2346            _warnings_showwarning = None

If capture is true, redirect all warnings to the logging package. If capture is False, ensure that warnings are not redirected to logging but to their original destinations.

def critical(msg, *args, **kwargs):
2160def critical(msg, *args, **kwargs):
2161    """
2162    Log a message with severity 'CRITICAL' on the root logger. If the logger
2163    has no handlers, call basicConfig() to add a console handler with a
2164    pre-defined format.
2165    """
2166    if len(root.handlers) == 0:
2167        basicConfig()
2168    root.critical(msg, *args, **kwargs)

Log a message with severity 'CRITICAL' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format.

def debug(msg, *args, **kwargs):
2219def debug(msg, *args, **kwargs):
2220    """
2221    Log a message with severity 'DEBUG' on the root logger. If the logger has
2222    no handlers, call basicConfig() to add a console handler with a pre-defined
2223    format.
2224    """
2225    if len(root.handlers) == 0:
2226        basicConfig()
2227    root.debug(msg, *args, **kwargs)

Log a message with severity 'DEBUG' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format.

def disable(level=50):
2239def disable(level=CRITICAL):
2240    """
2241    Disable all logging calls of severity 'level' and below.
2242    """
2243    root.manager.disable = level
2244    root.manager._clear_cache()

Disable all logging calls of severity 'level' and below.

def error(msg, *args, **kwargs):
2176def error(msg, *args, **kwargs):
2177    """
2178    Log a message with severity 'ERROR' on the root logger. If the logger has
2179    no handlers, call basicConfig() to add a console handler with a pre-defined
2180    format.
2181    """
2182    if len(root.handlers) == 0:
2183        basicConfig()
2184    root.error(msg, *args, **kwargs)

Log a message with severity 'ERROR' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format.

def exception(msg, *args, exc_info=True, **kwargs):
2186def exception(msg, *args, exc_info=True, **kwargs):
2187    """
2188    Log a message with severity 'ERROR' on the root logger, with exception
2189    information. If the logger has no handlers, basicConfig() is called to add
2190    a console handler with a pre-defined format.
2191    """
2192    error(msg, *args, exc_info=exc_info, **kwargs)

Log a message with severity 'ERROR' on the root logger, with exception information. If the logger has no handlers, basicConfig() is called to add a console handler with a pre-defined format.

def fatal(msg, *args, **kwargs):
2170def fatal(msg, *args, **kwargs):
2171    """
2172    Don't use this function, use critical() instead.
2173    """
2174    critical(msg, *args, **kwargs)

Don't use this function, use critical() instead.

def getLevelName(level):
130def getLevelName(level):
131    """
132    Return the textual or numeric representation of logging level 'level'.
133
134    If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
135    INFO, DEBUG) then you get the corresponding string. If you have
136    associated levels with names using addLevelName then the name you have
137    associated with 'level' is returned.
138
139    If a numeric value corresponding to one of the defined levels is passed
140    in, the corresponding string representation is returned.
141
142    If a string representation of the level is passed in, the corresponding
143    numeric value is returned.
144
145    If no matching numeric or string value is passed in, the string
146    'Level %s' % level is returned.
147    """
148    # See Issues #22386, #27937 and #29220 for why it's this way
149    result = _levelToName.get(level)
150    if result is not None:
151        return result
152    result = _nameToLevel.get(level)
153    if result is not None:
154        return result
155    return "Level %s" % level

Return the textual or numeric representation of logging level 'level'.

If the level is one of the predefined levels (CRITICAL, ERROR, WARNING, INFO, DEBUG) then you get the corresponding string. If you have associated levels with names using addLevelName then the name you have associated with 'level' is returned.

If a numeric value corresponding to one of the defined levels is passed in, the corresponding string representation is returned.

If a string representation of the level is passed in, the corresponding numeric value is returned.

If no matching numeric or string value is passed in, the string 'Level %s' % level is returned.

def getLogger(name=None):
2150def getLogger(name=None):
2151    """
2152    Return a logger with the specified name, creating it if necessary.
2153
2154    If no name is specified, return the root logger.
2155    """
2156    if not name or isinstance(name, str) and name == root.name:
2157        return root
2158    return Logger.manager.getLogger(name)

Return a logger with the specified name, creating it if necessary.

If no name is specified, return the root logger.

def getLoggerClass():
1348def getLoggerClass():
1349    """
1350    Return the class to be used when instantiating a logger.
1351    """
1352    return _loggerClass

Return the class to be used when instantiating a logger.

def info(msg, *args, **kwargs):
2209def info(msg, *args, **kwargs):
2210    """
2211    Log a message with severity 'INFO' on the root logger. If the logger has
2212    no handlers, call basicConfig() to add a console handler with a pre-defined
2213    format.
2214    """
2215    if len(root.handlers) == 0:
2216        basicConfig()
2217    root.info(msg, *args, **kwargs)

Log a message with severity 'INFO' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format.

def log(level, msg, *args, **kwargs):
2229def log(level, msg, *args, **kwargs):
2230    """
2231    Log 'msg % args' with the integer severity 'level' on the root logger. If
2232    the logger has no handlers, call basicConfig() to add a console handler
2233    with a pre-defined format.
2234    """
2235    if len(root.handlers) == 0:
2236        basicConfig()
2237    root.log(level, msg, *args, **kwargs)

Log 'msg % args' with the integer severity 'level' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format.

def makeLogRecord(dict):
418def makeLogRecord(dict):
419    """
420    Make a LogRecord whose attributes are defined by the specified dictionary,
421    This function is useful for converting a logging event received over
422    a socket connection (which is sent as a dictionary) into a LogRecord
423    instance.
424    """
425    rv = _logRecordFactory(None, None, "", 0, "", (), None, None)
426    rv.__dict__.update(dict)
427    return rv

Make a LogRecord whose attributes are defined by the specified dictionary, This function is useful for converting a logging event received over a socket connection (which is sent as a dictionary) into a LogRecord instance.

def setLoggerClass(klass):
1335def setLoggerClass(klass):
1336    """
1337    Set the class to be used when instantiating a logger. The class should
1338    define __init__() such that only a name argument is required, and the
1339    __init__() should call Logger.__init__()
1340    """
1341    if klass != Logger:
1342        if not issubclass(klass, Logger):
1343            raise TypeError("logger not derived from logging.Logger: "
1344                            + klass.__name__)
1345    global _loggerClass
1346    _loggerClass = klass

Set the class to be used when instantiating a logger. The class should define __init__() such that only a name argument is required, and the __init__() should call Logger.__init__()

def shutdown( handlerList=[<weakref at 0x7f976ffefbf0; to '_StderrHandler'>, <weakref at 0x7f976f2692b0; to 'NullHandler'>, <weakref at 0x7f976f136d90; to 'NullHandler'>, <weakref at 0x7f976f28bd80; to 'NullHandler'>]):
2246def shutdown(handlerList=_handlerList):
2247    """
2248    Perform any cleanup actions in the logging system (e.g. flushing
2249    buffers).
2250
2251    Should be called at application exit.
2252    """
2253    for wr in reversed(handlerList[:]):
2254        #errors might occur, for example, if files are locked
2255        #we just ignore them if raiseExceptions is not set
2256        try:
2257            h = wr()
2258            if h:
2259                try:
2260                    h.acquire()
2261                    # MemoryHandlers might not want to be flushed on close,
2262                    # but circular imports prevent us scoping this to just
2263                    # those handlers.  hence the default to True.
2264                    if getattr(h, 'flushOnClose', True):
2265                        h.flush()
2266                    h.close()
2267                except (OSError, ValueError):
2268                    # Ignore errors which might be caused
2269                    # because handlers have been closed but
2270                    # references to them are still around at
2271                    # application exit.
2272                    pass
2273                finally:
2274                    h.release()
2275        except: # ignore everything, as we're shutting down
2276            if raiseExceptions:
2277                raise
2278            #else, swallow

Perform any cleanup actions in the logging system (e.g. flushing buffers).

Should be called at application exit.

def warn(msg, *args, **kwargs):
2204def warn(msg, *args, **kwargs):
2205    warnings.warn("The 'warn' function is deprecated, "
2206        "use 'warning' instead", DeprecationWarning, 2)
2207    warning(msg, *args, **kwargs)
def warning(msg, *args, **kwargs):
2194def warning(msg, *args, **kwargs):
2195    """
2196    Log a message with severity 'WARNING' on the root logger. If the logger has
2197    no handlers, call basicConfig() to add a console handler with a pre-defined
2198    format.
2199    """
2200    if len(root.handlers) == 0:
2201        basicConfig()
2202    root.warning(msg, *args, **kwargs)

Log a message with severity 'WARNING' on the root logger. If the logger has no handlers, call basicConfig() to add a console handler with a pre-defined format.

def getLogRecordFactory():
411def getLogRecordFactory():
412    """
413    Return the factory to be used when instantiating a log record.
414    """
415
416    return _logRecordFactory

Return the factory to be used when instantiating a log record.

def setLogRecordFactory(factory):
401def setLogRecordFactory(factory):
402    """
403    Set the factory to be used when instantiating a log record.
404
405    :param factory: A callable which will be called to instantiate
406    a log record.
407    """
408    global _logRecordFactory
409    _logRecordFactory = factory

Set the factory to be used when instantiating a log record.

Parameters
  • factory: A callable which will be called to instantiate a log record.
lastResort = <_StderrHandler <stderr> (WARNING)>
raiseExceptions = True
def getLevelNamesMapping():
127def getLevelNamesMapping():
128    return _nameToLevel.copy()
def getHandlerByName(name):
904def getHandlerByName(name):
905    """
906    Get a handler with the specified *name*, or None if there isn't one with
907    that name.
908    """
909    return _handlers.get(name)

Get a handler with the specified name, or None if there isn't one with that name.

def getHandlerNames():
912def getHandlerNames():
913    """
914    Return all known handler names as an immutable set.
915    """
916    result = set(_handlers.keys())
917    return frozenset(result)

Return all known handler names as an immutable set.