17db96d56Sopenharmony_ci# Copyright 2001-2019 by Vinay Sajip. All Rights Reserved.
27db96d56Sopenharmony_ci#
37db96d56Sopenharmony_ci# Permission to use, copy, modify, and distribute this software and its
47db96d56Sopenharmony_ci# documentation for any purpose and without fee is hereby granted,
57db96d56Sopenharmony_ci# provided that the above copyright notice appear in all copies and that
67db96d56Sopenharmony_ci# both that copyright notice and this permission notice appear in
77db96d56Sopenharmony_ci# supporting documentation, and that the name of Vinay Sajip
87db96d56Sopenharmony_ci# not be used in advertising or publicity pertaining to distribution
97db96d56Sopenharmony_ci# of the software without specific, written prior permission.
107db96d56Sopenharmony_ci# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
117db96d56Sopenharmony_ci# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
127db96d56Sopenharmony_ci# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
137db96d56Sopenharmony_ci# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
147db96d56Sopenharmony_ci# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
157db96d56Sopenharmony_ci# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci"""
187db96d56Sopenharmony_ciLogging package for Python. Based on PEP 282 and comments thereto in
197db96d56Sopenharmony_cicomp.lang.python.
207db96d56Sopenharmony_ci
217db96d56Sopenharmony_ciCopyright (C) 2001-2019 Vinay Sajip. All Rights Reserved.
227db96d56Sopenharmony_ci
237db96d56Sopenharmony_ciTo use, simply 'import logging' and log away!
247db96d56Sopenharmony_ci"""
257db96d56Sopenharmony_ci
267db96d56Sopenharmony_ciimport sys, os, time, io, re, traceback, warnings, weakref, collections.abc
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_cifrom types import GenericAlias
297db96d56Sopenharmony_cifrom string import Template
307db96d56Sopenharmony_cifrom string import Formatter as StrFormatter
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ci__all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
347db96d56Sopenharmony_ci           'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO',
357db96d56Sopenharmony_ci           'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler',
367db96d56Sopenharmony_ci           'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig',
377db96d56Sopenharmony_ci           'captureWarnings', 'critical', 'debug', 'disable', 'error',
387db96d56Sopenharmony_ci           'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass',
397db96d56Sopenharmony_ci           'info', 'log', 'makeLogRecord', 'setLoggerClass', 'shutdown',
407db96d56Sopenharmony_ci           'warn', 'warning', 'getLogRecordFactory', 'setLogRecordFactory',
417db96d56Sopenharmony_ci           'lastResort', 'raiseExceptions', 'getLevelNamesMapping']
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ciimport threading
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_ci__author__  = "Vinay Sajip <vinay_sajip@red-dove.com>"
467db96d56Sopenharmony_ci__status__  = "production"
477db96d56Sopenharmony_ci# The following module attributes are no longer updated.
487db96d56Sopenharmony_ci__version__ = "0.5.1.2"
497db96d56Sopenharmony_ci__date__    = "07 February 2010"
507db96d56Sopenharmony_ci
517db96d56Sopenharmony_ci#---------------------------------------------------------------------------
527db96d56Sopenharmony_ci#   Miscellaneous module data
537db96d56Sopenharmony_ci#---------------------------------------------------------------------------
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ci#
567db96d56Sopenharmony_ci#_startTime is used as the base when calculating the relative time of events
577db96d56Sopenharmony_ci#
587db96d56Sopenharmony_ci_startTime = time.time()
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ci#
617db96d56Sopenharmony_ci#raiseExceptions is used to see if exceptions during handling should be
627db96d56Sopenharmony_ci#propagated
637db96d56Sopenharmony_ci#
647db96d56Sopenharmony_ciraiseExceptions = True
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_ci#
677db96d56Sopenharmony_ci# If you don't want threading information in the log, set this to zero
687db96d56Sopenharmony_ci#
697db96d56Sopenharmony_cilogThreads = True
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci#
727db96d56Sopenharmony_ci# If you don't want multiprocessing information in the log, set this to zero
737db96d56Sopenharmony_ci#
747db96d56Sopenharmony_cilogMultiprocessing = True
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ci#
777db96d56Sopenharmony_ci# If you don't want process information in the log, set this to zero
787db96d56Sopenharmony_ci#
797db96d56Sopenharmony_cilogProcesses = True
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ci#---------------------------------------------------------------------------
827db96d56Sopenharmony_ci#   Level related stuff
837db96d56Sopenharmony_ci#---------------------------------------------------------------------------
847db96d56Sopenharmony_ci#
857db96d56Sopenharmony_ci# Default levels and level names, these can be replaced with any positive set
867db96d56Sopenharmony_ci# of values having corresponding names. There is a pseudo-level, NOTSET, which
877db96d56Sopenharmony_ci# is only really there as a lower limit for user-defined levels. Handlers and
887db96d56Sopenharmony_ci# loggers are initialized with NOTSET so that they will log all messages, even
897db96d56Sopenharmony_ci# at user-defined levels.
907db96d56Sopenharmony_ci#
917db96d56Sopenharmony_ci
927db96d56Sopenharmony_ciCRITICAL = 50
937db96d56Sopenharmony_ciFATAL = CRITICAL
947db96d56Sopenharmony_ciERROR = 40
957db96d56Sopenharmony_ciWARNING = 30
967db96d56Sopenharmony_ciWARN = WARNING
977db96d56Sopenharmony_ciINFO = 20
987db96d56Sopenharmony_ciDEBUG = 10
997db96d56Sopenharmony_ciNOTSET = 0
1007db96d56Sopenharmony_ci
1017db96d56Sopenharmony_ci_levelToName = {
1027db96d56Sopenharmony_ci    CRITICAL: 'CRITICAL',
1037db96d56Sopenharmony_ci    ERROR: 'ERROR',
1047db96d56Sopenharmony_ci    WARNING: 'WARNING',
1057db96d56Sopenharmony_ci    INFO: 'INFO',
1067db96d56Sopenharmony_ci    DEBUG: 'DEBUG',
1077db96d56Sopenharmony_ci    NOTSET: 'NOTSET',
1087db96d56Sopenharmony_ci}
1097db96d56Sopenharmony_ci_nameToLevel = {
1107db96d56Sopenharmony_ci    'CRITICAL': CRITICAL,
1117db96d56Sopenharmony_ci    'FATAL': FATAL,
1127db96d56Sopenharmony_ci    'ERROR': ERROR,
1137db96d56Sopenharmony_ci    'WARN': WARNING,
1147db96d56Sopenharmony_ci    'WARNING': WARNING,
1157db96d56Sopenharmony_ci    'INFO': INFO,
1167db96d56Sopenharmony_ci    'DEBUG': DEBUG,
1177db96d56Sopenharmony_ci    'NOTSET': NOTSET,
1187db96d56Sopenharmony_ci}
1197db96d56Sopenharmony_ci
1207db96d56Sopenharmony_cidef getLevelNamesMapping():
1217db96d56Sopenharmony_ci    return _nameToLevel.copy()
1227db96d56Sopenharmony_ci
1237db96d56Sopenharmony_cidef getLevelName(level):
1247db96d56Sopenharmony_ci    """
1257db96d56Sopenharmony_ci    Return the textual or numeric representation of logging level 'level'.
1267db96d56Sopenharmony_ci
1277db96d56Sopenharmony_ci    If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
1287db96d56Sopenharmony_ci    INFO, DEBUG) then you get the corresponding string. If you have
1297db96d56Sopenharmony_ci    associated levels with names using addLevelName then the name you have
1307db96d56Sopenharmony_ci    associated with 'level' is returned.
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_ci    If a numeric value corresponding to one of the defined levels is passed
1337db96d56Sopenharmony_ci    in, the corresponding string representation is returned.
1347db96d56Sopenharmony_ci
1357db96d56Sopenharmony_ci    If a string representation of the level is passed in, the corresponding
1367db96d56Sopenharmony_ci    numeric value is returned.
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci    If no matching numeric or string value is passed in, the string
1397db96d56Sopenharmony_ci    'Level %s' % level is returned.
1407db96d56Sopenharmony_ci    """
1417db96d56Sopenharmony_ci    # See Issues #22386, #27937 and #29220 for why it's this way
1427db96d56Sopenharmony_ci    result = _levelToName.get(level)
1437db96d56Sopenharmony_ci    if result is not None:
1447db96d56Sopenharmony_ci        return result
1457db96d56Sopenharmony_ci    result = _nameToLevel.get(level)
1467db96d56Sopenharmony_ci    if result is not None:
1477db96d56Sopenharmony_ci        return result
1487db96d56Sopenharmony_ci    return "Level %s" % level
1497db96d56Sopenharmony_ci
1507db96d56Sopenharmony_cidef addLevelName(level, levelName):
1517db96d56Sopenharmony_ci    """
1527db96d56Sopenharmony_ci    Associate 'levelName' with 'level'.
1537db96d56Sopenharmony_ci
1547db96d56Sopenharmony_ci    This is used when converting levels to text during message formatting.
1557db96d56Sopenharmony_ci    """
1567db96d56Sopenharmony_ci    _acquireLock()
1577db96d56Sopenharmony_ci    try:    #unlikely to cause an exception, but you never know...
1587db96d56Sopenharmony_ci        _levelToName[level] = levelName
1597db96d56Sopenharmony_ci        _nameToLevel[levelName] = level
1607db96d56Sopenharmony_ci    finally:
1617db96d56Sopenharmony_ci        _releaseLock()
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ciif hasattr(sys, "_getframe"):
1647db96d56Sopenharmony_ci    currentframe = lambda: sys._getframe(1)
1657db96d56Sopenharmony_cielse: #pragma: no cover
1667db96d56Sopenharmony_ci    def currentframe():
1677db96d56Sopenharmony_ci        """Return the frame object for the caller's stack frame."""
1687db96d56Sopenharmony_ci        try:
1697db96d56Sopenharmony_ci            raise Exception
1707db96d56Sopenharmony_ci        except Exception:
1717db96d56Sopenharmony_ci            return sys.exc_info()[2].tb_frame.f_back
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_ci#
1747db96d56Sopenharmony_ci# _srcfile is used when walking the stack to check when we've got the first
1757db96d56Sopenharmony_ci# caller stack frame, by skipping frames whose filename is that of this
1767db96d56Sopenharmony_ci# module's source. It therefore should contain the filename of this module's
1777db96d56Sopenharmony_ci# source file.
1787db96d56Sopenharmony_ci#
1797db96d56Sopenharmony_ci# Ordinarily we would use __file__ for this, but frozen modules don't always
1807db96d56Sopenharmony_ci# have __file__ set, for some reason (see Issue #21736). Thus, we get the
1817db96d56Sopenharmony_ci# filename from a handy code object from a function defined in this module.
1827db96d56Sopenharmony_ci# (There's no particular reason for picking addLevelName.)
1837db96d56Sopenharmony_ci#
1847db96d56Sopenharmony_ci
1857db96d56Sopenharmony_ci_srcfile = os.path.normcase(addLevelName.__code__.co_filename)
1867db96d56Sopenharmony_ci
1877db96d56Sopenharmony_ci# _srcfile is only used in conjunction with sys._getframe().
1887db96d56Sopenharmony_ci# Setting _srcfile to None will prevent findCaller() from being called. This
1897db96d56Sopenharmony_ci# way, you can avoid the overhead of fetching caller information.
1907db96d56Sopenharmony_ci
1917db96d56Sopenharmony_ci# The following is based on warnings._is_internal_frame. It makes sure that
1927db96d56Sopenharmony_ci# frames of the import mechanism are skipped when logging at module level and
1937db96d56Sopenharmony_ci# using a stacklevel value greater than one.
1947db96d56Sopenharmony_cidef _is_internal_frame(frame):
1957db96d56Sopenharmony_ci    """Signal whether the frame is a CPython or logging module internal."""
1967db96d56Sopenharmony_ci    filename = os.path.normcase(frame.f_code.co_filename)
1977db96d56Sopenharmony_ci    return filename == _srcfile or (
1987db96d56Sopenharmony_ci        "importlib" in filename and "_bootstrap" in filename
1997db96d56Sopenharmony_ci    )
2007db96d56Sopenharmony_ci
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_cidef _checkLevel(level):
2037db96d56Sopenharmony_ci    if isinstance(level, int):
2047db96d56Sopenharmony_ci        rv = level
2057db96d56Sopenharmony_ci    elif str(level) == level:
2067db96d56Sopenharmony_ci        if level not in _nameToLevel:
2077db96d56Sopenharmony_ci            raise ValueError("Unknown level: %r" % level)
2087db96d56Sopenharmony_ci        rv = _nameToLevel[level]
2097db96d56Sopenharmony_ci    else:
2107db96d56Sopenharmony_ci        raise TypeError("Level not an integer or a valid string: %r"
2117db96d56Sopenharmony_ci                        % (level,))
2127db96d56Sopenharmony_ci    return rv
2137db96d56Sopenharmony_ci
2147db96d56Sopenharmony_ci#---------------------------------------------------------------------------
2157db96d56Sopenharmony_ci#   Thread-related stuff
2167db96d56Sopenharmony_ci#---------------------------------------------------------------------------
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ci#
2197db96d56Sopenharmony_ci#_lock is used to serialize access to shared data structures in this module.
2207db96d56Sopenharmony_ci#This needs to be an RLock because fileConfig() creates and configures
2217db96d56Sopenharmony_ci#Handlers, and so might arbitrary user threads. Since Handler code updates the
2227db96d56Sopenharmony_ci#shared dictionary _handlers, it needs to acquire the lock. But if configuring,
2237db96d56Sopenharmony_ci#the lock would already have been acquired - so we need an RLock.
2247db96d56Sopenharmony_ci#The same argument applies to Loggers and Manager.loggerDict.
2257db96d56Sopenharmony_ci#
2267db96d56Sopenharmony_ci_lock = threading.RLock()
2277db96d56Sopenharmony_ci
2287db96d56Sopenharmony_cidef _acquireLock():
2297db96d56Sopenharmony_ci    """
2307db96d56Sopenharmony_ci    Acquire the module-level lock for serializing access to shared data.
2317db96d56Sopenharmony_ci
2327db96d56Sopenharmony_ci    This should be released with _releaseLock().
2337db96d56Sopenharmony_ci    """
2347db96d56Sopenharmony_ci    if _lock:
2357db96d56Sopenharmony_ci        _lock.acquire()
2367db96d56Sopenharmony_ci
2377db96d56Sopenharmony_cidef _releaseLock():
2387db96d56Sopenharmony_ci    """
2397db96d56Sopenharmony_ci    Release the module-level lock acquired by calling _acquireLock().
2407db96d56Sopenharmony_ci    """
2417db96d56Sopenharmony_ci    if _lock:
2427db96d56Sopenharmony_ci        _lock.release()
2437db96d56Sopenharmony_ci
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ci# Prevent a held logging lock from blocking a child from logging.
2467db96d56Sopenharmony_ci
2477db96d56Sopenharmony_ciif not hasattr(os, 'register_at_fork'):  # Windows and friends.
2487db96d56Sopenharmony_ci    def _register_at_fork_reinit_lock(instance):
2497db96d56Sopenharmony_ci        pass  # no-op when os.register_at_fork does not exist.
2507db96d56Sopenharmony_cielse:
2517db96d56Sopenharmony_ci    # A collection of instances with a _at_fork_reinit method (logging.Handler)
2527db96d56Sopenharmony_ci    # to be called in the child after forking.  The weakref avoids us keeping
2537db96d56Sopenharmony_ci    # discarded Handler instances alive.
2547db96d56Sopenharmony_ci    _at_fork_reinit_lock_weakset = weakref.WeakSet()
2557db96d56Sopenharmony_ci
2567db96d56Sopenharmony_ci    def _register_at_fork_reinit_lock(instance):
2577db96d56Sopenharmony_ci        _acquireLock()
2587db96d56Sopenharmony_ci        try:
2597db96d56Sopenharmony_ci            _at_fork_reinit_lock_weakset.add(instance)
2607db96d56Sopenharmony_ci        finally:
2617db96d56Sopenharmony_ci            _releaseLock()
2627db96d56Sopenharmony_ci
2637db96d56Sopenharmony_ci    def _after_at_fork_child_reinit_locks():
2647db96d56Sopenharmony_ci        for handler in _at_fork_reinit_lock_weakset:
2657db96d56Sopenharmony_ci            handler._at_fork_reinit()
2667db96d56Sopenharmony_ci
2677db96d56Sopenharmony_ci        # _acquireLock() was called in the parent before forking.
2687db96d56Sopenharmony_ci        # The lock is reinitialized to unlocked state.
2697db96d56Sopenharmony_ci        _lock._at_fork_reinit()
2707db96d56Sopenharmony_ci
2717db96d56Sopenharmony_ci    os.register_at_fork(before=_acquireLock,
2727db96d56Sopenharmony_ci                        after_in_child=_after_at_fork_child_reinit_locks,
2737db96d56Sopenharmony_ci                        after_in_parent=_releaseLock)
2747db96d56Sopenharmony_ci
2757db96d56Sopenharmony_ci
2767db96d56Sopenharmony_ci#---------------------------------------------------------------------------
2777db96d56Sopenharmony_ci#   The logging record
2787db96d56Sopenharmony_ci#---------------------------------------------------------------------------
2797db96d56Sopenharmony_ci
2807db96d56Sopenharmony_ciclass LogRecord(object):
2817db96d56Sopenharmony_ci    """
2827db96d56Sopenharmony_ci    A LogRecord instance represents an event being logged.
2837db96d56Sopenharmony_ci
2847db96d56Sopenharmony_ci    LogRecord instances are created every time something is logged. They
2857db96d56Sopenharmony_ci    contain all the information pertinent to the event being logged. The
2867db96d56Sopenharmony_ci    main information passed in is in msg and args, which are combined
2877db96d56Sopenharmony_ci    using str(msg) % args to create the message field of the record. The
2887db96d56Sopenharmony_ci    record also includes information such as when the record was created,
2897db96d56Sopenharmony_ci    the source line where the logging call was made, and any exception
2907db96d56Sopenharmony_ci    information to be logged.
2917db96d56Sopenharmony_ci    """
2927db96d56Sopenharmony_ci    def __init__(self, name, level, pathname, lineno,
2937db96d56Sopenharmony_ci                 msg, args, exc_info, func=None, sinfo=None, **kwargs):
2947db96d56Sopenharmony_ci        """
2957db96d56Sopenharmony_ci        Initialize a logging record with interesting information.
2967db96d56Sopenharmony_ci        """
2977db96d56Sopenharmony_ci        ct = time.time()
2987db96d56Sopenharmony_ci        self.name = name
2997db96d56Sopenharmony_ci        self.msg = msg
3007db96d56Sopenharmony_ci        #
3017db96d56Sopenharmony_ci        # The following statement allows passing of a dictionary as a sole
3027db96d56Sopenharmony_ci        # argument, so that you can do something like
3037db96d56Sopenharmony_ci        #  logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
3047db96d56Sopenharmony_ci        # Suggested by Stefan Behnel.
3057db96d56Sopenharmony_ci        # Note that without the test for args[0], we get a problem because
3067db96d56Sopenharmony_ci        # during formatting, we test to see if the arg is present using
3077db96d56Sopenharmony_ci        # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
3087db96d56Sopenharmony_ci        # and if the passed arg fails 'if self.args:' then no formatting
3097db96d56Sopenharmony_ci        # is done. For example, logger.warning('Value is %d', 0) would log
3107db96d56Sopenharmony_ci        # 'Value is %d' instead of 'Value is 0'.
3117db96d56Sopenharmony_ci        # For the use case of passing a dictionary, this should not be a
3127db96d56Sopenharmony_ci        # problem.
3137db96d56Sopenharmony_ci        # Issue #21172: a request was made to relax the isinstance check
3147db96d56Sopenharmony_ci        # to hasattr(args[0], '__getitem__'). However, the docs on string
3157db96d56Sopenharmony_ci        # formatting still seem to suggest a mapping object is required.
3167db96d56Sopenharmony_ci        # Thus, while not removing the isinstance check, it does now look
3177db96d56Sopenharmony_ci        # for collections.abc.Mapping rather than, as before, dict.
3187db96d56Sopenharmony_ci        if (args and len(args) == 1 and isinstance(args[0], collections.abc.Mapping)
3197db96d56Sopenharmony_ci            and args[0]):
3207db96d56Sopenharmony_ci            args = args[0]
3217db96d56Sopenharmony_ci        self.args = args
3227db96d56Sopenharmony_ci        self.levelname = getLevelName(level)
3237db96d56Sopenharmony_ci        self.levelno = level
3247db96d56Sopenharmony_ci        self.pathname = pathname
3257db96d56Sopenharmony_ci        try:
3267db96d56Sopenharmony_ci            self.filename = os.path.basename(pathname)
3277db96d56Sopenharmony_ci            self.module = os.path.splitext(self.filename)[0]
3287db96d56Sopenharmony_ci        except (TypeError, ValueError, AttributeError):
3297db96d56Sopenharmony_ci            self.filename = pathname
3307db96d56Sopenharmony_ci            self.module = "Unknown module"
3317db96d56Sopenharmony_ci        self.exc_info = exc_info
3327db96d56Sopenharmony_ci        self.exc_text = None      # used to cache the traceback text
3337db96d56Sopenharmony_ci        self.stack_info = sinfo
3347db96d56Sopenharmony_ci        self.lineno = lineno
3357db96d56Sopenharmony_ci        self.funcName = func
3367db96d56Sopenharmony_ci        self.created = ct
3377db96d56Sopenharmony_ci        self.msecs = int((ct - int(ct)) * 1000) + 0.0  # see gh-89047
3387db96d56Sopenharmony_ci        self.relativeCreated = (self.created - _startTime) * 1000
3397db96d56Sopenharmony_ci        if logThreads:
3407db96d56Sopenharmony_ci            self.thread = threading.get_ident()
3417db96d56Sopenharmony_ci            self.threadName = threading.current_thread().name
3427db96d56Sopenharmony_ci        else: # pragma: no cover
3437db96d56Sopenharmony_ci            self.thread = None
3447db96d56Sopenharmony_ci            self.threadName = None
3457db96d56Sopenharmony_ci        if not logMultiprocessing: # pragma: no cover
3467db96d56Sopenharmony_ci            self.processName = None
3477db96d56Sopenharmony_ci        else:
3487db96d56Sopenharmony_ci            self.processName = 'MainProcess'
3497db96d56Sopenharmony_ci            mp = sys.modules.get('multiprocessing')
3507db96d56Sopenharmony_ci            if mp is not None:
3517db96d56Sopenharmony_ci                # Errors may occur if multiprocessing has not finished loading
3527db96d56Sopenharmony_ci                # yet - e.g. if a custom import hook causes third-party code
3537db96d56Sopenharmony_ci                # to run when multiprocessing calls import. See issue 8200
3547db96d56Sopenharmony_ci                # for an example
3557db96d56Sopenharmony_ci                try:
3567db96d56Sopenharmony_ci                    self.processName = mp.current_process().name
3577db96d56Sopenharmony_ci                except Exception: #pragma: no cover
3587db96d56Sopenharmony_ci                    pass
3597db96d56Sopenharmony_ci        if logProcesses and hasattr(os, 'getpid'):
3607db96d56Sopenharmony_ci            self.process = os.getpid()
3617db96d56Sopenharmony_ci        else:
3627db96d56Sopenharmony_ci            self.process = None
3637db96d56Sopenharmony_ci
3647db96d56Sopenharmony_ci    def __repr__(self):
3657db96d56Sopenharmony_ci        return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
3667db96d56Sopenharmony_ci            self.pathname, self.lineno, self.msg)
3677db96d56Sopenharmony_ci
3687db96d56Sopenharmony_ci    def getMessage(self):
3697db96d56Sopenharmony_ci        """
3707db96d56Sopenharmony_ci        Return the message for this LogRecord.
3717db96d56Sopenharmony_ci
3727db96d56Sopenharmony_ci        Return the message for this LogRecord after merging any user-supplied
3737db96d56Sopenharmony_ci        arguments with the message.
3747db96d56Sopenharmony_ci        """
3757db96d56Sopenharmony_ci        msg = str(self.msg)
3767db96d56Sopenharmony_ci        if self.args:
3777db96d56Sopenharmony_ci            msg = msg % self.args
3787db96d56Sopenharmony_ci        return msg
3797db96d56Sopenharmony_ci
3807db96d56Sopenharmony_ci#
3817db96d56Sopenharmony_ci#   Determine which class to use when instantiating log records.
3827db96d56Sopenharmony_ci#
3837db96d56Sopenharmony_ci_logRecordFactory = LogRecord
3847db96d56Sopenharmony_ci
3857db96d56Sopenharmony_cidef setLogRecordFactory(factory):
3867db96d56Sopenharmony_ci    """
3877db96d56Sopenharmony_ci    Set the factory to be used when instantiating a log record.
3887db96d56Sopenharmony_ci
3897db96d56Sopenharmony_ci    :param factory: A callable which will be called to instantiate
3907db96d56Sopenharmony_ci    a log record.
3917db96d56Sopenharmony_ci    """
3927db96d56Sopenharmony_ci    global _logRecordFactory
3937db96d56Sopenharmony_ci    _logRecordFactory = factory
3947db96d56Sopenharmony_ci
3957db96d56Sopenharmony_cidef getLogRecordFactory():
3967db96d56Sopenharmony_ci    """
3977db96d56Sopenharmony_ci    Return the factory to be used when instantiating a log record.
3987db96d56Sopenharmony_ci    """
3997db96d56Sopenharmony_ci
4007db96d56Sopenharmony_ci    return _logRecordFactory
4017db96d56Sopenharmony_ci
4027db96d56Sopenharmony_cidef makeLogRecord(dict):
4037db96d56Sopenharmony_ci    """
4047db96d56Sopenharmony_ci    Make a LogRecord whose attributes are defined by the specified dictionary,
4057db96d56Sopenharmony_ci    This function is useful for converting a logging event received over
4067db96d56Sopenharmony_ci    a socket connection (which is sent as a dictionary) into a LogRecord
4077db96d56Sopenharmony_ci    instance.
4087db96d56Sopenharmony_ci    """
4097db96d56Sopenharmony_ci    rv = _logRecordFactory(None, None, "", 0, "", (), None, None)
4107db96d56Sopenharmony_ci    rv.__dict__.update(dict)
4117db96d56Sopenharmony_ci    return rv
4127db96d56Sopenharmony_ci
4137db96d56Sopenharmony_ci
4147db96d56Sopenharmony_ci#---------------------------------------------------------------------------
4157db96d56Sopenharmony_ci#   Formatter classes and functions
4167db96d56Sopenharmony_ci#---------------------------------------------------------------------------
4177db96d56Sopenharmony_ci_str_formatter = StrFormatter()
4187db96d56Sopenharmony_cidel StrFormatter
4197db96d56Sopenharmony_ci
4207db96d56Sopenharmony_ci
4217db96d56Sopenharmony_ciclass PercentStyle(object):
4227db96d56Sopenharmony_ci
4237db96d56Sopenharmony_ci    default_format = '%(message)s'
4247db96d56Sopenharmony_ci    asctime_format = '%(asctime)s'
4257db96d56Sopenharmony_ci    asctime_search = '%(asctime)'
4267db96d56Sopenharmony_ci    validation_pattern = re.compile(r'%\(\w+\)[#0+ -]*(\*|\d+)?(\.(\*|\d+))?[diouxefgcrsa%]', re.I)
4277db96d56Sopenharmony_ci
4287db96d56Sopenharmony_ci    def __init__(self, fmt, *, defaults=None):
4297db96d56Sopenharmony_ci        self._fmt = fmt or self.default_format
4307db96d56Sopenharmony_ci        self._defaults = defaults
4317db96d56Sopenharmony_ci
4327db96d56Sopenharmony_ci    def usesTime(self):
4337db96d56Sopenharmony_ci        return self._fmt.find(self.asctime_search) >= 0
4347db96d56Sopenharmony_ci
4357db96d56Sopenharmony_ci    def validate(self):
4367db96d56Sopenharmony_ci        """Validate the input format, ensure it matches the correct style"""
4377db96d56Sopenharmony_ci        if not self.validation_pattern.search(self._fmt):
4387db96d56Sopenharmony_ci            raise ValueError("Invalid format '%s' for '%s' style" % (self._fmt, self.default_format[0]))
4397db96d56Sopenharmony_ci
4407db96d56Sopenharmony_ci    def _format(self, record):
4417db96d56Sopenharmony_ci        if defaults := self._defaults:
4427db96d56Sopenharmony_ci            values = defaults | record.__dict__
4437db96d56Sopenharmony_ci        else:
4447db96d56Sopenharmony_ci            values = record.__dict__
4457db96d56Sopenharmony_ci        return self._fmt % values
4467db96d56Sopenharmony_ci
4477db96d56Sopenharmony_ci    def format(self, record):
4487db96d56Sopenharmony_ci        try:
4497db96d56Sopenharmony_ci            return self._format(record)
4507db96d56Sopenharmony_ci        except KeyError as e:
4517db96d56Sopenharmony_ci            raise ValueError('Formatting field not found in record: %s' % e)
4527db96d56Sopenharmony_ci
4537db96d56Sopenharmony_ci
4547db96d56Sopenharmony_ciclass StrFormatStyle(PercentStyle):
4557db96d56Sopenharmony_ci    default_format = '{message}'
4567db96d56Sopenharmony_ci    asctime_format = '{asctime}'
4577db96d56Sopenharmony_ci    asctime_search = '{asctime'
4587db96d56Sopenharmony_ci
4597db96d56Sopenharmony_ci    fmt_spec = re.compile(r'^(.?[<>=^])?[+ -]?#?0?(\d+|{\w+})?[,_]?(\.(\d+|{\w+}))?[bcdefgnosx%]?$', re.I)
4607db96d56Sopenharmony_ci    field_spec = re.compile(r'^(\d+|\w+)(\.\w+|\[[^]]+\])*$')
4617db96d56Sopenharmony_ci
4627db96d56Sopenharmony_ci    def _format(self, record):
4637db96d56Sopenharmony_ci        if defaults := self._defaults:
4647db96d56Sopenharmony_ci            values = defaults | record.__dict__
4657db96d56Sopenharmony_ci        else:
4667db96d56Sopenharmony_ci            values = record.__dict__
4677db96d56Sopenharmony_ci        return self._fmt.format(**values)
4687db96d56Sopenharmony_ci
4697db96d56Sopenharmony_ci    def validate(self):
4707db96d56Sopenharmony_ci        """Validate the input format, ensure it is the correct string formatting style"""
4717db96d56Sopenharmony_ci        fields = set()
4727db96d56Sopenharmony_ci        try:
4737db96d56Sopenharmony_ci            for _, fieldname, spec, conversion in _str_formatter.parse(self._fmt):
4747db96d56Sopenharmony_ci                if fieldname:
4757db96d56Sopenharmony_ci                    if not self.field_spec.match(fieldname):
4767db96d56Sopenharmony_ci                        raise ValueError('invalid field name/expression: %r' % fieldname)
4777db96d56Sopenharmony_ci                    fields.add(fieldname)
4787db96d56Sopenharmony_ci                if conversion and conversion not in 'rsa':
4797db96d56Sopenharmony_ci                    raise ValueError('invalid conversion: %r' % conversion)
4807db96d56Sopenharmony_ci                if spec and not self.fmt_spec.match(spec):
4817db96d56Sopenharmony_ci                    raise ValueError('bad specifier: %r' % spec)
4827db96d56Sopenharmony_ci        except ValueError as e:
4837db96d56Sopenharmony_ci            raise ValueError('invalid format: %s' % e)
4847db96d56Sopenharmony_ci        if not fields:
4857db96d56Sopenharmony_ci            raise ValueError('invalid format: no fields')
4867db96d56Sopenharmony_ci
4877db96d56Sopenharmony_ci
4887db96d56Sopenharmony_ciclass StringTemplateStyle(PercentStyle):
4897db96d56Sopenharmony_ci    default_format = '${message}'
4907db96d56Sopenharmony_ci    asctime_format = '${asctime}'
4917db96d56Sopenharmony_ci    asctime_search = '${asctime}'
4927db96d56Sopenharmony_ci
4937db96d56Sopenharmony_ci    def __init__(self, *args, **kwargs):
4947db96d56Sopenharmony_ci        super().__init__(*args, **kwargs)
4957db96d56Sopenharmony_ci        self._tpl = Template(self._fmt)
4967db96d56Sopenharmony_ci
4977db96d56Sopenharmony_ci    def usesTime(self):
4987db96d56Sopenharmony_ci        fmt = self._fmt
4997db96d56Sopenharmony_ci        return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_search) >= 0
5007db96d56Sopenharmony_ci
5017db96d56Sopenharmony_ci    def validate(self):
5027db96d56Sopenharmony_ci        pattern = Template.pattern
5037db96d56Sopenharmony_ci        fields = set()
5047db96d56Sopenharmony_ci        for m in pattern.finditer(self._fmt):
5057db96d56Sopenharmony_ci            d = m.groupdict()
5067db96d56Sopenharmony_ci            if d['named']:
5077db96d56Sopenharmony_ci                fields.add(d['named'])
5087db96d56Sopenharmony_ci            elif d['braced']:
5097db96d56Sopenharmony_ci                fields.add(d['braced'])
5107db96d56Sopenharmony_ci            elif m.group(0) == '$':
5117db96d56Sopenharmony_ci                raise ValueError('invalid format: bare \'$\' not allowed')
5127db96d56Sopenharmony_ci        if not fields:
5137db96d56Sopenharmony_ci            raise ValueError('invalid format: no fields')
5147db96d56Sopenharmony_ci
5157db96d56Sopenharmony_ci    def _format(self, record):
5167db96d56Sopenharmony_ci        if defaults := self._defaults:
5177db96d56Sopenharmony_ci            values = defaults | record.__dict__
5187db96d56Sopenharmony_ci        else:
5197db96d56Sopenharmony_ci            values = record.__dict__
5207db96d56Sopenharmony_ci        return self._tpl.substitute(**values)
5217db96d56Sopenharmony_ci
5227db96d56Sopenharmony_ci
5237db96d56Sopenharmony_ciBASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
5247db96d56Sopenharmony_ci
5257db96d56Sopenharmony_ci_STYLES = {
5267db96d56Sopenharmony_ci    '%': (PercentStyle, BASIC_FORMAT),
5277db96d56Sopenharmony_ci    '{': (StrFormatStyle, '{levelname}:{name}:{message}'),
5287db96d56Sopenharmony_ci    '$': (StringTemplateStyle, '${levelname}:${name}:${message}'),
5297db96d56Sopenharmony_ci}
5307db96d56Sopenharmony_ci
5317db96d56Sopenharmony_ciclass Formatter(object):
5327db96d56Sopenharmony_ci    """
5337db96d56Sopenharmony_ci    Formatter instances are used to convert a LogRecord to text.
5347db96d56Sopenharmony_ci
5357db96d56Sopenharmony_ci    Formatters need to know how a LogRecord is constructed. They are
5367db96d56Sopenharmony_ci    responsible for converting a LogRecord to (usually) a string which can
5377db96d56Sopenharmony_ci    be interpreted by either a human or an external system. The base Formatter
5387db96d56Sopenharmony_ci    allows a formatting string to be specified. If none is supplied, the
5397db96d56Sopenharmony_ci    style-dependent default value, "%(message)s", "{message}", or
5407db96d56Sopenharmony_ci    "${message}", is used.
5417db96d56Sopenharmony_ci
5427db96d56Sopenharmony_ci    The Formatter can be initialized with a format string which makes use of
5437db96d56Sopenharmony_ci    knowledge of the LogRecord attributes - e.g. the default value mentioned
5447db96d56Sopenharmony_ci    above makes use of the fact that the user's message and arguments are pre-
5457db96d56Sopenharmony_ci    formatted into a LogRecord's message attribute. Currently, the useful
5467db96d56Sopenharmony_ci    attributes in a LogRecord are described by:
5477db96d56Sopenharmony_ci
5487db96d56Sopenharmony_ci    %(name)s            Name of the logger (logging channel)
5497db96d56Sopenharmony_ci    %(levelno)s         Numeric logging level for the message (DEBUG, INFO,
5507db96d56Sopenharmony_ci                        WARNING, ERROR, CRITICAL)
5517db96d56Sopenharmony_ci    %(levelname)s       Text logging level for the message ("DEBUG", "INFO",
5527db96d56Sopenharmony_ci                        "WARNING", "ERROR", "CRITICAL")
5537db96d56Sopenharmony_ci    %(pathname)s        Full pathname of the source file where the logging
5547db96d56Sopenharmony_ci                        call was issued (if available)
5557db96d56Sopenharmony_ci    %(filename)s        Filename portion of pathname
5567db96d56Sopenharmony_ci    %(module)s          Module (name portion of filename)
5577db96d56Sopenharmony_ci    %(lineno)d          Source line number where the logging call was issued
5587db96d56Sopenharmony_ci                        (if available)
5597db96d56Sopenharmony_ci    %(funcName)s        Function name
5607db96d56Sopenharmony_ci    %(created)f         Time when the LogRecord was created (time.time()
5617db96d56Sopenharmony_ci                        return value)
5627db96d56Sopenharmony_ci    %(asctime)s         Textual time when the LogRecord was created
5637db96d56Sopenharmony_ci    %(msecs)d           Millisecond portion of the creation time
5647db96d56Sopenharmony_ci    %(relativeCreated)d Time in milliseconds when the LogRecord was created,
5657db96d56Sopenharmony_ci                        relative to the time the logging module was loaded
5667db96d56Sopenharmony_ci                        (typically at application startup time)
5677db96d56Sopenharmony_ci    %(thread)d          Thread ID (if available)
5687db96d56Sopenharmony_ci    %(threadName)s      Thread name (if available)
5697db96d56Sopenharmony_ci    %(process)d         Process ID (if available)
5707db96d56Sopenharmony_ci    %(message)s         The result of record.getMessage(), computed just as
5717db96d56Sopenharmony_ci                        the record is emitted
5727db96d56Sopenharmony_ci    """
5737db96d56Sopenharmony_ci
5747db96d56Sopenharmony_ci    converter = time.localtime
5757db96d56Sopenharmony_ci
5767db96d56Sopenharmony_ci    def __init__(self, fmt=None, datefmt=None, style='%', validate=True, *,
5777db96d56Sopenharmony_ci                 defaults=None):
5787db96d56Sopenharmony_ci        """
5797db96d56Sopenharmony_ci        Initialize the formatter with specified format strings.
5807db96d56Sopenharmony_ci
5817db96d56Sopenharmony_ci        Initialize the formatter either with the specified format string, or a
5827db96d56Sopenharmony_ci        default as described above. Allow for specialized date formatting with
5837db96d56Sopenharmony_ci        the optional datefmt argument. If datefmt is omitted, you get an
5847db96d56Sopenharmony_ci        ISO8601-like (or RFC 3339-like) format.
5857db96d56Sopenharmony_ci
5867db96d56Sopenharmony_ci        Use a style parameter of '%', '{' or '$' to specify that you want to
5877db96d56Sopenharmony_ci        use one of %-formatting, :meth:`str.format` (``{}``) formatting or
5887db96d56Sopenharmony_ci        :class:`string.Template` formatting in your format string.
5897db96d56Sopenharmony_ci
5907db96d56Sopenharmony_ci        .. versionchanged:: 3.2
5917db96d56Sopenharmony_ci           Added the ``style`` parameter.
5927db96d56Sopenharmony_ci        """
5937db96d56Sopenharmony_ci        if style not in _STYLES:
5947db96d56Sopenharmony_ci            raise ValueError('Style must be one of: %s' % ','.join(
5957db96d56Sopenharmony_ci                             _STYLES.keys()))
5967db96d56Sopenharmony_ci        self._style = _STYLES[style][0](fmt, defaults=defaults)
5977db96d56Sopenharmony_ci        if validate:
5987db96d56Sopenharmony_ci            self._style.validate()
5997db96d56Sopenharmony_ci
6007db96d56Sopenharmony_ci        self._fmt = self._style._fmt
6017db96d56Sopenharmony_ci        self.datefmt = datefmt
6027db96d56Sopenharmony_ci
6037db96d56Sopenharmony_ci    default_time_format = '%Y-%m-%d %H:%M:%S'
6047db96d56Sopenharmony_ci    default_msec_format = '%s,%03d'
6057db96d56Sopenharmony_ci
6067db96d56Sopenharmony_ci    def formatTime(self, record, datefmt=None):
6077db96d56Sopenharmony_ci        """
6087db96d56Sopenharmony_ci        Return the creation time of the specified LogRecord as formatted text.
6097db96d56Sopenharmony_ci
6107db96d56Sopenharmony_ci        This method should be called from format() by a formatter which
6117db96d56Sopenharmony_ci        wants to make use of a formatted time. This method can be overridden
6127db96d56Sopenharmony_ci        in formatters to provide for any specific requirement, but the
6137db96d56Sopenharmony_ci        basic behaviour is as follows: if datefmt (a string) is specified,
6147db96d56Sopenharmony_ci        it is used with time.strftime() to format the creation time of the
6157db96d56Sopenharmony_ci        record. Otherwise, an ISO8601-like (or RFC 3339-like) format is used.
6167db96d56Sopenharmony_ci        The resulting string is returned. This function uses a user-configurable
6177db96d56Sopenharmony_ci        function to convert the creation time to a tuple. By default,
6187db96d56Sopenharmony_ci        time.localtime() is used; to change this for a particular formatter
6197db96d56Sopenharmony_ci        instance, set the 'converter' attribute to a function with the same
6207db96d56Sopenharmony_ci        signature as time.localtime() or time.gmtime(). To change it for all
6217db96d56Sopenharmony_ci        formatters, for example if you want all logging times to be shown in GMT,
6227db96d56Sopenharmony_ci        set the 'converter' attribute in the Formatter class.
6237db96d56Sopenharmony_ci        """
6247db96d56Sopenharmony_ci        ct = self.converter(record.created)
6257db96d56Sopenharmony_ci        if datefmt:
6267db96d56Sopenharmony_ci            s = time.strftime(datefmt, ct)
6277db96d56Sopenharmony_ci        else:
6287db96d56Sopenharmony_ci            s = time.strftime(self.default_time_format, ct)
6297db96d56Sopenharmony_ci            if self.default_msec_format:
6307db96d56Sopenharmony_ci                s = self.default_msec_format % (s, record.msecs)
6317db96d56Sopenharmony_ci        return s
6327db96d56Sopenharmony_ci
6337db96d56Sopenharmony_ci    def formatException(self, ei):
6347db96d56Sopenharmony_ci        """
6357db96d56Sopenharmony_ci        Format and return the specified exception information as a string.
6367db96d56Sopenharmony_ci
6377db96d56Sopenharmony_ci        This default implementation just uses
6387db96d56Sopenharmony_ci        traceback.print_exception()
6397db96d56Sopenharmony_ci        """
6407db96d56Sopenharmony_ci        sio = io.StringIO()
6417db96d56Sopenharmony_ci        tb = ei[2]
6427db96d56Sopenharmony_ci        # See issues #9427, #1553375. Commented out for now.
6437db96d56Sopenharmony_ci        #if getattr(self, 'fullstack', False):
6447db96d56Sopenharmony_ci        #    traceback.print_stack(tb.tb_frame.f_back, file=sio)
6457db96d56Sopenharmony_ci        traceback.print_exception(ei[0], ei[1], tb, None, sio)
6467db96d56Sopenharmony_ci        s = sio.getvalue()
6477db96d56Sopenharmony_ci        sio.close()
6487db96d56Sopenharmony_ci        if s[-1:] == "\n":
6497db96d56Sopenharmony_ci            s = s[:-1]
6507db96d56Sopenharmony_ci        return s
6517db96d56Sopenharmony_ci
6527db96d56Sopenharmony_ci    def usesTime(self):
6537db96d56Sopenharmony_ci        """
6547db96d56Sopenharmony_ci        Check if the format uses the creation time of the record.
6557db96d56Sopenharmony_ci        """
6567db96d56Sopenharmony_ci        return self._style.usesTime()
6577db96d56Sopenharmony_ci
6587db96d56Sopenharmony_ci    def formatMessage(self, record):
6597db96d56Sopenharmony_ci        return self._style.format(record)
6607db96d56Sopenharmony_ci
6617db96d56Sopenharmony_ci    def formatStack(self, stack_info):
6627db96d56Sopenharmony_ci        """
6637db96d56Sopenharmony_ci        This method is provided as an extension point for specialized
6647db96d56Sopenharmony_ci        formatting of stack information.
6657db96d56Sopenharmony_ci
6667db96d56Sopenharmony_ci        The input data is a string as returned from a call to
6677db96d56Sopenharmony_ci        :func:`traceback.print_stack`, but with the last trailing newline
6687db96d56Sopenharmony_ci        removed.
6697db96d56Sopenharmony_ci
6707db96d56Sopenharmony_ci        The base implementation just returns the value passed in.
6717db96d56Sopenharmony_ci        """
6727db96d56Sopenharmony_ci        return stack_info
6737db96d56Sopenharmony_ci
6747db96d56Sopenharmony_ci    def format(self, record):
6757db96d56Sopenharmony_ci        """
6767db96d56Sopenharmony_ci        Format the specified record as text.
6777db96d56Sopenharmony_ci
6787db96d56Sopenharmony_ci        The record's attribute dictionary is used as the operand to a
6797db96d56Sopenharmony_ci        string formatting operation which yields the returned string.
6807db96d56Sopenharmony_ci        Before formatting the dictionary, a couple of preparatory steps
6817db96d56Sopenharmony_ci        are carried out. The message attribute of the record is computed
6827db96d56Sopenharmony_ci        using LogRecord.getMessage(). If the formatting string uses the
6837db96d56Sopenharmony_ci        time (as determined by a call to usesTime(), formatTime() is
6847db96d56Sopenharmony_ci        called to format the event time. If there is exception information,
6857db96d56Sopenharmony_ci        it is formatted using formatException() and appended to the message.
6867db96d56Sopenharmony_ci        """
6877db96d56Sopenharmony_ci        record.message = record.getMessage()
6887db96d56Sopenharmony_ci        if self.usesTime():
6897db96d56Sopenharmony_ci            record.asctime = self.formatTime(record, self.datefmt)
6907db96d56Sopenharmony_ci        s = self.formatMessage(record)
6917db96d56Sopenharmony_ci        if record.exc_info:
6927db96d56Sopenharmony_ci            # Cache the traceback text to avoid converting it multiple times
6937db96d56Sopenharmony_ci            # (it's constant anyway)
6947db96d56Sopenharmony_ci            if not record.exc_text:
6957db96d56Sopenharmony_ci                record.exc_text = self.formatException(record.exc_info)
6967db96d56Sopenharmony_ci        if record.exc_text:
6977db96d56Sopenharmony_ci            if s[-1:] != "\n":
6987db96d56Sopenharmony_ci                s = s + "\n"
6997db96d56Sopenharmony_ci            s = s + record.exc_text
7007db96d56Sopenharmony_ci        if record.stack_info:
7017db96d56Sopenharmony_ci            if s[-1:] != "\n":
7027db96d56Sopenharmony_ci                s = s + "\n"
7037db96d56Sopenharmony_ci            s = s + self.formatStack(record.stack_info)
7047db96d56Sopenharmony_ci        return s
7057db96d56Sopenharmony_ci
7067db96d56Sopenharmony_ci#
7077db96d56Sopenharmony_ci#   The default formatter to use when no other is specified
7087db96d56Sopenharmony_ci#
7097db96d56Sopenharmony_ci_defaultFormatter = Formatter()
7107db96d56Sopenharmony_ci
7117db96d56Sopenharmony_ciclass BufferingFormatter(object):
7127db96d56Sopenharmony_ci    """
7137db96d56Sopenharmony_ci    A formatter suitable for formatting a number of records.
7147db96d56Sopenharmony_ci    """
7157db96d56Sopenharmony_ci    def __init__(self, linefmt=None):
7167db96d56Sopenharmony_ci        """
7177db96d56Sopenharmony_ci        Optionally specify a formatter which will be used to format each
7187db96d56Sopenharmony_ci        individual record.
7197db96d56Sopenharmony_ci        """
7207db96d56Sopenharmony_ci        if linefmt:
7217db96d56Sopenharmony_ci            self.linefmt = linefmt
7227db96d56Sopenharmony_ci        else:
7237db96d56Sopenharmony_ci            self.linefmt = _defaultFormatter
7247db96d56Sopenharmony_ci
7257db96d56Sopenharmony_ci    def formatHeader(self, records):
7267db96d56Sopenharmony_ci        """
7277db96d56Sopenharmony_ci        Return the header string for the specified records.
7287db96d56Sopenharmony_ci        """
7297db96d56Sopenharmony_ci        return ""
7307db96d56Sopenharmony_ci
7317db96d56Sopenharmony_ci    def formatFooter(self, records):
7327db96d56Sopenharmony_ci        """
7337db96d56Sopenharmony_ci        Return the footer string for the specified records.
7347db96d56Sopenharmony_ci        """
7357db96d56Sopenharmony_ci        return ""
7367db96d56Sopenharmony_ci
7377db96d56Sopenharmony_ci    def format(self, records):
7387db96d56Sopenharmony_ci        """
7397db96d56Sopenharmony_ci        Format the specified records and return the result as a string.
7407db96d56Sopenharmony_ci        """
7417db96d56Sopenharmony_ci        rv = ""
7427db96d56Sopenharmony_ci        if len(records) > 0:
7437db96d56Sopenharmony_ci            rv = rv + self.formatHeader(records)
7447db96d56Sopenharmony_ci            for record in records:
7457db96d56Sopenharmony_ci                rv = rv + self.linefmt.format(record)
7467db96d56Sopenharmony_ci            rv = rv + self.formatFooter(records)
7477db96d56Sopenharmony_ci        return rv
7487db96d56Sopenharmony_ci
7497db96d56Sopenharmony_ci#---------------------------------------------------------------------------
7507db96d56Sopenharmony_ci#   Filter classes and functions
7517db96d56Sopenharmony_ci#---------------------------------------------------------------------------
7527db96d56Sopenharmony_ci
7537db96d56Sopenharmony_ciclass Filter(object):
7547db96d56Sopenharmony_ci    """
7557db96d56Sopenharmony_ci    Filter instances are used to perform arbitrary filtering of LogRecords.
7567db96d56Sopenharmony_ci
7577db96d56Sopenharmony_ci    Loggers and Handlers can optionally use Filter instances to filter
7587db96d56Sopenharmony_ci    records as desired. The base filter class only allows events which are
7597db96d56Sopenharmony_ci    below a certain point in the logger hierarchy. For example, a filter
7607db96d56Sopenharmony_ci    initialized with "A.B" will allow events logged by loggers "A.B",
7617db96d56Sopenharmony_ci    "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
7627db96d56Sopenharmony_ci    initialized with the empty string, all events are passed.
7637db96d56Sopenharmony_ci    """
7647db96d56Sopenharmony_ci    def __init__(self, name=''):
7657db96d56Sopenharmony_ci        """
7667db96d56Sopenharmony_ci        Initialize a filter.
7677db96d56Sopenharmony_ci
7687db96d56Sopenharmony_ci        Initialize with the name of the logger which, together with its
7697db96d56Sopenharmony_ci        children, will have its events allowed through the filter. If no
7707db96d56Sopenharmony_ci        name is specified, allow every event.
7717db96d56Sopenharmony_ci        """
7727db96d56Sopenharmony_ci        self.name = name
7737db96d56Sopenharmony_ci        self.nlen = len(name)
7747db96d56Sopenharmony_ci
7757db96d56Sopenharmony_ci    def filter(self, record):
7767db96d56Sopenharmony_ci        """
7777db96d56Sopenharmony_ci        Determine if the specified record is to be logged.
7787db96d56Sopenharmony_ci
7797db96d56Sopenharmony_ci        Returns True if the record should be logged, or False otherwise.
7807db96d56Sopenharmony_ci        If deemed appropriate, the record may be modified in-place.
7817db96d56Sopenharmony_ci        """
7827db96d56Sopenharmony_ci        if self.nlen == 0:
7837db96d56Sopenharmony_ci            return True
7847db96d56Sopenharmony_ci        elif self.name == record.name:
7857db96d56Sopenharmony_ci            return True
7867db96d56Sopenharmony_ci        elif record.name.find(self.name, 0, self.nlen) != 0:
7877db96d56Sopenharmony_ci            return False
7887db96d56Sopenharmony_ci        return (record.name[self.nlen] == ".")
7897db96d56Sopenharmony_ci
7907db96d56Sopenharmony_ciclass Filterer(object):
7917db96d56Sopenharmony_ci    """
7927db96d56Sopenharmony_ci    A base class for loggers and handlers which allows them to share
7937db96d56Sopenharmony_ci    common code.
7947db96d56Sopenharmony_ci    """
7957db96d56Sopenharmony_ci    def __init__(self):
7967db96d56Sopenharmony_ci        """
7977db96d56Sopenharmony_ci        Initialize the list of filters to be an empty list.
7987db96d56Sopenharmony_ci        """
7997db96d56Sopenharmony_ci        self.filters = []
8007db96d56Sopenharmony_ci
8017db96d56Sopenharmony_ci    def addFilter(self, filter):
8027db96d56Sopenharmony_ci        """
8037db96d56Sopenharmony_ci        Add the specified filter to this handler.
8047db96d56Sopenharmony_ci        """
8057db96d56Sopenharmony_ci        if not (filter in self.filters):
8067db96d56Sopenharmony_ci            self.filters.append(filter)
8077db96d56Sopenharmony_ci
8087db96d56Sopenharmony_ci    def removeFilter(self, filter):
8097db96d56Sopenharmony_ci        """
8107db96d56Sopenharmony_ci        Remove the specified filter from this handler.
8117db96d56Sopenharmony_ci        """
8127db96d56Sopenharmony_ci        if filter in self.filters:
8137db96d56Sopenharmony_ci            self.filters.remove(filter)
8147db96d56Sopenharmony_ci
8157db96d56Sopenharmony_ci    def filter(self, record):
8167db96d56Sopenharmony_ci        """
8177db96d56Sopenharmony_ci        Determine if a record is loggable by consulting all the filters.
8187db96d56Sopenharmony_ci
8197db96d56Sopenharmony_ci        The default is to allow the record to be logged; any filter can veto
8207db96d56Sopenharmony_ci        this and the record is then dropped. Returns a zero value if a record
8217db96d56Sopenharmony_ci        is to be dropped, else non-zero.
8227db96d56Sopenharmony_ci
8237db96d56Sopenharmony_ci        .. versionchanged:: 3.2
8247db96d56Sopenharmony_ci
8257db96d56Sopenharmony_ci           Allow filters to be just callables.
8267db96d56Sopenharmony_ci        """
8277db96d56Sopenharmony_ci        rv = True
8287db96d56Sopenharmony_ci        for f in self.filters:
8297db96d56Sopenharmony_ci            if hasattr(f, 'filter'):
8307db96d56Sopenharmony_ci                result = f.filter(record)
8317db96d56Sopenharmony_ci            else:
8327db96d56Sopenharmony_ci                result = f(record) # assume callable - will raise if not
8337db96d56Sopenharmony_ci            if not result:
8347db96d56Sopenharmony_ci                rv = False
8357db96d56Sopenharmony_ci                break
8367db96d56Sopenharmony_ci        return rv
8377db96d56Sopenharmony_ci
8387db96d56Sopenharmony_ci#---------------------------------------------------------------------------
8397db96d56Sopenharmony_ci#   Handler classes and functions
8407db96d56Sopenharmony_ci#---------------------------------------------------------------------------
8417db96d56Sopenharmony_ci
8427db96d56Sopenharmony_ci_handlers = weakref.WeakValueDictionary()  #map of handler names to handlers
8437db96d56Sopenharmony_ci_handlerList = [] # added to allow handlers to be removed in reverse of order initialized
8447db96d56Sopenharmony_ci
8457db96d56Sopenharmony_cidef _removeHandlerRef(wr):
8467db96d56Sopenharmony_ci    """
8477db96d56Sopenharmony_ci    Remove a handler reference from the internal cleanup list.
8487db96d56Sopenharmony_ci    """
8497db96d56Sopenharmony_ci    # This function can be called during module teardown, when globals are
8507db96d56Sopenharmony_ci    # set to None. It can also be called from another thread. So we need to
8517db96d56Sopenharmony_ci    # pre-emptively grab the necessary globals and check if they're None,
8527db96d56Sopenharmony_ci    # to prevent race conditions and failures during interpreter shutdown.
8537db96d56Sopenharmony_ci    acquire, release, handlers = _acquireLock, _releaseLock, _handlerList
8547db96d56Sopenharmony_ci    if acquire and release and handlers:
8557db96d56Sopenharmony_ci        acquire()
8567db96d56Sopenharmony_ci        try:
8577db96d56Sopenharmony_ci            handlers.remove(wr)
8587db96d56Sopenharmony_ci        except ValueError:
8597db96d56Sopenharmony_ci            pass
8607db96d56Sopenharmony_ci        finally:
8617db96d56Sopenharmony_ci            release()
8627db96d56Sopenharmony_ci
8637db96d56Sopenharmony_cidef _addHandlerRef(handler):
8647db96d56Sopenharmony_ci    """
8657db96d56Sopenharmony_ci    Add a handler to the internal cleanup list using a weak reference.
8667db96d56Sopenharmony_ci    """
8677db96d56Sopenharmony_ci    _acquireLock()
8687db96d56Sopenharmony_ci    try:
8697db96d56Sopenharmony_ci        _handlerList.append(weakref.ref(handler, _removeHandlerRef))
8707db96d56Sopenharmony_ci    finally:
8717db96d56Sopenharmony_ci        _releaseLock()
8727db96d56Sopenharmony_ci
8737db96d56Sopenharmony_ciclass Handler(Filterer):
8747db96d56Sopenharmony_ci    """
8757db96d56Sopenharmony_ci    Handler instances dispatch logging events to specific destinations.
8767db96d56Sopenharmony_ci
8777db96d56Sopenharmony_ci    The base handler class. Acts as a placeholder which defines the Handler
8787db96d56Sopenharmony_ci    interface. Handlers can optionally use Formatter instances to format
8797db96d56Sopenharmony_ci    records as desired. By default, no formatter is specified; in this case,
8807db96d56Sopenharmony_ci    the 'raw' message as determined by record.message is logged.
8817db96d56Sopenharmony_ci    """
8827db96d56Sopenharmony_ci    def __init__(self, level=NOTSET):
8837db96d56Sopenharmony_ci        """
8847db96d56Sopenharmony_ci        Initializes the instance - basically setting the formatter to None
8857db96d56Sopenharmony_ci        and the filter list to empty.
8867db96d56Sopenharmony_ci        """
8877db96d56Sopenharmony_ci        Filterer.__init__(self)
8887db96d56Sopenharmony_ci        self._name = None
8897db96d56Sopenharmony_ci        self.level = _checkLevel(level)
8907db96d56Sopenharmony_ci        self.formatter = None
8917db96d56Sopenharmony_ci        self._closed = False
8927db96d56Sopenharmony_ci        # Add the handler to the global _handlerList (for cleanup on shutdown)
8937db96d56Sopenharmony_ci        _addHandlerRef(self)
8947db96d56Sopenharmony_ci        self.createLock()
8957db96d56Sopenharmony_ci
8967db96d56Sopenharmony_ci    def get_name(self):
8977db96d56Sopenharmony_ci        return self._name
8987db96d56Sopenharmony_ci
8997db96d56Sopenharmony_ci    def set_name(self, name):
9007db96d56Sopenharmony_ci        _acquireLock()
9017db96d56Sopenharmony_ci        try:
9027db96d56Sopenharmony_ci            if self._name in _handlers:
9037db96d56Sopenharmony_ci                del _handlers[self._name]
9047db96d56Sopenharmony_ci            self._name = name
9057db96d56Sopenharmony_ci            if name:
9067db96d56Sopenharmony_ci                _handlers[name] = self
9077db96d56Sopenharmony_ci        finally:
9087db96d56Sopenharmony_ci            _releaseLock()
9097db96d56Sopenharmony_ci
9107db96d56Sopenharmony_ci    name = property(get_name, set_name)
9117db96d56Sopenharmony_ci
9127db96d56Sopenharmony_ci    def createLock(self):
9137db96d56Sopenharmony_ci        """
9147db96d56Sopenharmony_ci        Acquire a thread lock for serializing access to the underlying I/O.
9157db96d56Sopenharmony_ci        """
9167db96d56Sopenharmony_ci        self.lock = threading.RLock()
9177db96d56Sopenharmony_ci        _register_at_fork_reinit_lock(self)
9187db96d56Sopenharmony_ci
9197db96d56Sopenharmony_ci    def _at_fork_reinit(self):
9207db96d56Sopenharmony_ci        self.lock._at_fork_reinit()
9217db96d56Sopenharmony_ci
9227db96d56Sopenharmony_ci    def acquire(self):
9237db96d56Sopenharmony_ci        """
9247db96d56Sopenharmony_ci        Acquire the I/O thread lock.
9257db96d56Sopenharmony_ci        """
9267db96d56Sopenharmony_ci        if self.lock:
9277db96d56Sopenharmony_ci            self.lock.acquire()
9287db96d56Sopenharmony_ci
9297db96d56Sopenharmony_ci    def release(self):
9307db96d56Sopenharmony_ci        """
9317db96d56Sopenharmony_ci        Release the I/O thread lock.
9327db96d56Sopenharmony_ci        """
9337db96d56Sopenharmony_ci        if self.lock:
9347db96d56Sopenharmony_ci            self.lock.release()
9357db96d56Sopenharmony_ci
9367db96d56Sopenharmony_ci    def setLevel(self, level):
9377db96d56Sopenharmony_ci        """
9387db96d56Sopenharmony_ci        Set the logging level of this handler.  level must be an int or a str.
9397db96d56Sopenharmony_ci        """
9407db96d56Sopenharmony_ci        self.level = _checkLevel(level)
9417db96d56Sopenharmony_ci
9427db96d56Sopenharmony_ci    def format(self, record):
9437db96d56Sopenharmony_ci        """
9447db96d56Sopenharmony_ci        Format the specified record.
9457db96d56Sopenharmony_ci
9467db96d56Sopenharmony_ci        If a formatter is set, use it. Otherwise, use the default formatter
9477db96d56Sopenharmony_ci        for the module.
9487db96d56Sopenharmony_ci        """
9497db96d56Sopenharmony_ci        if self.formatter:
9507db96d56Sopenharmony_ci            fmt = self.formatter
9517db96d56Sopenharmony_ci        else:
9527db96d56Sopenharmony_ci            fmt = _defaultFormatter
9537db96d56Sopenharmony_ci        return fmt.format(record)
9547db96d56Sopenharmony_ci
9557db96d56Sopenharmony_ci    def emit(self, record):
9567db96d56Sopenharmony_ci        """
9577db96d56Sopenharmony_ci        Do whatever it takes to actually log the specified logging record.
9587db96d56Sopenharmony_ci
9597db96d56Sopenharmony_ci        This version is intended to be implemented by subclasses and so
9607db96d56Sopenharmony_ci        raises a NotImplementedError.
9617db96d56Sopenharmony_ci        """
9627db96d56Sopenharmony_ci        raise NotImplementedError('emit must be implemented '
9637db96d56Sopenharmony_ci                                  'by Handler subclasses')
9647db96d56Sopenharmony_ci
9657db96d56Sopenharmony_ci    def handle(self, record):
9667db96d56Sopenharmony_ci        """
9677db96d56Sopenharmony_ci        Conditionally emit the specified logging record.
9687db96d56Sopenharmony_ci
9697db96d56Sopenharmony_ci        Emission depends on filters which may have been added to the handler.
9707db96d56Sopenharmony_ci        Wrap the actual emission of the record with acquisition/release of
9717db96d56Sopenharmony_ci        the I/O thread lock. Returns whether the filter passed the record for
9727db96d56Sopenharmony_ci        emission.
9737db96d56Sopenharmony_ci        """
9747db96d56Sopenharmony_ci        rv = self.filter(record)
9757db96d56Sopenharmony_ci        if rv:
9767db96d56Sopenharmony_ci            self.acquire()
9777db96d56Sopenharmony_ci            try:
9787db96d56Sopenharmony_ci                self.emit(record)
9797db96d56Sopenharmony_ci            finally:
9807db96d56Sopenharmony_ci                self.release()
9817db96d56Sopenharmony_ci        return rv
9827db96d56Sopenharmony_ci
9837db96d56Sopenharmony_ci    def setFormatter(self, fmt):
9847db96d56Sopenharmony_ci        """
9857db96d56Sopenharmony_ci        Set the formatter for this handler.
9867db96d56Sopenharmony_ci        """
9877db96d56Sopenharmony_ci        self.formatter = fmt
9887db96d56Sopenharmony_ci
9897db96d56Sopenharmony_ci    def flush(self):
9907db96d56Sopenharmony_ci        """
9917db96d56Sopenharmony_ci        Ensure all logging output has been flushed.
9927db96d56Sopenharmony_ci
9937db96d56Sopenharmony_ci        This version does nothing and is intended to be implemented by
9947db96d56Sopenharmony_ci        subclasses.
9957db96d56Sopenharmony_ci        """
9967db96d56Sopenharmony_ci        pass
9977db96d56Sopenharmony_ci
9987db96d56Sopenharmony_ci    def close(self):
9997db96d56Sopenharmony_ci        """
10007db96d56Sopenharmony_ci        Tidy up any resources used by the handler.
10017db96d56Sopenharmony_ci
10027db96d56Sopenharmony_ci        This version removes the handler from an internal map of handlers,
10037db96d56Sopenharmony_ci        _handlers, which is used for handler lookup by name. Subclasses
10047db96d56Sopenharmony_ci        should ensure that this gets called from overridden close()
10057db96d56Sopenharmony_ci        methods.
10067db96d56Sopenharmony_ci        """
10077db96d56Sopenharmony_ci        #get the module data lock, as we're updating a shared structure.
10087db96d56Sopenharmony_ci        _acquireLock()
10097db96d56Sopenharmony_ci        try:    #unlikely to raise an exception, but you never know...
10107db96d56Sopenharmony_ci            self._closed = True
10117db96d56Sopenharmony_ci            if self._name and self._name in _handlers:
10127db96d56Sopenharmony_ci                del _handlers[self._name]
10137db96d56Sopenharmony_ci        finally:
10147db96d56Sopenharmony_ci            _releaseLock()
10157db96d56Sopenharmony_ci
10167db96d56Sopenharmony_ci    def handleError(self, record):
10177db96d56Sopenharmony_ci        """
10187db96d56Sopenharmony_ci        Handle errors which occur during an emit() call.
10197db96d56Sopenharmony_ci
10207db96d56Sopenharmony_ci        This method should be called from handlers when an exception is
10217db96d56Sopenharmony_ci        encountered during an emit() call. If raiseExceptions is false,
10227db96d56Sopenharmony_ci        exceptions get silently ignored. This is what is mostly wanted
10237db96d56Sopenharmony_ci        for a logging system - most users will not care about errors in
10247db96d56Sopenharmony_ci        the logging system, they are more interested in application errors.
10257db96d56Sopenharmony_ci        You could, however, replace this with a custom handler if you wish.
10267db96d56Sopenharmony_ci        The record which was being processed is passed in to this method.
10277db96d56Sopenharmony_ci        """
10287db96d56Sopenharmony_ci        if raiseExceptions and sys.stderr:  # see issue 13807
10297db96d56Sopenharmony_ci            t, v, tb = sys.exc_info()
10307db96d56Sopenharmony_ci            try:
10317db96d56Sopenharmony_ci                sys.stderr.write('--- Logging error ---\n')
10327db96d56Sopenharmony_ci                traceback.print_exception(t, v, tb, None, sys.stderr)
10337db96d56Sopenharmony_ci                sys.stderr.write('Call stack:\n')
10347db96d56Sopenharmony_ci                # Walk the stack frame up until we're out of logging,
10357db96d56Sopenharmony_ci                # so as to print the calling context.
10367db96d56Sopenharmony_ci                frame = tb.tb_frame
10377db96d56Sopenharmony_ci                while (frame and os.path.dirname(frame.f_code.co_filename) ==
10387db96d56Sopenharmony_ci                       __path__[0]):
10397db96d56Sopenharmony_ci                    frame = frame.f_back
10407db96d56Sopenharmony_ci                if frame:
10417db96d56Sopenharmony_ci                    traceback.print_stack(frame, file=sys.stderr)
10427db96d56Sopenharmony_ci                else:
10437db96d56Sopenharmony_ci                    # couldn't find the right stack frame, for some reason
10447db96d56Sopenharmony_ci                    sys.stderr.write('Logged from file %s, line %s\n' % (
10457db96d56Sopenharmony_ci                                     record.filename, record.lineno))
10467db96d56Sopenharmony_ci                # Issue 18671: output logging message and arguments
10477db96d56Sopenharmony_ci                try:
10487db96d56Sopenharmony_ci                    sys.stderr.write('Message: %r\n'
10497db96d56Sopenharmony_ci                                     'Arguments: %s\n' % (record.msg,
10507db96d56Sopenharmony_ci                                                          record.args))
10517db96d56Sopenharmony_ci                except RecursionError:  # See issue 36272
10527db96d56Sopenharmony_ci                    raise
10537db96d56Sopenharmony_ci                except Exception:
10547db96d56Sopenharmony_ci                    sys.stderr.write('Unable to print the message and arguments'
10557db96d56Sopenharmony_ci                                     ' - possible formatting error.\nUse the'
10567db96d56Sopenharmony_ci                                     ' traceback above to help find the error.\n'
10577db96d56Sopenharmony_ci                                    )
10587db96d56Sopenharmony_ci            except OSError: #pragma: no cover
10597db96d56Sopenharmony_ci                pass    # see issue 5971
10607db96d56Sopenharmony_ci            finally:
10617db96d56Sopenharmony_ci                del t, v, tb
10627db96d56Sopenharmony_ci
10637db96d56Sopenharmony_ci    def __repr__(self):
10647db96d56Sopenharmony_ci        level = getLevelName(self.level)
10657db96d56Sopenharmony_ci        return '<%s (%s)>' % (self.__class__.__name__, level)
10667db96d56Sopenharmony_ci
10677db96d56Sopenharmony_ciclass StreamHandler(Handler):
10687db96d56Sopenharmony_ci    """
10697db96d56Sopenharmony_ci    A handler class which writes logging records, appropriately formatted,
10707db96d56Sopenharmony_ci    to a stream. Note that this class does not close the stream, as
10717db96d56Sopenharmony_ci    sys.stdout or sys.stderr may be used.
10727db96d56Sopenharmony_ci    """
10737db96d56Sopenharmony_ci
10747db96d56Sopenharmony_ci    terminator = '\n'
10757db96d56Sopenharmony_ci
10767db96d56Sopenharmony_ci    def __init__(self, stream=None):
10777db96d56Sopenharmony_ci        """
10787db96d56Sopenharmony_ci        Initialize the handler.
10797db96d56Sopenharmony_ci
10807db96d56Sopenharmony_ci        If stream is not specified, sys.stderr is used.
10817db96d56Sopenharmony_ci        """
10827db96d56Sopenharmony_ci        Handler.__init__(self)
10837db96d56Sopenharmony_ci        if stream is None:
10847db96d56Sopenharmony_ci            stream = sys.stderr
10857db96d56Sopenharmony_ci        self.stream = stream
10867db96d56Sopenharmony_ci
10877db96d56Sopenharmony_ci    def flush(self):
10887db96d56Sopenharmony_ci        """
10897db96d56Sopenharmony_ci        Flushes the stream.
10907db96d56Sopenharmony_ci        """
10917db96d56Sopenharmony_ci        self.acquire()
10927db96d56Sopenharmony_ci        try:
10937db96d56Sopenharmony_ci            if self.stream and hasattr(self.stream, "flush"):
10947db96d56Sopenharmony_ci                self.stream.flush()
10957db96d56Sopenharmony_ci        finally:
10967db96d56Sopenharmony_ci            self.release()
10977db96d56Sopenharmony_ci
10987db96d56Sopenharmony_ci    def emit(self, record):
10997db96d56Sopenharmony_ci        """
11007db96d56Sopenharmony_ci        Emit a record.
11017db96d56Sopenharmony_ci
11027db96d56Sopenharmony_ci        If a formatter is specified, it is used to format the record.
11037db96d56Sopenharmony_ci        The record is then written to the stream with a trailing newline.  If
11047db96d56Sopenharmony_ci        exception information is present, it is formatted using
11057db96d56Sopenharmony_ci        traceback.print_exception and appended to the stream.  If the stream
11067db96d56Sopenharmony_ci        has an 'encoding' attribute, it is used to determine how to do the
11077db96d56Sopenharmony_ci        output to the stream.
11087db96d56Sopenharmony_ci        """
11097db96d56Sopenharmony_ci        try:
11107db96d56Sopenharmony_ci            msg = self.format(record)
11117db96d56Sopenharmony_ci            stream = self.stream
11127db96d56Sopenharmony_ci            # issue 35046: merged two stream.writes into one.
11137db96d56Sopenharmony_ci            stream.write(msg + self.terminator)
11147db96d56Sopenharmony_ci            self.flush()
11157db96d56Sopenharmony_ci        except RecursionError:  # See issue 36272
11167db96d56Sopenharmony_ci            raise
11177db96d56Sopenharmony_ci        except Exception:
11187db96d56Sopenharmony_ci            self.handleError(record)
11197db96d56Sopenharmony_ci
11207db96d56Sopenharmony_ci    def setStream(self, stream):
11217db96d56Sopenharmony_ci        """
11227db96d56Sopenharmony_ci        Sets the StreamHandler's stream to the specified value,
11237db96d56Sopenharmony_ci        if it is different.
11247db96d56Sopenharmony_ci
11257db96d56Sopenharmony_ci        Returns the old stream, if the stream was changed, or None
11267db96d56Sopenharmony_ci        if it wasn't.
11277db96d56Sopenharmony_ci        """
11287db96d56Sopenharmony_ci        if stream is self.stream:
11297db96d56Sopenharmony_ci            result = None
11307db96d56Sopenharmony_ci        else:
11317db96d56Sopenharmony_ci            result = self.stream
11327db96d56Sopenharmony_ci            self.acquire()
11337db96d56Sopenharmony_ci            try:
11347db96d56Sopenharmony_ci                self.flush()
11357db96d56Sopenharmony_ci                self.stream = stream
11367db96d56Sopenharmony_ci            finally:
11377db96d56Sopenharmony_ci                self.release()
11387db96d56Sopenharmony_ci        return result
11397db96d56Sopenharmony_ci
11407db96d56Sopenharmony_ci    def __repr__(self):
11417db96d56Sopenharmony_ci        level = getLevelName(self.level)
11427db96d56Sopenharmony_ci        name = getattr(self.stream, 'name', '')
11437db96d56Sopenharmony_ci        #  bpo-36015: name can be an int
11447db96d56Sopenharmony_ci        name = str(name)
11457db96d56Sopenharmony_ci        if name:
11467db96d56Sopenharmony_ci            name += ' '
11477db96d56Sopenharmony_ci        return '<%s %s(%s)>' % (self.__class__.__name__, name, level)
11487db96d56Sopenharmony_ci
11497db96d56Sopenharmony_ci    __class_getitem__ = classmethod(GenericAlias)
11507db96d56Sopenharmony_ci
11517db96d56Sopenharmony_ci
11527db96d56Sopenharmony_ciclass FileHandler(StreamHandler):
11537db96d56Sopenharmony_ci    """
11547db96d56Sopenharmony_ci    A handler class which writes formatted logging records to disk files.
11557db96d56Sopenharmony_ci    """
11567db96d56Sopenharmony_ci    def __init__(self, filename, mode='a', encoding=None, delay=False, errors=None):
11577db96d56Sopenharmony_ci        """
11587db96d56Sopenharmony_ci        Open the specified file and use it as the stream for logging.
11597db96d56Sopenharmony_ci        """
11607db96d56Sopenharmony_ci        # Issue #27493: add support for Path objects to be passed in
11617db96d56Sopenharmony_ci        filename = os.fspath(filename)
11627db96d56Sopenharmony_ci        #keep the absolute path, otherwise derived classes which use this
11637db96d56Sopenharmony_ci        #may come a cropper when the current directory changes
11647db96d56Sopenharmony_ci        self.baseFilename = os.path.abspath(filename)
11657db96d56Sopenharmony_ci        self.mode = mode
11667db96d56Sopenharmony_ci        self.encoding = encoding
11677db96d56Sopenharmony_ci        if "b" not in mode:
11687db96d56Sopenharmony_ci            self.encoding = io.text_encoding(encoding)
11697db96d56Sopenharmony_ci        self.errors = errors
11707db96d56Sopenharmony_ci        self.delay = delay
11717db96d56Sopenharmony_ci        # bpo-26789: FileHandler keeps a reference to the builtin open()
11727db96d56Sopenharmony_ci        # function to be able to open or reopen the file during Python
11737db96d56Sopenharmony_ci        # finalization.
11747db96d56Sopenharmony_ci        self._builtin_open = open
11757db96d56Sopenharmony_ci        if delay:
11767db96d56Sopenharmony_ci            #We don't open the stream, but we still need to call the
11777db96d56Sopenharmony_ci            #Handler constructor to set level, formatter, lock etc.
11787db96d56Sopenharmony_ci            Handler.__init__(self)
11797db96d56Sopenharmony_ci            self.stream = None
11807db96d56Sopenharmony_ci        else:
11817db96d56Sopenharmony_ci            StreamHandler.__init__(self, self._open())
11827db96d56Sopenharmony_ci
11837db96d56Sopenharmony_ci    def close(self):
11847db96d56Sopenharmony_ci        """
11857db96d56Sopenharmony_ci        Closes the stream.
11867db96d56Sopenharmony_ci        """
11877db96d56Sopenharmony_ci        self.acquire()
11887db96d56Sopenharmony_ci        try:
11897db96d56Sopenharmony_ci            try:
11907db96d56Sopenharmony_ci                if self.stream:
11917db96d56Sopenharmony_ci                    try:
11927db96d56Sopenharmony_ci                        self.flush()
11937db96d56Sopenharmony_ci                    finally:
11947db96d56Sopenharmony_ci                        stream = self.stream
11957db96d56Sopenharmony_ci                        self.stream = None
11967db96d56Sopenharmony_ci                        if hasattr(stream, "close"):
11977db96d56Sopenharmony_ci                            stream.close()
11987db96d56Sopenharmony_ci            finally:
11997db96d56Sopenharmony_ci                # Issue #19523: call unconditionally to
12007db96d56Sopenharmony_ci                # prevent a handler leak when delay is set
12017db96d56Sopenharmony_ci                # Also see Issue #42378: we also rely on
12027db96d56Sopenharmony_ci                # self._closed being set to True there
12037db96d56Sopenharmony_ci                StreamHandler.close(self)
12047db96d56Sopenharmony_ci        finally:
12057db96d56Sopenharmony_ci            self.release()
12067db96d56Sopenharmony_ci
12077db96d56Sopenharmony_ci    def _open(self):
12087db96d56Sopenharmony_ci        """
12097db96d56Sopenharmony_ci        Open the current base file with the (original) mode and encoding.
12107db96d56Sopenharmony_ci        Return the resulting stream.
12117db96d56Sopenharmony_ci        """
12127db96d56Sopenharmony_ci        open_func = self._builtin_open
12137db96d56Sopenharmony_ci        return open_func(self.baseFilename, self.mode,
12147db96d56Sopenharmony_ci                         encoding=self.encoding, errors=self.errors)
12157db96d56Sopenharmony_ci
12167db96d56Sopenharmony_ci    def emit(self, record):
12177db96d56Sopenharmony_ci        """
12187db96d56Sopenharmony_ci        Emit a record.
12197db96d56Sopenharmony_ci
12207db96d56Sopenharmony_ci        If the stream was not opened because 'delay' was specified in the
12217db96d56Sopenharmony_ci        constructor, open it before calling the superclass's emit.
12227db96d56Sopenharmony_ci
12237db96d56Sopenharmony_ci        If stream is not open, current mode is 'w' and `_closed=True`, record
12247db96d56Sopenharmony_ci        will not be emitted (see Issue #42378).
12257db96d56Sopenharmony_ci        """
12267db96d56Sopenharmony_ci        if self.stream is None:
12277db96d56Sopenharmony_ci            if self.mode != 'w' or not self._closed:
12287db96d56Sopenharmony_ci                self.stream = self._open()
12297db96d56Sopenharmony_ci        if self.stream:
12307db96d56Sopenharmony_ci            StreamHandler.emit(self, record)
12317db96d56Sopenharmony_ci
12327db96d56Sopenharmony_ci    def __repr__(self):
12337db96d56Sopenharmony_ci        level = getLevelName(self.level)
12347db96d56Sopenharmony_ci        return '<%s %s (%s)>' % (self.__class__.__name__, self.baseFilename, level)
12357db96d56Sopenharmony_ci
12367db96d56Sopenharmony_ci
12377db96d56Sopenharmony_ciclass _StderrHandler(StreamHandler):
12387db96d56Sopenharmony_ci    """
12397db96d56Sopenharmony_ci    This class is like a StreamHandler using sys.stderr, but always uses
12407db96d56Sopenharmony_ci    whatever sys.stderr is currently set to rather than the value of
12417db96d56Sopenharmony_ci    sys.stderr at handler construction time.
12427db96d56Sopenharmony_ci    """
12437db96d56Sopenharmony_ci    def __init__(self, level=NOTSET):
12447db96d56Sopenharmony_ci        """
12457db96d56Sopenharmony_ci        Initialize the handler.
12467db96d56Sopenharmony_ci        """
12477db96d56Sopenharmony_ci        Handler.__init__(self, level)
12487db96d56Sopenharmony_ci
12497db96d56Sopenharmony_ci    @property
12507db96d56Sopenharmony_ci    def stream(self):
12517db96d56Sopenharmony_ci        return sys.stderr
12527db96d56Sopenharmony_ci
12537db96d56Sopenharmony_ci
12547db96d56Sopenharmony_ci_defaultLastResort = _StderrHandler(WARNING)
12557db96d56Sopenharmony_cilastResort = _defaultLastResort
12567db96d56Sopenharmony_ci
12577db96d56Sopenharmony_ci#---------------------------------------------------------------------------
12587db96d56Sopenharmony_ci#   Manager classes and functions
12597db96d56Sopenharmony_ci#---------------------------------------------------------------------------
12607db96d56Sopenharmony_ci
12617db96d56Sopenharmony_ciclass PlaceHolder(object):
12627db96d56Sopenharmony_ci    """
12637db96d56Sopenharmony_ci    PlaceHolder instances are used in the Manager logger hierarchy to take
12647db96d56Sopenharmony_ci    the place of nodes for which no loggers have been defined. This class is
12657db96d56Sopenharmony_ci    intended for internal use only and not as part of the public API.
12667db96d56Sopenharmony_ci    """
12677db96d56Sopenharmony_ci    def __init__(self, alogger):
12687db96d56Sopenharmony_ci        """
12697db96d56Sopenharmony_ci        Initialize with the specified logger being a child of this placeholder.
12707db96d56Sopenharmony_ci        """
12717db96d56Sopenharmony_ci        self.loggerMap = { alogger : None }
12727db96d56Sopenharmony_ci
12737db96d56Sopenharmony_ci    def append(self, alogger):
12747db96d56Sopenharmony_ci        """
12757db96d56Sopenharmony_ci        Add the specified logger as a child of this placeholder.
12767db96d56Sopenharmony_ci        """
12777db96d56Sopenharmony_ci        if alogger not in self.loggerMap:
12787db96d56Sopenharmony_ci            self.loggerMap[alogger] = None
12797db96d56Sopenharmony_ci
12807db96d56Sopenharmony_ci#
12817db96d56Sopenharmony_ci#   Determine which class to use when instantiating loggers.
12827db96d56Sopenharmony_ci#
12837db96d56Sopenharmony_ci
12847db96d56Sopenharmony_cidef setLoggerClass(klass):
12857db96d56Sopenharmony_ci    """
12867db96d56Sopenharmony_ci    Set the class to be used when instantiating a logger. The class should
12877db96d56Sopenharmony_ci    define __init__() such that only a name argument is required, and the
12887db96d56Sopenharmony_ci    __init__() should call Logger.__init__()
12897db96d56Sopenharmony_ci    """
12907db96d56Sopenharmony_ci    if klass != Logger:
12917db96d56Sopenharmony_ci        if not issubclass(klass, Logger):
12927db96d56Sopenharmony_ci            raise TypeError("logger not derived from logging.Logger: "
12937db96d56Sopenharmony_ci                            + klass.__name__)
12947db96d56Sopenharmony_ci    global _loggerClass
12957db96d56Sopenharmony_ci    _loggerClass = klass
12967db96d56Sopenharmony_ci
12977db96d56Sopenharmony_cidef getLoggerClass():
12987db96d56Sopenharmony_ci    """
12997db96d56Sopenharmony_ci    Return the class to be used when instantiating a logger.
13007db96d56Sopenharmony_ci    """
13017db96d56Sopenharmony_ci    return _loggerClass
13027db96d56Sopenharmony_ci
13037db96d56Sopenharmony_ciclass Manager(object):
13047db96d56Sopenharmony_ci    """
13057db96d56Sopenharmony_ci    There is [under normal circumstances] just one Manager instance, which
13067db96d56Sopenharmony_ci    holds the hierarchy of loggers.
13077db96d56Sopenharmony_ci    """
13087db96d56Sopenharmony_ci    def __init__(self, rootnode):
13097db96d56Sopenharmony_ci        """
13107db96d56Sopenharmony_ci        Initialize the manager with the root node of the logger hierarchy.
13117db96d56Sopenharmony_ci        """
13127db96d56Sopenharmony_ci        self.root = rootnode
13137db96d56Sopenharmony_ci        self.disable = 0
13147db96d56Sopenharmony_ci        self.emittedNoHandlerWarning = False
13157db96d56Sopenharmony_ci        self.loggerDict = {}
13167db96d56Sopenharmony_ci        self.loggerClass = None
13177db96d56Sopenharmony_ci        self.logRecordFactory = None
13187db96d56Sopenharmony_ci
13197db96d56Sopenharmony_ci    @property
13207db96d56Sopenharmony_ci    def disable(self):
13217db96d56Sopenharmony_ci        return self._disable
13227db96d56Sopenharmony_ci
13237db96d56Sopenharmony_ci    @disable.setter
13247db96d56Sopenharmony_ci    def disable(self, value):
13257db96d56Sopenharmony_ci        self._disable = _checkLevel(value)
13267db96d56Sopenharmony_ci
13277db96d56Sopenharmony_ci    def getLogger(self, name):
13287db96d56Sopenharmony_ci        """
13297db96d56Sopenharmony_ci        Get a logger with the specified name (channel name), creating it
13307db96d56Sopenharmony_ci        if it doesn't yet exist. This name is a dot-separated hierarchical
13317db96d56Sopenharmony_ci        name, such as "a", "a.b", "a.b.c" or similar.
13327db96d56Sopenharmony_ci
13337db96d56Sopenharmony_ci        If a PlaceHolder existed for the specified name [i.e. the logger
13347db96d56Sopenharmony_ci        didn't exist but a child of it did], replace it with the created
13357db96d56Sopenharmony_ci        logger and fix up the parent/child references which pointed to the
13367db96d56Sopenharmony_ci        placeholder to now point to the logger.
13377db96d56Sopenharmony_ci        """
13387db96d56Sopenharmony_ci        rv = None
13397db96d56Sopenharmony_ci        if not isinstance(name, str):
13407db96d56Sopenharmony_ci            raise TypeError('A logger name must be a string')
13417db96d56Sopenharmony_ci        _acquireLock()
13427db96d56Sopenharmony_ci        try:
13437db96d56Sopenharmony_ci            if name in self.loggerDict:
13447db96d56Sopenharmony_ci                rv = self.loggerDict[name]
13457db96d56Sopenharmony_ci                if isinstance(rv, PlaceHolder):
13467db96d56Sopenharmony_ci                    ph = rv
13477db96d56Sopenharmony_ci                    rv = (self.loggerClass or _loggerClass)(name)
13487db96d56Sopenharmony_ci                    rv.manager = self
13497db96d56Sopenharmony_ci                    self.loggerDict[name] = rv
13507db96d56Sopenharmony_ci                    self._fixupChildren(ph, rv)
13517db96d56Sopenharmony_ci                    self._fixupParents(rv)
13527db96d56Sopenharmony_ci            else:
13537db96d56Sopenharmony_ci                rv = (self.loggerClass or _loggerClass)(name)
13547db96d56Sopenharmony_ci                rv.manager = self
13557db96d56Sopenharmony_ci                self.loggerDict[name] = rv
13567db96d56Sopenharmony_ci                self._fixupParents(rv)
13577db96d56Sopenharmony_ci        finally:
13587db96d56Sopenharmony_ci            _releaseLock()
13597db96d56Sopenharmony_ci        return rv
13607db96d56Sopenharmony_ci
13617db96d56Sopenharmony_ci    def setLoggerClass(self, klass):
13627db96d56Sopenharmony_ci        """
13637db96d56Sopenharmony_ci        Set the class to be used when instantiating a logger with this Manager.
13647db96d56Sopenharmony_ci        """
13657db96d56Sopenharmony_ci        if klass != Logger:
13667db96d56Sopenharmony_ci            if not issubclass(klass, Logger):
13677db96d56Sopenharmony_ci                raise TypeError("logger not derived from logging.Logger: "
13687db96d56Sopenharmony_ci                                + klass.__name__)
13697db96d56Sopenharmony_ci        self.loggerClass = klass
13707db96d56Sopenharmony_ci
13717db96d56Sopenharmony_ci    def setLogRecordFactory(self, factory):
13727db96d56Sopenharmony_ci        """
13737db96d56Sopenharmony_ci        Set the factory to be used when instantiating a log record with this
13747db96d56Sopenharmony_ci        Manager.
13757db96d56Sopenharmony_ci        """
13767db96d56Sopenharmony_ci        self.logRecordFactory = factory
13777db96d56Sopenharmony_ci
13787db96d56Sopenharmony_ci    def _fixupParents(self, alogger):
13797db96d56Sopenharmony_ci        """
13807db96d56Sopenharmony_ci        Ensure that there are either loggers or placeholders all the way
13817db96d56Sopenharmony_ci        from the specified logger to the root of the logger hierarchy.
13827db96d56Sopenharmony_ci        """
13837db96d56Sopenharmony_ci        name = alogger.name
13847db96d56Sopenharmony_ci        i = name.rfind(".")
13857db96d56Sopenharmony_ci        rv = None
13867db96d56Sopenharmony_ci        while (i > 0) and not rv:
13877db96d56Sopenharmony_ci            substr = name[:i]
13887db96d56Sopenharmony_ci            if substr not in self.loggerDict:
13897db96d56Sopenharmony_ci                self.loggerDict[substr] = PlaceHolder(alogger)
13907db96d56Sopenharmony_ci            else:
13917db96d56Sopenharmony_ci                obj = self.loggerDict[substr]
13927db96d56Sopenharmony_ci                if isinstance(obj, Logger):
13937db96d56Sopenharmony_ci                    rv = obj
13947db96d56Sopenharmony_ci                else:
13957db96d56Sopenharmony_ci                    assert isinstance(obj, PlaceHolder)
13967db96d56Sopenharmony_ci                    obj.append(alogger)
13977db96d56Sopenharmony_ci            i = name.rfind(".", 0, i - 1)
13987db96d56Sopenharmony_ci        if not rv:
13997db96d56Sopenharmony_ci            rv = self.root
14007db96d56Sopenharmony_ci        alogger.parent = rv
14017db96d56Sopenharmony_ci
14027db96d56Sopenharmony_ci    def _fixupChildren(self, ph, alogger):
14037db96d56Sopenharmony_ci        """
14047db96d56Sopenharmony_ci        Ensure that children of the placeholder ph are connected to the
14057db96d56Sopenharmony_ci        specified logger.
14067db96d56Sopenharmony_ci        """
14077db96d56Sopenharmony_ci        name = alogger.name
14087db96d56Sopenharmony_ci        namelen = len(name)
14097db96d56Sopenharmony_ci        for c in ph.loggerMap.keys():
14107db96d56Sopenharmony_ci            #The if means ... if not c.parent.name.startswith(nm)
14117db96d56Sopenharmony_ci            if c.parent.name[:namelen] != name:
14127db96d56Sopenharmony_ci                alogger.parent = c.parent
14137db96d56Sopenharmony_ci                c.parent = alogger
14147db96d56Sopenharmony_ci
14157db96d56Sopenharmony_ci    def _clear_cache(self):
14167db96d56Sopenharmony_ci        """
14177db96d56Sopenharmony_ci        Clear the cache for all loggers in loggerDict
14187db96d56Sopenharmony_ci        Called when level changes are made
14197db96d56Sopenharmony_ci        """
14207db96d56Sopenharmony_ci
14217db96d56Sopenharmony_ci        _acquireLock()
14227db96d56Sopenharmony_ci        for logger in self.loggerDict.values():
14237db96d56Sopenharmony_ci            if isinstance(logger, Logger):
14247db96d56Sopenharmony_ci                logger._cache.clear()
14257db96d56Sopenharmony_ci        self.root._cache.clear()
14267db96d56Sopenharmony_ci        _releaseLock()
14277db96d56Sopenharmony_ci
14287db96d56Sopenharmony_ci#---------------------------------------------------------------------------
14297db96d56Sopenharmony_ci#   Logger classes and functions
14307db96d56Sopenharmony_ci#---------------------------------------------------------------------------
14317db96d56Sopenharmony_ci
14327db96d56Sopenharmony_ciclass Logger(Filterer):
14337db96d56Sopenharmony_ci    """
14347db96d56Sopenharmony_ci    Instances of the Logger class represent a single logging channel. A
14357db96d56Sopenharmony_ci    "logging channel" indicates an area of an application. Exactly how an
14367db96d56Sopenharmony_ci    "area" is defined is up to the application developer. Since an
14377db96d56Sopenharmony_ci    application can have any number of areas, logging channels are identified
14387db96d56Sopenharmony_ci    by a unique string. Application areas can be nested (e.g. an area
14397db96d56Sopenharmony_ci    of "input processing" might include sub-areas "read CSV files", "read
14407db96d56Sopenharmony_ci    XLS files" and "read Gnumeric files"). To cater for this natural nesting,
14417db96d56Sopenharmony_ci    channel names are organized into a namespace hierarchy where levels are
14427db96d56Sopenharmony_ci    separated by periods, much like the Java or Python package namespace. So
14437db96d56Sopenharmony_ci    in the instance given above, channel names might be "input" for the upper
14447db96d56Sopenharmony_ci    level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
14457db96d56Sopenharmony_ci    There is no arbitrary limit to the depth of nesting.
14467db96d56Sopenharmony_ci    """
14477db96d56Sopenharmony_ci    def __init__(self, name, level=NOTSET):
14487db96d56Sopenharmony_ci        """
14497db96d56Sopenharmony_ci        Initialize the logger with a name and an optional level.
14507db96d56Sopenharmony_ci        """
14517db96d56Sopenharmony_ci        Filterer.__init__(self)
14527db96d56Sopenharmony_ci        self.name = name
14537db96d56Sopenharmony_ci        self.level = _checkLevel(level)
14547db96d56Sopenharmony_ci        self.parent = None
14557db96d56Sopenharmony_ci        self.propagate = True
14567db96d56Sopenharmony_ci        self.handlers = []
14577db96d56Sopenharmony_ci        self.disabled = False
14587db96d56Sopenharmony_ci        self._cache = {}
14597db96d56Sopenharmony_ci
14607db96d56Sopenharmony_ci    def setLevel(self, level):
14617db96d56Sopenharmony_ci        """
14627db96d56Sopenharmony_ci        Set the logging level of this logger.  level must be an int or a str.
14637db96d56Sopenharmony_ci        """
14647db96d56Sopenharmony_ci        self.level = _checkLevel(level)
14657db96d56Sopenharmony_ci        self.manager._clear_cache()
14667db96d56Sopenharmony_ci
14677db96d56Sopenharmony_ci    def debug(self, msg, *args, **kwargs):
14687db96d56Sopenharmony_ci        """
14697db96d56Sopenharmony_ci        Log 'msg % args' with severity 'DEBUG'.
14707db96d56Sopenharmony_ci
14717db96d56Sopenharmony_ci        To pass exception information, use the keyword argument exc_info with
14727db96d56Sopenharmony_ci        a true value, e.g.
14737db96d56Sopenharmony_ci
14747db96d56Sopenharmony_ci        logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
14757db96d56Sopenharmony_ci        """
14767db96d56Sopenharmony_ci        if self.isEnabledFor(DEBUG):
14777db96d56Sopenharmony_ci            self._log(DEBUG, msg, args, **kwargs)
14787db96d56Sopenharmony_ci
14797db96d56Sopenharmony_ci    def info(self, msg, *args, **kwargs):
14807db96d56Sopenharmony_ci        """
14817db96d56Sopenharmony_ci        Log 'msg % args' with severity 'INFO'.
14827db96d56Sopenharmony_ci
14837db96d56Sopenharmony_ci        To pass exception information, use the keyword argument exc_info with
14847db96d56Sopenharmony_ci        a true value, e.g.
14857db96d56Sopenharmony_ci
14867db96d56Sopenharmony_ci        logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
14877db96d56Sopenharmony_ci        """
14887db96d56Sopenharmony_ci        if self.isEnabledFor(INFO):
14897db96d56Sopenharmony_ci            self._log(INFO, msg, args, **kwargs)
14907db96d56Sopenharmony_ci
14917db96d56Sopenharmony_ci    def warning(self, msg, *args, **kwargs):
14927db96d56Sopenharmony_ci        """
14937db96d56Sopenharmony_ci        Log 'msg % args' with severity 'WARNING'.
14947db96d56Sopenharmony_ci
14957db96d56Sopenharmony_ci        To pass exception information, use the keyword argument exc_info with
14967db96d56Sopenharmony_ci        a true value, e.g.
14977db96d56Sopenharmony_ci
14987db96d56Sopenharmony_ci        logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
14997db96d56Sopenharmony_ci        """
15007db96d56Sopenharmony_ci        if self.isEnabledFor(WARNING):
15017db96d56Sopenharmony_ci            self._log(WARNING, msg, args, **kwargs)
15027db96d56Sopenharmony_ci
15037db96d56Sopenharmony_ci    def warn(self, msg, *args, **kwargs):
15047db96d56Sopenharmony_ci        warnings.warn("The 'warn' method is deprecated, "
15057db96d56Sopenharmony_ci            "use 'warning' instead", DeprecationWarning, 2)
15067db96d56Sopenharmony_ci        self.warning(msg, *args, **kwargs)
15077db96d56Sopenharmony_ci
15087db96d56Sopenharmony_ci    def error(self, msg, *args, **kwargs):
15097db96d56Sopenharmony_ci        """
15107db96d56Sopenharmony_ci        Log 'msg % args' with severity 'ERROR'.
15117db96d56Sopenharmony_ci
15127db96d56Sopenharmony_ci        To pass exception information, use the keyword argument exc_info with
15137db96d56Sopenharmony_ci        a true value, e.g.
15147db96d56Sopenharmony_ci
15157db96d56Sopenharmony_ci        logger.error("Houston, we have a %s", "major problem", exc_info=1)
15167db96d56Sopenharmony_ci        """
15177db96d56Sopenharmony_ci        if self.isEnabledFor(ERROR):
15187db96d56Sopenharmony_ci            self._log(ERROR, msg, args, **kwargs)
15197db96d56Sopenharmony_ci
15207db96d56Sopenharmony_ci    def exception(self, msg, *args, exc_info=True, **kwargs):
15217db96d56Sopenharmony_ci        """
15227db96d56Sopenharmony_ci        Convenience method for logging an ERROR with exception information.
15237db96d56Sopenharmony_ci        """
15247db96d56Sopenharmony_ci        self.error(msg, *args, exc_info=exc_info, **kwargs)
15257db96d56Sopenharmony_ci
15267db96d56Sopenharmony_ci    def critical(self, msg, *args, **kwargs):
15277db96d56Sopenharmony_ci        """
15287db96d56Sopenharmony_ci        Log 'msg % args' with severity 'CRITICAL'.
15297db96d56Sopenharmony_ci
15307db96d56Sopenharmony_ci        To pass exception information, use the keyword argument exc_info with
15317db96d56Sopenharmony_ci        a true value, e.g.
15327db96d56Sopenharmony_ci
15337db96d56Sopenharmony_ci        logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
15347db96d56Sopenharmony_ci        """
15357db96d56Sopenharmony_ci        if self.isEnabledFor(CRITICAL):
15367db96d56Sopenharmony_ci            self._log(CRITICAL, msg, args, **kwargs)
15377db96d56Sopenharmony_ci
15387db96d56Sopenharmony_ci    def fatal(self, msg, *args, **kwargs):
15397db96d56Sopenharmony_ci        """
15407db96d56Sopenharmony_ci        Don't use this method, use critical() instead.
15417db96d56Sopenharmony_ci        """
15427db96d56Sopenharmony_ci        self.critical(msg, *args, **kwargs)
15437db96d56Sopenharmony_ci
15447db96d56Sopenharmony_ci    def log(self, level, msg, *args, **kwargs):
15457db96d56Sopenharmony_ci        """
15467db96d56Sopenharmony_ci        Log 'msg % args' with the integer severity 'level'.
15477db96d56Sopenharmony_ci
15487db96d56Sopenharmony_ci        To pass exception information, use the keyword argument exc_info with
15497db96d56Sopenharmony_ci        a true value, e.g.
15507db96d56Sopenharmony_ci
15517db96d56Sopenharmony_ci        logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
15527db96d56Sopenharmony_ci        """
15537db96d56Sopenharmony_ci        if not isinstance(level, int):
15547db96d56Sopenharmony_ci            if raiseExceptions:
15557db96d56Sopenharmony_ci                raise TypeError("level must be an integer")
15567db96d56Sopenharmony_ci            else:
15577db96d56Sopenharmony_ci                return
15587db96d56Sopenharmony_ci        if self.isEnabledFor(level):
15597db96d56Sopenharmony_ci            self._log(level, msg, args, **kwargs)
15607db96d56Sopenharmony_ci
15617db96d56Sopenharmony_ci    def findCaller(self, stack_info=False, stacklevel=1):
15627db96d56Sopenharmony_ci        """
15637db96d56Sopenharmony_ci        Find the stack frame of the caller so that we can note the source
15647db96d56Sopenharmony_ci        file name, line number and function name.
15657db96d56Sopenharmony_ci        """
15667db96d56Sopenharmony_ci        f = currentframe()
15677db96d56Sopenharmony_ci        #On some versions of IronPython, currentframe() returns None if
15687db96d56Sopenharmony_ci        #IronPython isn't run with -X:Frames.
15697db96d56Sopenharmony_ci        if f is None:
15707db96d56Sopenharmony_ci            return "(unknown file)", 0, "(unknown function)", None
15717db96d56Sopenharmony_ci        while stacklevel > 0:
15727db96d56Sopenharmony_ci            next_f = f.f_back
15737db96d56Sopenharmony_ci            if next_f is None:
15747db96d56Sopenharmony_ci                ## We've got options here.
15757db96d56Sopenharmony_ci                ## If we want to use the last (deepest) frame:
15767db96d56Sopenharmony_ci                break
15777db96d56Sopenharmony_ci                ## If we want to mimic the warnings module:
15787db96d56Sopenharmony_ci                #return ("sys", 1, "(unknown function)", None)
15797db96d56Sopenharmony_ci                ## If we want to be pedantic:
15807db96d56Sopenharmony_ci                #raise ValueError("call stack is not deep enough")
15817db96d56Sopenharmony_ci            f = next_f
15827db96d56Sopenharmony_ci            if not _is_internal_frame(f):
15837db96d56Sopenharmony_ci                stacklevel -= 1
15847db96d56Sopenharmony_ci        co = f.f_code
15857db96d56Sopenharmony_ci        sinfo = None
15867db96d56Sopenharmony_ci        if stack_info:
15877db96d56Sopenharmony_ci            with io.StringIO() as sio:
15887db96d56Sopenharmony_ci                sio.write("Stack (most recent call last):\n")
15897db96d56Sopenharmony_ci                traceback.print_stack(f, file=sio)
15907db96d56Sopenharmony_ci                sinfo = sio.getvalue()
15917db96d56Sopenharmony_ci                if sinfo[-1] == '\n':
15927db96d56Sopenharmony_ci                    sinfo = sinfo[:-1]
15937db96d56Sopenharmony_ci        return co.co_filename, f.f_lineno, co.co_name, sinfo
15947db96d56Sopenharmony_ci
15957db96d56Sopenharmony_ci    def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
15967db96d56Sopenharmony_ci                   func=None, extra=None, sinfo=None):
15977db96d56Sopenharmony_ci        """
15987db96d56Sopenharmony_ci        A factory method which can be overridden in subclasses to create
15997db96d56Sopenharmony_ci        specialized LogRecords.
16007db96d56Sopenharmony_ci        """
16017db96d56Sopenharmony_ci        rv = _logRecordFactory(name, level, fn, lno, msg, args, exc_info, func,
16027db96d56Sopenharmony_ci                             sinfo)
16037db96d56Sopenharmony_ci        if extra is not None:
16047db96d56Sopenharmony_ci            for key in extra:
16057db96d56Sopenharmony_ci                if (key in ["message", "asctime"]) or (key in rv.__dict__):
16067db96d56Sopenharmony_ci                    raise KeyError("Attempt to overwrite %r in LogRecord" % key)
16077db96d56Sopenharmony_ci                rv.__dict__[key] = extra[key]
16087db96d56Sopenharmony_ci        return rv
16097db96d56Sopenharmony_ci
16107db96d56Sopenharmony_ci    def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False,
16117db96d56Sopenharmony_ci             stacklevel=1):
16127db96d56Sopenharmony_ci        """
16137db96d56Sopenharmony_ci        Low-level logging routine which creates a LogRecord and then calls
16147db96d56Sopenharmony_ci        all the handlers of this logger to handle the record.
16157db96d56Sopenharmony_ci        """
16167db96d56Sopenharmony_ci        sinfo = None
16177db96d56Sopenharmony_ci        if _srcfile:
16187db96d56Sopenharmony_ci            #IronPython doesn't track Python frames, so findCaller raises an
16197db96d56Sopenharmony_ci            #exception on some versions of IronPython. We trap it here so that
16207db96d56Sopenharmony_ci            #IronPython can use logging.
16217db96d56Sopenharmony_ci            try:
16227db96d56Sopenharmony_ci                fn, lno, func, sinfo = self.findCaller(stack_info, stacklevel)
16237db96d56Sopenharmony_ci            except ValueError: # pragma: no cover
16247db96d56Sopenharmony_ci                fn, lno, func = "(unknown file)", 0, "(unknown function)"
16257db96d56Sopenharmony_ci        else: # pragma: no cover
16267db96d56Sopenharmony_ci            fn, lno, func = "(unknown file)", 0, "(unknown function)"
16277db96d56Sopenharmony_ci        if exc_info:
16287db96d56Sopenharmony_ci            if isinstance(exc_info, BaseException):
16297db96d56Sopenharmony_ci                exc_info = (type(exc_info), exc_info, exc_info.__traceback__)
16307db96d56Sopenharmony_ci            elif not isinstance(exc_info, tuple):
16317db96d56Sopenharmony_ci                exc_info = sys.exc_info()
16327db96d56Sopenharmony_ci        record = self.makeRecord(self.name, level, fn, lno, msg, args,
16337db96d56Sopenharmony_ci                                 exc_info, func, extra, sinfo)
16347db96d56Sopenharmony_ci        self.handle(record)
16357db96d56Sopenharmony_ci
16367db96d56Sopenharmony_ci    def handle(self, record):
16377db96d56Sopenharmony_ci        """
16387db96d56Sopenharmony_ci        Call the handlers for the specified record.
16397db96d56Sopenharmony_ci
16407db96d56Sopenharmony_ci        This method is used for unpickled records received from a socket, as
16417db96d56Sopenharmony_ci        well as those created locally. Logger-level filtering is applied.
16427db96d56Sopenharmony_ci        """
16437db96d56Sopenharmony_ci        if (not self.disabled) and self.filter(record):
16447db96d56Sopenharmony_ci            self.callHandlers(record)
16457db96d56Sopenharmony_ci
16467db96d56Sopenharmony_ci    def addHandler(self, hdlr):
16477db96d56Sopenharmony_ci        """
16487db96d56Sopenharmony_ci        Add the specified handler to this logger.
16497db96d56Sopenharmony_ci        """
16507db96d56Sopenharmony_ci        _acquireLock()
16517db96d56Sopenharmony_ci        try:
16527db96d56Sopenharmony_ci            if not (hdlr in self.handlers):
16537db96d56Sopenharmony_ci                self.handlers.append(hdlr)
16547db96d56Sopenharmony_ci        finally:
16557db96d56Sopenharmony_ci            _releaseLock()
16567db96d56Sopenharmony_ci
16577db96d56Sopenharmony_ci    def removeHandler(self, hdlr):
16587db96d56Sopenharmony_ci        """
16597db96d56Sopenharmony_ci        Remove the specified handler from this logger.
16607db96d56Sopenharmony_ci        """
16617db96d56Sopenharmony_ci        _acquireLock()
16627db96d56Sopenharmony_ci        try:
16637db96d56Sopenharmony_ci            if hdlr in self.handlers:
16647db96d56Sopenharmony_ci                self.handlers.remove(hdlr)
16657db96d56Sopenharmony_ci        finally:
16667db96d56Sopenharmony_ci            _releaseLock()
16677db96d56Sopenharmony_ci
16687db96d56Sopenharmony_ci    def hasHandlers(self):
16697db96d56Sopenharmony_ci        """
16707db96d56Sopenharmony_ci        See if this logger has any handlers configured.
16717db96d56Sopenharmony_ci
16727db96d56Sopenharmony_ci        Loop through all handlers for this logger and its parents in the
16737db96d56Sopenharmony_ci        logger hierarchy. Return True if a handler was found, else False.
16747db96d56Sopenharmony_ci        Stop searching up the hierarchy whenever a logger with the "propagate"
16757db96d56Sopenharmony_ci        attribute set to zero is found - that will be the last logger which
16767db96d56Sopenharmony_ci        is checked for the existence of handlers.
16777db96d56Sopenharmony_ci        """
16787db96d56Sopenharmony_ci        c = self
16797db96d56Sopenharmony_ci        rv = False
16807db96d56Sopenharmony_ci        while c:
16817db96d56Sopenharmony_ci            if c.handlers:
16827db96d56Sopenharmony_ci                rv = True
16837db96d56Sopenharmony_ci                break
16847db96d56Sopenharmony_ci            if not c.propagate:
16857db96d56Sopenharmony_ci                break
16867db96d56Sopenharmony_ci            else:
16877db96d56Sopenharmony_ci                c = c.parent
16887db96d56Sopenharmony_ci        return rv
16897db96d56Sopenharmony_ci
16907db96d56Sopenharmony_ci    def callHandlers(self, record):
16917db96d56Sopenharmony_ci        """
16927db96d56Sopenharmony_ci        Pass a record to all relevant handlers.
16937db96d56Sopenharmony_ci
16947db96d56Sopenharmony_ci        Loop through all handlers for this logger and its parents in the
16957db96d56Sopenharmony_ci        logger hierarchy. If no handler was found, output a one-off error
16967db96d56Sopenharmony_ci        message to sys.stderr. Stop searching up the hierarchy whenever a
16977db96d56Sopenharmony_ci        logger with the "propagate" attribute set to zero is found - that
16987db96d56Sopenharmony_ci        will be the last logger whose handlers are called.
16997db96d56Sopenharmony_ci        """
17007db96d56Sopenharmony_ci        c = self
17017db96d56Sopenharmony_ci        found = 0
17027db96d56Sopenharmony_ci        while c:
17037db96d56Sopenharmony_ci            for hdlr in c.handlers:
17047db96d56Sopenharmony_ci                found = found + 1
17057db96d56Sopenharmony_ci                if record.levelno >= hdlr.level:
17067db96d56Sopenharmony_ci                    hdlr.handle(record)
17077db96d56Sopenharmony_ci            if not c.propagate:
17087db96d56Sopenharmony_ci                c = None    #break out
17097db96d56Sopenharmony_ci            else:
17107db96d56Sopenharmony_ci                c = c.parent
17117db96d56Sopenharmony_ci        if (found == 0):
17127db96d56Sopenharmony_ci            if lastResort:
17137db96d56Sopenharmony_ci                if record.levelno >= lastResort.level:
17147db96d56Sopenharmony_ci                    lastResort.handle(record)
17157db96d56Sopenharmony_ci            elif raiseExceptions and not self.manager.emittedNoHandlerWarning:
17167db96d56Sopenharmony_ci                sys.stderr.write("No handlers could be found for logger"
17177db96d56Sopenharmony_ci                                 " \"%s\"\n" % self.name)
17187db96d56Sopenharmony_ci                self.manager.emittedNoHandlerWarning = True
17197db96d56Sopenharmony_ci
17207db96d56Sopenharmony_ci    def getEffectiveLevel(self):
17217db96d56Sopenharmony_ci        """
17227db96d56Sopenharmony_ci        Get the effective level for this logger.
17237db96d56Sopenharmony_ci
17247db96d56Sopenharmony_ci        Loop through this logger and its parents in the logger hierarchy,
17257db96d56Sopenharmony_ci        looking for a non-zero logging level. Return the first one found.
17267db96d56Sopenharmony_ci        """
17277db96d56Sopenharmony_ci        logger = self
17287db96d56Sopenharmony_ci        while logger:
17297db96d56Sopenharmony_ci            if logger.level:
17307db96d56Sopenharmony_ci                return logger.level
17317db96d56Sopenharmony_ci            logger = logger.parent
17327db96d56Sopenharmony_ci        return NOTSET
17337db96d56Sopenharmony_ci
17347db96d56Sopenharmony_ci    def isEnabledFor(self, level):
17357db96d56Sopenharmony_ci        """
17367db96d56Sopenharmony_ci        Is this logger enabled for level 'level'?
17377db96d56Sopenharmony_ci        """
17387db96d56Sopenharmony_ci        if self.disabled:
17397db96d56Sopenharmony_ci            return False
17407db96d56Sopenharmony_ci
17417db96d56Sopenharmony_ci        try:
17427db96d56Sopenharmony_ci            return self._cache[level]
17437db96d56Sopenharmony_ci        except KeyError:
17447db96d56Sopenharmony_ci            _acquireLock()
17457db96d56Sopenharmony_ci            try:
17467db96d56Sopenharmony_ci                if self.manager.disable >= level:
17477db96d56Sopenharmony_ci                    is_enabled = self._cache[level] = False
17487db96d56Sopenharmony_ci                else:
17497db96d56Sopenharmony_ci                    is_enabled = self._cache[level] = (
17507db96d56Sopenharmony_ci                        level >= self.getEffectiveLevel()
17517db96d56Sopenharmony_ci                    )
17527db96d56Sopenharmony_ci            finally:
17537db96d56Sopenharmony_ci                _releaseLock()
17547db96d56Sopenharmony_ci            return is_enabled
17557db96d56Sopenharmony_ci
17567db96d56Sopenharmony_ci    def getChild(self, suffix):
17577db96d56Sopenharmony_ci        """
17587db96d56Sopenharmony_ci        Get a logger which is a descendant to this one.
17597db96d56Sopenharmony_ci
17607db96d56Sopenharmony_ci        This is a convenience method, such that
17617db96d56Sopenharmony_ci
17627db96d56Sopenharmony_ci        logging.getLogger('abc').getChild('def.ghi')
17637db96d56Sopenharmony_ci
17647db96d56Sopenharmony_ci        is the same as
17657db96d56Sopenharmony_ci
17667db96d56Sopenharmony_ci        logging.getLogger('abc.def.ghi')
17677db96d56Sopenharmony_ci
17687db96d56Sopenharmony_ci        It's useful, for example, when the parent logger is named using
17697db96d56Sopenharmony_ci        __name__ rather than a literal string.
17707db96d56Sopenharmony_ci        """
17717db96d56Sopenharmony_ci        if self.root is not self:
17727db96d56Sopenharmony_ci            suffix = '.'.join((self.name, suffix))
17737db96d56Sopenharmony_ci        return self.manager.getLogger(suffix)
17747db96d56Sopenharmony_ci
17757db96d56Sopenharmony_ci    def __repr__(self):
17767db96d56Sopenharmony_ci        level = getLevelName(self.getEffectiveLevel())
17777db96d56Sopenharmony_ci        return '<%s %s (%s)>' % (self.__class__.__name__, self.name, level)
17787db96d56Sopenharmony_ci
17797db96d56Sopenharmony_ci    def __reduce__(self):
17807db96d56Sopenharmony_ci        if getLogger(self.name) is not self:
17817db96d56Sopenharmony_ci            import pickle
17827db96d56Sopenharmony_ci            raise pickle.PicklingError('logger cannot be pickled')
17837db96d56Sopenharmony_ci        return getLogger, (self.name,)
17847db96d56Sopenharmony_ci
17857db96d56Sopenharmony_ci
17867db96d56Sopenharmony_ciclass RootLogger(Logger):
17877db96d56Sopenharmony_ci    """
17887db96d56Sopenharmony_ci    A root logger is not that different to any other logger, except that
17897db96d56Sopenharmony_ci    it must have a logging level and there is only one instance of it in
17907db96d56Sopenharmony_ci    the hierarchy.
17917db96d56Sopenharmony_ci    """
17927db96d56Sopenharmony_ci    def __init__(self, level):
17937db96d56Sopenharmony_ci        """
17947db96d56Sopenharmony_ci        Initialize the logger with the name "root".
17957db96d56Sopenharmony_ci        """
17967db96d56Sopenharmony_ci        Logger.__init__(self, "root", level)
17977db96d56Sopenharmony_ci
17987db96d56Sopenharmony_ci    def __reduce__(self):
17997db96d56Sopenharmony_ci        return getLogger, ()
18007db96d56Sopenharmony_ci
18017db96d56Sopenharmony_ci_loggerClass = Logger
18027db96d56Sopenharmony_ci
18037db96d56Sopenharmony_ciclass LoggerAdapter(object):
18047db96d56Sopenharmony_ci    """
18057db96d56Sopenharmony_ci    An adapter for loggers which makes it easier to specify contextual
18067db96d56Sopenharmony_ci    information in logging output.
18077db96d56Sopenharmony_ci    """
18087db96d56Sopenharmony_ci
18097db96d56Sopenharmony_ci    def __init__(self, logger, extra=None):
18107db96d56Sopenharmony_ci        """
18117db96d56Sopenharmony_ci        Initialize the adapter with a logger and a dict-like object which
18127db96d56Sopenharmony_ci        provides contextual information. This constructor signature allows
18137db96d56Sopenharmony_ci        easy stacking of LoggerAdapters, if so desired.
18147db96d56Sopenharmony_ci
18157db96d56Sopenharmony_ci        You can effectively pass keyword arguments as shown in the
18167db96d56Sopenharmony_ci        following example:
18177db96d56Sopenharmony_ci
18187db96d56Sopenharmony_ci        adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
18197db96d56Sopenharmony_ci        """
18207db96d56Sopenharmony_ci        self.logger = logger
18217db96d56Sopenharmony_ci        self.extra = extra
18227db96d56Sopenharmony_ci
18237db96d56Sopenharmony_ci    def process(self, msg, kwargs):
18247db96d56Sopenharmony_ci        """
18257db96d56Sopenharmony_ci        Process the logging message and keyword arguments passed in to
18267db96d56Sopenharmony_ci        a logging call to insert contextual information. You can either
18277db96d56Sopenharmony_ci        manipulate the message itself, the keyword args or both. Return
18287db96d56Sopenharmony_ci        the message and kwargs modified (or not) to suit your needs.
18297db96d56Sopenharmony_ci
18307db96d56Sopenharmony_ci        Normally, you'll only need to override this one method in a
18317db96d56Sopenharmony_ci        LoggerAdapter subclass for your specific needs.
18327db96d56Sopenharmony_ci        """
18337db96d56Sopenharmony_ci        kwargs["extra"] = self.extra
18347db96d56Sopenharmony_ci        return msg, kwargs
18357db96d56Sopenharmony_ci
18367db96d56Sopenharmony_ci    #
18377db96d56Sopenharmony_ci    # Boilerplate convenience methods
18387db96d56Sopenharmony_ci    #
18397db96d56Sopenharmony_ci    def debug(self, msg, *args, **kwargs):
18407db96d56Sopenharmony_ci        """
18417db96d56Sopenharmony_ci        Delegate a debug call to the underlying logger.
18427db96d56Sopenharmony_ci        """
18437db96d56Sopenharmony_ci        self.log(DEBUG, msg, *args, **kwargs)
18447db96d56Sopenharmony_ci
18457db96d56Sopenharmony_ci    def info(self, msg, *args, **kwargs):
18467db96d56Sopenharmony_ci        """
18477db96d56Sopenharmony_ci        Delegate an info call to the underlying logger.
18487db96d56Sopenharmony_ci        """
18497db96d56Sopenharmony_ci        self.log(INFO, msg, *args, **kwargs)
18507db96d56Sopenharmony_ci
18517db96d56Sopenharmony_ci    def warning(self, msg, *args, **kwargs):
18527db96d56Sopenharmony_ci        """
18537db96d56Sopenharmony_ci        Delegate a warning call to the underlying logger.
18547db96d56Sopenharmony_ci        """
18557db96d56Sopenharmony_ci        self.log(WARNING, msg, *args, **kwargs)
18567db96d56Sopenharmony_ci
18577db96d56Sopenharmony_ci    def warn(self, msg, *args, **kwargs):
18587db96d56Sopenharmony_ci        warnings.warn("The 'warn' method is deprecated, "
18597db96d56Sopenharmony_ci            "use 'warning' instead", DeprecationWarning, 2)
18607db96d56Sopenharmony_ci        self.warning(msg, *args, **kwargs)
18617db96d56Sopenharmony_ci
18627db96d56Sopenharmony_ci    def error(self, msg, *args, **kwargs):
18637db96d56Sopenharmony_ci        """
18647db96d56Sopenharmony_ci        Delegate an error call to the underlying logger.
18657db96d56Sopenharmony_ci        """
18667db96d56Sopenharmony_ci        self.log(ERROR, msg, *args, **kwargs)
18677db96d56Sopenharmony_ci
18687db96d56Sopenharmony_ci    def exception(self, msg, *args, exc_info=True, **kwargs):
18697db96d56Sopenharmony_ci        """
18707db96d56Sopenharmony_ci        Delegate an exception call to the underlying logger.
18717db96d56Sopenharmony_ci        """
18727db96d56Sopenharmony_ci        self.log(ERROR, msg, *args, exc_info=exc_info, **kwargs)
18737db96d56Sopenharmony_ci
18747db96d56Sopenharmony_ci    def critical(self, msg, *args, **kwargs):
18757db96d56Sopenharmony_ci        """
18767db96d56Sopenharmony_ci        Delegate a critical call to the underlying logger.
18777db96d56Sopenharmony_ci        """
18787db96d56Sopenharmony_ci        self.log(CRITICAL, msg, *args, **kwargs)
18797db96d56Sopenharmony_ci
18807db96d56Sopenharmony_ci    def log(self, level, msg, *args, **kwargs):
18817db96d56Sopenharmony_ci        """
18827db96d56Sopenharmony_ci        Delegate a log call to the underlying logger, after adding
18837db96d56Sopenharmony_ci        contextual information from this adapter instance.
18847db96d56Sopenharmony_ci        """
18857db96d56Sopenharmony_ci        if self.isEnabledFor(level):
18867db96d56Sopenharmony_ci            msg, kwargs = self.process(msg, kwargs)
18877db96d56Sopenharmony_ci            self.logger.log(level, msg, *args, **kwargs)
18887db96d56Sopenharmony_ci
18897db96d56Sopenharmony_ci    def isEnabledFor(self, level):
18907db96d56Sopenharmony_ci        """
18917db96d56Sopenharmony_ci        Is this logger enabled for level 'level'?
18927db96d56Sopenharmony_ci        """
18937db96d56Sopenharmony_ci        return self.logger.isEnabledFor(level)
18947db96d56Sopenharmony_ci
18957db96d56Sopenharmony_ci    def setLevel(self, level):
18967db96d56Sopenharmony_ci        """
18977db96d56Sopenharmony_ci        Set the specified level on the underlying logger.
18987db96d56Sopenharmony_ci        """
18997db96d56Sopenharmony_ci        self.logger.setLevel(level)
19007db96d56Sopenharmony_ci
19017db96d56Sopenharmony_ci    def getEffectiveLevel(self):
19027db96d56Sopenharmony_ci        """
19037db96d56Sopenharmony_ci        Get the effective level for the underlying logger.
19047db96d56Sopenharmony_ci        """
19057db96d56Sopenharmony_ci        return self.logger.getEffectiveLevel()
19067db96d56Sopenharmony_ci
19077db96d56Sopenharmony_ci    def hasHandlers(self):
19087db96d56Sopenharmony_ci        """
19097db96d56Sopenharmony_ci        See if the underlying logger has any handlers.
19107db96d56Sopenharmony_ci        """
19117db96d56Sopenharmony_ci        return self.logger.hasHandlers()
19127db96d56Sopenharmony_ci
19137db96d56Sopenharmony_ci    def _log(self, level, msg, args, exc_info=None, extra=None, stack_info=False):
19147db96d56Sopenharmony_ci        """
19157db96d56Sopenharmony_ci        Low-level log implementation, proxied to allow nested logger adapters.
19167db96d56Sopenharmony_ci        """
19177db96d56Sopenharmony_ci        return self.logger._log(
19187db96d56Sopenharmony_ci            level,
19197db96d56Sopenharmony_ci            msg,
19207db96d56Sopenharmony_ci            args,
19217db96d56Sopenharmony_ci            exc_info=exc_info,
19227db96d56Sopenharmony_ci            extra=extra,
19237db96d56Sopenharmony_ci            stack_info=stack_info,
19247db96d56Sopenharmony_ci        )
19257db96d56Sopenharmony_ci
19267db96d56Sopenharmony_ci    @property
19277db96d56Sopenharmony_ci    def manager(self):
19287db96d56Sopenharmony_ci        return self.logger.manager
19297db96d56Sopenharmony_ci
19307db96d56Sopenharmony_ci    @manager.setter
19317db96d56Sopenharmony_ci    def manager(self, value):
19327db96d56Sopenharmony_ci        self.logger.manager = value
19337db96d56Sopenharmony_ci
19347db96d56Sopenharmony_ci    @property
19357db96d56Sopenharmony_ci    def name(self):
19367db96d56Sopenharmony_ci        return self.logger.name
19377db96d56Sopenharmony_ci
19387db96d56Sopenharmony_ci    def __repr__(self):
19397db96d56Sopenharmony_ci        logger = self.logger
19407db96d56Sopenharmony_ci        level = getLevelName(logger.getEffectiveLevel())
19417db96d56Sopenharmony_ci        return '<%s %s (%s)>' % (self.__class__.__name__, logger.name, level)
19427db96d56Sopenharmony_ci
19437db96d56Sopenharmony_ci    __class_getitem__ = classmethod(GenericAlias)
19447db96d56Sopenharmony_ci
19457db96d56Sopenharmony_ciroot = RootLogger(WARNING)
19467db96d56Sopenharmony_ciLogger.root = root
19477db96d56Sopenharmony_ciLogger.manager = Manager(Logger.root)
19487db96d56Sopenharmony_ci
19497db96d56Sopenharmony_ci#---------------------------------------------------------------------------
19507db96d56Sopenharmony_ci# Configuration classes and functions
19517db96d56Sopenharmony_ci#---------------------------------------------------------------------------
19527db96d56Sopenharmony_ci
19537db96d56Sopenharmony_cidef basicConfig(**kwargs):
19547db96d56Sopenharmony_ci    """
19557db96d56Sopenharmony_ci    Do basic configuration for the logging system.
19567db96d56Sopenharmony_ci
19577db96d56Sopenharmony_ci    This function does nothing if the root logger already has handlers
19587db96d56Sopenharmony_ci    configured, unless the keyword argument *force* is set to ``True``.
19597db96d56Sopenharmony_ci    It is a convenience method intended for use by simple scripts
19607db96d56Sopenharmony_ci    to do one-shot configuration of the logging package.
19617db96d56Sopenharmony_ci
19627db96d56Sopenharmony_ci    The default behaviour is to create a StreamHandler which writes to
19637db96d56Sopenharmony_ci    sys.stderr, set a formatter using the BASIC_FORMAT format string, and
19647db96d56Sopenharmony_ci    add the handler to the root logger.
19657db96d56Sopenharmony_ci
19667db96d56Sopenharmony_ci    A number of optional keyword arguments may be specified, which can alter
19677db96d56Sopenharmony_ci    the default behaviour.
19687db96d56Sopenharmony_ci
19697db96d56Sopenharmony_ci    filename  Specifies that a FileHandler be created, using the specified
19707db96d56Sopenharmony_ci              filename, rather than a StreamHandler.
19717db96d56Sopenharmony_ci    filemode  Specifies the mode to open the file, if filename is specified
19727db96d56Sopenharmony_ci              (if filemode is unspecified, it defaults to 'a').
19737db96d56Sopenharmony_ci    format    Use the specified format string for the handler.
19747db96d56Sopenharmony_ci    datefmt   Use the specified date/time format.
19757db96d56Sopenharmony_ci    style     If a format string is specified, use this to specify the
19767db96d56Sopenharmony_ci              type of format string (possible values '%', '{', '$', for
19777db96d56Sopenharmony_ci              %-formatting, :meth:`str.format` and :class:`string.Template`
19787db96d56Sopenharmony_ci              - defaults to '%').
19797db96d56Sopenharmony_ci    level     Set the root logger level to the specified level.
19807db96d56Sopenharmony_ci    stream    Use the specified stream to initialize the StreamHandler. Note
19817db96d56Sopenharmony_ci              that this argument is incompatible with 'filename' - if both
19827db96d56Sopenharmony_ci              are present, 'stream' is ignored.
19837db96d56Sopenharmony_ci    handlers  If specified, this should be an iterable of already created
19847db96d56Sopenharmony_ci              handlers, which will be added to the root handler. Any handler
19857db96d56Sopenharmony_ci              in the list which does not have a formatter assigned will be
19867db96d56Sopenharmony_ci              assigned the formatter created in this function.
19877db96d56Sopenharmony_ci    force     If this keyword  is specified as true, any existing handlers
19887db96d56Sopenharmony_ci              attached to the root logger are removed and closed, before
19897db96d56Sopenharmony_ci              carrying out the configuration as specified by the other
19907db96d56Sopenharmony_ci              arguments.
19917db96d56Sopenharmony_ci    encoding  If specified together with a filename, this encoding is passed to
19927db96d56Sopenharmony_ci              the created FileHandler, causing it to be used when the file is
19937db96d56Sopenharmony_ci              opened.
19947db96d56Sopenharmony_ci    errors    If specified together with a filename, this value is passed to the
19957db96d56Sopenharmony_ci              created FileHandler, causing it to be used when the file is
19967db96d56Sopenharmony_ci              opened in text mode. If not specified, the default value is
19977db96d56Sopenharmony_ci              `backslashreplace`.
19987db96d56Sopenharmony_ci
19997db96d56Sopenharmony_ci    Note that you could specify a stream created using open(filename, mode)
20007db96d56Sopenharmony_ci    rather than passing the filename and mode in. However, it should be
20017db96d56Sopenharmony_ci    remembered that StreamHandler does not close its stream (since it may be
20027db96d56Sopenharmony_ci    using sys.stdout or sys.stderr), whereas FileHandler closes its stream
20037db96d56Sopenharmony_ci    when the handler is closed.
20047db96d56Sopenharmony_ci
20057db96d56Sopenharmony_ci    .. versionchanged:: 3.2
20067db96d56Sopenharmony_ci       Added the ``style`` parameter.
20077db96d56Sopenharmony_ci
20087db96d56Sopenharmony_ci    .. versionchanged:: 3.3
20097db96d56Sopenharmony_ci       Added the ``handlers`` parameter. A ``ValueError`` is now thrown for
20107db96d56Sopenharmony_ci       incompatible arguments (e.g. ``handlers`` specified together with
20117db96d56Sopenharmony_ci       ``filename``/``filemode``, or ``filename``/``filemode`` specified
20127db96d56Sopenharmony_ci       together with ``stream``, or ``handlers`` specified together with
20137db96d56Sopenharmony_ci       ``stream``.
20147db96d56Sopenharmony_ci
20157db96d56Sopenharmony_ci    .. versionchanged:: 3.8
20167db96d56Sopenharmony_ci       Added the ``force`` parameter.
20177db96d56Sopenharmony_ci
20187db96d56Sopenharmony_ci    .. versionchanged:: 3.9
20197db96d56Sopenharmony_ci       Added the ``encoding`` and ``errors`` parameters.
20207db96d56Sopenharmony_ci    """
20217db96d56Sopenharmony_ci    # Add thread safety in case someone mistakenly calls
20227db96d56Sopenharmony_ci    # basicConfig() from multiple threads
20237db96d56Sopenharmony_ci    _acquireLock()
20247db96d56Sopenharmony_ci    try:
20257db96d56Sopenharmony_ci        force = kwargs.pop('force', False)
20267db96d56Sopenharmony_ci        encoding = kwargs.pop('encoding', None)
20277db96d56Sopenharmony_ci        errors = kwargs.pop('errors', 'backslashreplace')
20287db96d56Sopenharmony_ci        if force:
20297db96d56Sopenharmony_ci            for h in root.handlers[:]:
20307db96d56Sopenharmony_ci                root.removeHandler(h)
20317db96d56Sopenharmony_ci                h.close()
20327db96d56Sopenharmony_ci        if len(root.handlers) == 0:
20337db96d56Sopenharmony_ci            handlers = kwargs.pop("handlers", None)
20347db96d56Sopenharmony_ci            if handlers is None:
20357db96d56Sopenharmony_ci                if "stream" in kwargs and "filename" in kwargs:
20367db96d56Sopenharmony_ci                    raise ValueError("'stream' and 'filename' should not be "
20377db96d56Sopenharmony_ci                                     "specified together")
20387db96d56Sopenharmony_ci            else:
20397db96d56Sopenharmony_ci                if "stream" in kwargs or "filename" in kwargs:
20407db96d56Sopenharmony_ci                    raise ValueError("'stream' or 'filename' should not be "
20417db96d56Sopenharmony_ci                                     "specified together with 'handlers'")
20427db96d56Sopenharmony_ci            if handlers is None:
20437db96d56Sopenharmony_ci                filename = kwargs.pop("filename", None)
20447db96d56Sopenharmony_ci                mode = kwargs.pop("filemode", 'a')
20457db96d56Sopenharmony_ci                if filename:
20467db96d56Sopenharmony_ci                    if 'b' in mode:
20477db96d56Sopenharmony_ci                        errors = None
20487db96d56Sopenharmony_ci                    else:
20497db96d56Sopenharmony_ci                        encoding = io.text_encoding(encoding)
20507db96d56Sopenharmony_ci                    h = FileHandler(filename, mode,
20517db96d56Sopenharmony_ci                                    encoding=encoding, errors=errors)
20527db96d56Sopenharmony_ci                else:
20537db96d56Sopenharmony_ci                    stream = kwargs.pop("stream", None)
20547db96d56Sopenharmony_ci                    h = StreamHandler(stream)
20557db96d56Sopenharmony_ci                handlers = [h]
20567db96d56Sopenharmony_ci            dfs = kwargs.pop("datefmt", None)
20577db96d56Sopenharmony_ci            style = kwargs.pop("style", '%')
20587db96d56Sopenharmony_ci            if style not in _STYLES:
20597db96d56Sopenharmony_ci                raise ValueError('Style must be one of: %s' % ','.join(
20607db96d56Sopenharmony_ci                                 _STYLES.keys()))
20617db96d56Sopenharmony_ci            fs = kwargs.pop("format", _STYLES[style][1])
20627db96d56Sopenharmony_ci            fmt = Formatter(fs, dfs, style)
20637db96d56Sopenharmony_ci            for h in handlers:
20647db96d56Sopenharmony_ci                if h.formatter is None:
20657db96d56Sopenharmony_ci                    h.setFormatter(fmt)
20667db96d56Sopenharmony_ci                root.addHandler(h)
20677db96d56Sopenharmony_ci            level = kwargs.pop("level", None)
20687db96d56Sopenharmony_ci            if level is not None:
20697db96d56Sopenharmony_ci                root.setLevel(level)
20707db96d56Sopenharmony_ci            if kwargs:
20717db96d56Sopenharmony_ci                keys = ', '.join(kwargs.keys())
20727db96d56Sopenharmony_ci                raise ValueError('Unrecognised argument(s): %s' % keys)
20737db96d56Sopenharmony_ci    finally:
20747db96d56Sopenharmony_ci        _releaseLock()
20757db96d56Sopenharmony_ci
20767db96d56Sopenharmony_ci#---------------------------------------------------------------------------
20777db96d56Sopenharmony_ci# Utility functions at module level.
20787db96d56Sopenharmony_ci# Basically delegate everything to the root logger.
20797db96d56Sopenharmony_ci#---------------------------------------------------------------------------
20807db96d56Sopenharmony_ci
20817db96d56Sopenharmony_cidef getLogger(name=None):
20827db96d56Sopenharmony_ci    """
20837db96d56Sopenharmony_ci    Return a logger with the specified name, creating it if necessary.
20847db96d56Sopenharmony_ci
20857db96d56Sopenharmony_ci    If no name is specified, return the root logger.
20867db96d56Sopenharmony_ci    """
20877db96d56Sopenharmony_ci    if not name or isinstance(name, str) and name == root.name:
20887db96d56Sopenharmony_ci        return root
20897db96d56Sopenharmony_ci    return Logger.manager.getLogger(name)
20907db96d56Sopenharmony_ci
20917db96d56Sopenharmony_cidef critical(msg, *args, **kwargs):
20927db96d56Sopenharmony_ci    """
20937db96d56Sopenharmony_ci    Log a message with severity 'CRITICAL' on the root logger. If the logger
20947db96d56Sopenharmony_ci    has no handlers, call basicConfig() to add a console handler with a
20957db96d56Sopenharmony_ci    pre-defined format.
20967db96d56Sopenharmony_ci    """
20977db96d56Sopenharmony_ci    if len(root.handlers) == 0:
20987db96d56Sopenharmony_ci        basicConfig()
20997db96d56Sopenharmony_ci    root.critical(msg, *args, **kwargs)
21007db96d56Sopenharmony_ci
21017db96d56Sopenharmony_cidef fatal(msg, *args, **kwargs):
21027db96d56Sopenharmony_ci    """
21037db96d56Sopenharmony_ci    Don't use this function, use critical() instead.
21047db96d56Sopenharmony_ci    """
21057db96d56Sopenharmony_ci    critical(msg, *args, **kwargs)
21067db96d56Sopenharmony_ci
21077db96d56Sopenharmony_cidef error(msg, *args, **kwargs):
21087db96d56Sopenharmony_ci    """
21097db96d56Sopenharmony_ci    Log a message with severity 'ERROR' on the root logger. If the logger has
21107db96d56Sopenharmony_ci    no handlers, call basicConfig() to add a console handler with a pre-defined
21117db96d56Sopenharmony_ci    format.
21127db96d56Sopenharmony_ci    """
21137db96d56Sopenharmony_ci    if len(root.handlers) == 0:
21147db96d56Sopenharmony_ci        basicConfig()
21157db96d56Sopenharmony_ci    root.error(msg, *args, **kwargs)
21167db96d56Sopenharmony_ci
21177db96d56Sopenharmony_cidef exception(msg, *args, exc_info=True, **kwargs):
21187db96d56Sopenharmony_ci    """
21197db96d56Sopenharmony_ci    Log a message with severity 'ERROR' on the root logger, with exception
21207db96d56Sopenharmony_ci    information. If the logger has no handlers, basicConfig() is called to add
21217db96d56Sopenharmony_ci    a console handler with a pre-defined format.
21227db96d56Sopenharmony_ci    """
21237db96d56Sopenharmony_ci    error(msg, *args, exc_info=exc_info, **kwargs)
21247db96d56Sopenharmony_ci
21257db96d56Sopenharmony_cidef warning(msg, *args, **kwargs):
21267db96d56Sopenharmony_ci    """
21277db96d56Sopenharmony_ci    Log a message with severity 'WARNING' on the root logger. If the logger has
21287db96d56Sopenharmony_ci    no handlers, call basicConfig() to add a console handler with a pre-defined
21297db96d56Sopenharmony_ci    format.
21307db96d56Sopenharmony_ci    """
21317db96d56Sopenharmony_ci    if len(root.handlers) == 0:
21327db96d56Sopenharmony_ci        basicConfig()
21337db96d56Sopenharmony_ci    root.warning(msg, *args, **kwargs)
21347db96d56Sopenharmony_ci
21357db96d56Sopenharmony_cidef warn(msg, *args, **kwargs):
21367db96d56Sopenharmony_ci    warnings.warn("The 'warn' function is deprecated, "
21377db96d56Sopenharmony_ci        "use 'warning' instead", DeprecationWarning, 2)
21387db96d56Sopenharmony_ci    warning(msg, *args, **kwargs)
21397db96d56Sopenharmony_ci
21407db96d56Sopenharmony_cidef info(msg, *args, **kwargs):
21417db96d56Sopenharmony_ci    """
21427db96d56Sopenharmony_ci    Log a message with severity 'INFO' on the root logger. If the logger has
21437db96d56Sopenharmony_ci    no handlers, call basicConfig() to add a console handler with a pre-defined
21447db96d56Sopenharmony_ci    format.
21457db96d56Sopenharmony_ci    """
21467db96d56Sopenharmony_ci    if len(root.handlers) == 0:
21477db96d56Sopenharmony_ci        basicConfig()
21487db96d56Sopenharmony_ci    root.info(msg, *args, **kwargs)
21497db96d56Sopenharmony_ci
21507db96d56Sopenharmony_cidef debug(msg, *args, **kwargs):
21517db96d56Sopenharmony_ci    """
21527db96d56Sopenharmony_ci    Log a message with severity 'DEBUG' on the root logger. If the logger has
21537db96d56Sopenharmony_ci    no handlers, call basicConfig() to add a console handler with a pre-defined
21547db96d56Sopenharmony_ci    format.
21557db96d56Sopenharmony_ci    """
21567db96d56Sopenharmony_ci    if len(root.handlers) == 0:
21577db96d56Sopenharmony_ci        basicConfig()
21587db96d56Sopenharmony_ci    root.debug(msg, *args, **kwargs)
21597db96d56Sopenharmony_ci
21607db96d56Sopenharmony_cidef log(level, msg, *args, **kwargs):
21617db96d56Sopenharmony_ci    """
21627db96d56Sopenharmony_ci    Log 'msg % args' with the integer severity 'level' on the root logger. If
21637db96d56Sopenharmony_ci    the logger has no handlers, call basicConfig() to add a console handler
21647db96d56Sopenharmony_ci    with a pre-defined format.
21657db96d56Sopenharmony_ci    """
21667db96d56Sopenharmony_ci    if len(root.handlers) == 0:
21677db96d56Sopenharmony_ci        basicConfig()
21687db96d56Sopenharmony_ci    root.log(level, msg, *args, **kwargs)
21697db96d56Sopenharmony_ci
21707db96d56Sopenharmony_cidef disable(level=CRITICAL):
21717db96d56Sopenharmony_ci    """
21727db96d56Sopenharmony_ci    Disable all logging calls of severity 'level' and below.
21737db96d56Sopenharmony_ci    """
21747db96d56Sopenharmony_ci    root.manager.disable = level
21757db96d56Sopenharmony_ci    root.manager._clear_cache()
21767db96d56Sopenharmony_ci
21777db96d56Sopenharmony_cidef shutdown(handlerList=_handlerList):
21787db96d56Sopenharmony_ci    """
21797db96d56Sopenharmony_ci    Perform any cleanup actions in the logging system (e.g. flushing
21807db96d56Sopenharmony_ci    buffers).
21817db96d56Sopenharmony_ci
21827db96d56Sopenharmony_ci    Should be called at application exit.
21837db96d56Sopenharmony_ci    """
21847db96d56Sopenharmony_ci    for wr in reversed(handlerList[:]):
21857db96d56Sopenharmony_ci        #errors might occur, for example, if files are locked
21867db96d56Sopenharmony_ci        #we just ignore them if raiseExceptions is not set
21877db96d56Sopenharmony_ci        try:
21887db96d56Sopenharmony_ci            h = wr()
21897db96d56Sopenharmony_ci            if h:
21907db96d56Sopenharmony_ci                try:
21917db96d56Sopenharmony_ci                    h.acquire()
21927db96d56Sopenharmony_ci                    h.flush()
21937db96d56Sopenharmony_ci                    h.close()
21947db96d56Sopenharmony_ci                except (OSError, ValueError):
21957db96d56Sopenharmony_ci                    # Ignore errors which might be caused
21967db96d56Sopenharmony_ci                    # because handlers have been closed but
21977db96d56Sopenharmony_ci                    # references to them are still around at
21987db96d56Sopenharmony_ci                    # application exit.
21997db96d56Sopenharmony_ci                    pass
22007db96d56Sopenharmony_ci                finally:
22017db96d56Sopenharmony_ci                    h.release()
22027db96d56Sopenharmony_ci        except: # ignore everything, as we're shutting down
22037db96d56Sopenharmony_ci            if raiseExceptions:
22047db96d56Sopenharmony_ci                raise
22057db96d56Sopenharmony_ci            #else, swallow
22067db96d56Sopenharmony_ci
22077db96d56Sopenharmony_ci#Let's try and shutdown automatically on application exit...
22087db96d56Sopenharmony_ciimport atexit
22097db96d56Sopenharmony_ciatexit.register(shutdown)
22107db96d56Sopenharmony_ci
22117db96d56Sopenharmony_ci# Null handler
22127db96d56Sopenharmony_ci
22137db96d56Sopenharmony_ciclass NullHandler(Handler):
22147db96d56Sopenharmony_ci    """
22157db96d56Sopenharmony_ci    This handler does nothing. It's intended to be used to avoid the
22167db96d56Sopenharmony_ci    "No handlers could be found for logger XXX" one-off warning. This is
22177db96d56Sopenharmony_ci    important for library code, which may contain code to log events. If a user
22187db96d56Sopenharmony_ci    of the library does not configure logging, the one-off warning might be
22197db96d56Sopenharmony_ci    produced; to avoid this, the library developer simply needs to instantiate
22207db96d56Sopenharmony_ci    a NullHandler and add it to the top-level logger of the library module or
22217db96d56Sopenharmony_ci    package.
22227db96d56Sopenharmony_ci    """
22237db96d56Sopenharmony_ci    def handle(self, record):
22247db96d56Sopenharmony_ci        """Stub."""
22257db96d56Sopenharmony_ci
22267db96d56Sopenharmony_ci    def emit(self, record):
22277db96d56Sopenharmony_ci        """Stub."""
22287db96d56Sopenharmony_ci
22297db96d56Sopenharmony_ci    def createLock(self):
22307db96d56Sopenharmony_ci        self.lock = None
22317db96d56Sopenharmony_ci
22327db96d56Sopenharmony_ci    def _at_fork_reinit(self):
22337db96d56Sopenharmony_ci        pass
22347db96d56Sopenharmony_ci
22357db96d56Sopenharmony_ci# Warnings integration
22367db96d56Sopenharmony_ci
22377db96d56Sopenharmony_ci_warnings_showwarning = None
22387db96d56Sopenharmony_ci
22397db96d56Sopenharmony_cidef _showwarning(message, category, filename, lineno, file=None, line=None):
22407db96d56Sopenharmony_ci    """
22417db96d56Sopenharmony_ci    Implementation of showwarnings which redirects to logging, which will first
22427db96d56Sopenharmony_ci    check to see if the file parameter is None. If a file is specified, it will
22437db96d56Sopenharmony_ci    delegate to the original warnings implementation of showwarning. Otherwise,
22447db96d56Sopenharmony_ci    it will call warnings.formatwarning and will log the resulting string to a
22457db96d56Sopenharmony_ci    warnings logger named "py.warnings" with level logging.WARNING.
22467db96d56Sopenharmony_ci    """
22477db96d56Sopenharmony_ci    if file is not None:
22487db96d56Sopenharmony_ci        if _warnings_showwarning is not None:
22497db96d56Sopenharmony_ci            _warnings_showwarning(message, category, filename, lineno, file, line)
22507db96d56Sopenharmony_ci    else:
22517db96d56Sopenharmony_ci        s = warnings.formatwarning(message, category, filename, lineno, line)
22527db96d56Sopenharmony_ci        logger = getLogger("py.warnings")
22537db96d56Sopenharmony_ci        if not logger.handlers:
22547db96d56Sopenharmony_ci            logger.addHandler(NullHandler())
22557db96d56Sopenharmony_ci        # bpo-46557: Log str(s) as msg instead of logger.warning("%s", s)
22567db96d56Sopenharmony_ci        # since some log aggregation tools group logs by the msg arg
22577db96d56Sopenharmony_ci        logger.warning(str(s))
22587db96d56Sopenharmony_ci
22597db96d56Sopenharmony_cidef captureWarnings(capture):
22607db96d56Sopenharmony_ci    """
22617db96d56Sopenharmony_ci    If capture is true, redirect all warnings to the logging package.
22627db96d56Sopenharmony_ci    If capture is False, ensure that warnings are not redirected to logging
22637db96d56Sopenharmony_ci    but to their original destinations.
22647db96d56Sopenharmony_ci    """
22657db96d56Sopenharmony_ci    global _warnings_showwarning
22667db96d56Sopenharmony_ci    if capture:
22677db96d56Sopenharmony_ci        if _warnings_showwarning is None:
22687db96d56Sopenharmony_ci            _warnings_showwarning = warnings.showwarning
22697db96d56Sopenharmony_ci            warnings.showwarning = _showwarning
22707db96d56Sopenharmony_ci    else:
22717db96d56Sopenharmony_ci        if _warnings_showwarning is not None:
22727db96d56Sopenharmony_ci            warnings.showwarning = _warnings_showwarning
22737db96d56Sopenharmony_ci            _warnings_showwarning = None
2274