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