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