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