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