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