Manual py3k backport: [svn r74155] Issue #6242: Fix deallocator of io.StringIO and...
[python.git] / Lib / logging / __init__.py
blobf85296d8665534b49a3f9fe12a9db3e2683802f0
1 # Copyright 2001-2009 by Vinay Sajip. All Rights Reserved.
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.
17 """
18 Logging package for Python. Based on PEP 282 and comments thereto in
19 comp.lang.python, and influenced by Apache's log4j system.
21 Copyright (C) 2001-2009 Vinay Sajip. All Rights Reserved.
23 To use, simply 'import logging' and log away!
24 """
26 import sys, os, time, cStringIO, traceback, warnings
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']
36 try:
37 import codecs
38 except ImportError:
39 codecs = None
41 try:
42 import thread
43 import threading
44 except ImportError:
45 thread = None
47 __author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
48 __status__ = "production"
49 __version__ = "0.5.0.9"
50 __date__ = "09 October 2009"
52 #---------------------------------------------------------------------------
53 # Miscellaneous module data
54 #---------------------------------------------------------------------------
55 try:
56 unicode
57 _unicode = True
58 except NameError:
59 _unicode = False
62 # _srcfile is used when walking the stack to check when we've got the first
63 # caller stack frame.
65 if hasattr(sys, 'frozen'): #support for py2exe
66 _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
67 elif __file__[-4:].lower() in ['.pyc', '.pyo']:
68 _srcfile = __file__[:-4] + '.py'
69 else:
70 _srcfile = __file__
71 _srcfile = os.path.normcase(_srcfile)
73 # next bit filched from 1.5.2's inspect.py
74 def currentframe():
75 """Return the frame object for the caller's stack frame."""
76 try:
77 raise Exception
78 except:
79 return sys.exc_info()[2].tb_frame.f_back
81 if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
82 # done filching
84 # _srcfile is only used in conjunction with sys._getframe().
85 # To provide compatibility with older versions of Python, set _srcfile
86 # to None if _getframe() is not available; this value will prevent
87 # findCaller() from being called.
88 #if not hasattr(sys, "_getframe"):
89 # _srcfile = None
92 #_startTime is used as the base when calculating the relative time of events
94 _startTime = time.time()
97 #raiseExceptions is used to see if exceptions during handling should be
98 #propagated
100 raiseExceptions = 1
103 # If you don't want threading information in the log, set this to zero
105 logThreads = 1
108 # If you don't want multiprocessing information in the log, set this to zero
110 logMultiprocessing = 1
113 # If you don't want process information in the log, set this to zero
115 logProcesses = 1
117 #---------------------------------------------------------------------------
118 # Level related stuff
119 #---------------------------------------------------------------------------
121 # Default levels and level names, these can be replaced with any positive set
122 # of values having corresponding names. There is a pseudo-level, NOTSET, which
123 # is only really there as a lower limit for user-defined levels. Handlers and
124 # loggers are initialized with NOTSET so that they will log all messages, even
125 # at user-defined levels.
128 CRITICAL = 50
129 FATAL = CRITICAL
130 ERROR = 40
131 WARNING = 30
132 WARN = WARNING
133 INFO = 20
134 DEBUG = 10
135 NOTSET = 0
137 _levelNames = {
138 CRITICAL : 'CRITICAL',
139 ERROR : 'ERROR',
140 WARNING : 'WARNING',
141 INFO : 'INFO',
142 DEBUG : 'DEBUG',
143 NOTSET : 'NOTSET',
144 'CRITICAL' : CRITICAL,
145 'ERROR' : ERROR,
146 'WARN' : WARNING,
147 'WARNING' : WARNING,
148 'INFO' : INFO,
149 'DEBUG' : DEBUG,
150 'NOTSET' : NOTSET,
153 def getLevelName(level):
155 Return the textual representation of logging level 'level'.
157 If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
158 INFO, DEBUG) then you get the corresponding string. If you have
159 associated levels with names using addLevelName then the name you have
160 associated with 'level' is returned.
162 If a numeric value corresponding to one of the defined levels is passed
163 in, the corresponding string representation is returned.
165 Otherwise, the string "Level %s" % level is returned.
167 return _levelNames.get(level, ("Level %s" % level))
169 def addLevelName(level, levelName):
171 Associate 'levelName' with 'level'.
173 This is used when converting levels to text during message formatting.
175 _acquireLock()
176 try: #unlikely to cause an exception, but you never know...
177 _levelNames[level] = levelName
178 _levelNames[levelName] = level
179 finally:
180 _releaseLock()
182 def _checkLevel(level):
183 if isinstance(level, int):
184 rv = level
185 elif str(level) == level:
186 if level not in _levelNames:
187 raise ValueError("Unknown level: %r" % level)
188 rv = _levelNames[level]
189 else:
190 raise TypeError("Level not an integer or a valid string: %r" % level)
191 return rv
193 #---------------------------------------------------------------------------
194 # Thread-related stuff
195 #---------------------------------------------------------------------------
198 #_lock is used to serialize access to shared data structures in this module.
199 #This needs to be an RLock because fileConfig() creates Handlers and so
200 #might arbitrary user threads. Since Handler.__init__() updates the shared
201 #dictionary _handlers, it needs to acquire the lock. But if configuring,
202 #the lock would already have been acquired - so we need an RLock.
203 #The same argument applies to Loggers and Manager.loggerDict.
205 _lock = None
207 def _acquireLock():
209 Acquire the module-level lock for serializing access to shared data.
211 This should be released with _releaseLock().
213 global _lock
214 if (not _lock) and thread:
215 _lock = threading.RLock()
216 if _lock:
217 _lock.acquire()
219 def _releaseLock():
221 Release the module-level lock acquired by calling _acquireLock().
223 if _lock:
224 _lock.release()
226 #---------------------------------------------------------------------------
227 # The logging record
228 #---------------------------------------------------------------------------
230 class LogRecord:
232 A LogRecord instance represents an event being logged.
234 LogRecord instances are created every time something is logged. They
235 contain all the information pertinent to the event being logged. The
236 main information passed in is in msg and args, which are combined
237 using str(msg) % args to create the message field of the record. The
238 record also includes information such as when the record was created,
239 the source line where the logging call was made, and any exception
240 information to be logged.
242 def __init__(self, name, level, pathname, lineno,
243 msg, args, exc_info, func=None):
245 Initialize a logging record with interesting information.
247 ct = time.time()
248 self.name = name
249 self.msg = msg
251 # The following statement allows passing of a dictionary as a sole
252 # argument, so that you can do something like
253 # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
254 # Suggested by Stefan Behnel.
255 # Note that without the test for args[0], we get a problem because
256 # during formatting, we test to see if the arg is present using
257 # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
258 # and if the passed arg fails 'if self.args:' then no formatting
259 # is done. For example, logger.warn('Value is %d', 0) would log
260 # 'Value is %d' instead of 'Value is 0'.
261 # For the use case of passing a dictionary, this should not be a
262 # problem.
263 if args and len(args) == 1 and isinstance(args[0], dict) and args[0]:
264 args = args[0]
265 self.args = args
266 self.levelname = getLevelName(level)
267 self.levelno = level
268 self.pathname = pathname
269 try:
270 self.filename = os.path.basename(pathname)
271 self.module = os.path.splitext(self.filename)[0]
272 except (TypeError, ValueError, AttributeError):
273 self.filename = pathname
274 self.module = "Unknown module"
275 self.exc_info = exc_info
276 self.exc_text = None # used to cache the traceback text
277 self.lineno = lineno
278 self.funcName = func
279 self.created = ct
280 self.msecs = (ct - long(ct)) * 1000
281 self.relativeCreated = (self.created - _startTime) * 1000
282 if logThreads and thread:
283 self.thread = thread.get_ident()
284 self.threadName = threading.current_thread().name
285 else:
286 self.thread = None
287 self.threadName = None
288 if not logMultiprocessing:
289 self.processName = None
290 elif 'multiprocessing' not in sys.modules:
291 self.processName = 'MainProcess'
292 else:
293 self.processName = sys.modules['multiprocessing'].current_process().name
294 if logProcesses and hasattr(os, 'getpid'):
295 self.process = os.getpid()
296 else:
297 self.process = None
299 def __str__(self):
300 return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
301 self.pathname, self.lineno, self.msg)
303 def getMessage(self):
305 Return the message for this LogRecord.
307 Return the message for this LogRecord after merging any user-supplied
308 arguments with the message.
310 if not _unicode: #if no unicode support...
311 msg = str(self.msg)
312 else:
313 msg = self.msg
314 if not isinstance(msg, basestring):
315 try:
316 msg = str(self.msg)
317 except UnicodeError:
318 msg = self.msg #Defer encoding till later
319 if self.args:
320 msg = msg % self.args
321 return msg
323 def makeLogRecord(dict):
325 Make a LogRecord whose attributes are defined by the specified dictionary,
326 This function is useful for converting a logging event received over
327 a socket connection (which is sent as a dictionary) into a LogRecord
328 instance.
330 rv = LogRecord(None, None, "", 0, "", (), None, None)
331 rv.__dict__.update(dict)
332 return rv
334 #---------------------------------------------------------------------------
335 # Formatter classes and functions
336 #---------------------------------------------------------------------------
338 class Formatter:
340 Formatter instances are used to convert a LogRecord to text.
342 Formatters need to know how a LogRecord is constructed. They are
343 responsible for converting a LogRecord to (usually) a string which can
344 be interpreted by either a human or an external system. The base Formatter
345 allows a formatting string to be specified. If none is supplied, the
346 default value of "%s(message)\\n" is used.
348 The Formatter can be initialized with a format string which makes use of
349 knowledge of the LogRecord attributes - e.g. the default value mentioned
350 above makes use of the fact that the user's message and arguments are pre-
351 formatted into a LogRecord's message attribute. Currently, the useful
352 attributes in a LogRecord are described by:
354 %(name)s Name of the logger (logging channel)
355 %(levelno)s Numeric logging level for the message (DEBUG, INFO,
356 WARNING, ERROR, CRITICAL)
357 %(levelname)s Text logging level for the message ("DEBUG", "INFO",
358 "WARNING", "ERROR", "CRITICAL")
359 %(pathname)s Full pathname of the source file where the logging
360 call was issued (if available)
361 %(filename)s Filename portion of pathname
362 %(module)s Module (name portion of filename)
363 %(lineno)d Source line number where the logging call was issued
364 (if available)
365 %(funcName)s Function name
366 %(created)f Time when the LogRecord was created (time.time()
367 return value)
368 %(asctime)s Textual time when the LogRecord was created
369 %(msecs)d Millisecond portion of the creation time
370 %(relativeCreated)d Time in milliseconds when the LogRecord was created,
371 relative to the time the logging module was loaded
372 (typically at application startup time)
373 %(thread)d Thread ID (if available)
374 %(threadName)s Thread name (if available)
375 %(process)d Process ID (if available)
376 %(message)s The result of record.getMessage(), computed just as
377 the record is emitted
380 converter = time.localtime
382 def __init__(self, fmt=None, datefmt=None):
384 Initialize the formatter with specified format strings.
386 Initialize the formatter either with the specified format string, or a
387 default as described above. Allow for specialized date formatting with
388 the optional datefmt argument (if omitted, you get the ISO8601 format).
390 if fmt:
391 self._fmt = fmt
392 else:
393 self._fmt = "%(message)s"
394 self.datefmt = datefmt
396 def formatTime(self, record, datefmt=None):
398 Return the creation time of the specified LogRecord as formatted text.
400 This method should be called from format() by a formatter which
401 wants to make use of a formatted time. This method can be overridden
402 in formatters to provide for any specific requirement, but the
403 basic behaviour is as follows: if datefmt (a string) is specified,
404 it is used with time.strftime() to format the creation time of the
405 record. Otherwise, the ISO8601 format is used. The resulting
406 string is returned. This function uses a user-configurable function
407 to convert the creation time to a tuple. By default, time.localtime()
408 is used; to change this for a particular formatter instance, set the
409 'converter' attribute to a function with the same signature as
410 time.localtime() or time.gmtime(). To change it for all formatters,
411 for example if you want all logging times to be shown in GMT,
412 set the 'converter' attribute in the Formatter class.
414 ct = self.converter(record.created)
415 if datefmt:
416 s = time.strftime(datefmt, ct)
417 else:
418 t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
419 s = "%s,%03d" % (t, record.msecs)
420 return s
422 def formatException(self, ei):
424 Format and return the specified exception information as a string.
426 This default implementation just uses
427 traceback.print_exception()
429 sio = cStringIO.StringIO()
430 traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
431 s = sio.getvalue()
432 sio.close()
433 if s[-1:] == "\n":
434 s = s[:-1]
435 return s
437 def format(self, record):
439 Format the specified record as text.
441 The record's attribute dictionary is used as the operand to a
442 string formatting operation which yields the returned string.
443 Before formatting the dictionary, a couple of preparatory steps
444 are carried out. The message attribute of the record is computed
445 using LogRecord.getMessage(). If the formatting string contains
446 "%(asctime)", formatTime() is called to format the event time.
447 If there is exception information, it is formatted using
448 formatException() and appended to the message.
450 record.message = record.getMessage()
451 if self._fmt.find("%(asctime)") >= 0:
452 record.asctime = self.formatTime(record, self.datefmt)
453 s = self._fmt % record.__dict__
454 if record.exc_info:
455 # Cache the traceback text to avoid converting it multiple times
456 # (it's constant anyway)
457 if not record.exc_text:
458 record.exc_text = self.formatException(record.exc_info)
459 if record.exc_text:
460 if s[-1:] != "\n":
461 s = s + "\n"
462 s = s + record.exc_text
463 return s
466 # The default formatter to use when no other is specified
468 _defaultFormatter = Formatter()
470 class BufferingFormatter:
472 A formatter suitable for formatting a number of records.
474 def __init__(self, linefmt=None):
476 Optionally specify a formatter which will be used to format each
477 individual record.
479 if linefmt:
480 self.linefmt = linefmt
481 else:
482 self.linefmt = _defaultFormatter
484 def formatHeader(self, records):
486 Return the header string for the specified records.
488 return ""
490 def formatFooter(self, records):
492 Return the footer string for the specified records.
494 return ""
496 def format(self, records):
498 Format the specified records and return the result as a string.
500 rv = ""
501 if len(records) > 0:
502 rv = rv + self.formatHeader(records)
503 for record in records:
504 rv = rv + self.linefmt.format(record)
505 rv = rv + self.formatFooter(records)
506 return rv
508 #---------------------------------------------------------------------------
509 # Filter classes and functions
510 #---------------------------------------------------------------------------
512 class Filter:
514 Filter instances are used to perform arbitrary filtering of LogRecords.
516 Loggers and Handlers can optionally use Filter instances to filter
517 records as desired. The base filter class only allows events which are
518 below a certain point in the logger hierarchy. For example, a filter
519 initialized with "A.B" will allow events logged by loggers "A.B",
520 "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
521 initialized with the empty string, all events are passed.
523 def __init__(self, name=''):
525 Initialize a filter.
527 Initialize with the name of the logger which, together with its
528 children, will have its events allowed through the filter. If no
529 name is specified, allow every event.
531 self.name = name
532 self.nlen = len(name)
534 def filter(self, record):
536 Determine if the specified record is to be logged.
538 Is the specified record to be logged? Returns 0 for no, nonzero for
539 yes. If deemed appropriate, the record may be modified in-place.
541 if self.nlen == 0:
542 return 1
543 elif self.name == record.name:
544 return 1
545 elif record.name.find(self.name, 0, self.nlen) != 0:
546 return 0
547 return (record.name[self.nlen] == ".")
549 class Filterer:
551 A base class for loggers and handlers which allows them to share
552 common code.
554 def __init__(self):
556 Initialize the list of filters to be an empty list.
558 self.filters = []
560 def addFilter(self, filter):
562 Add the specified filter to this handler.
564 if not (filter in self.filters):
565 self.filters.append(filter)
567 def removeFilter(self, filter):
569 Remove the specified filter from this handler.
571 if filter in self.filters:
572 self.filters.remove(filter)
574 def filter(self, record):
576 Determine if a record is loggable by consulting all the filters.
578 The default is to allow the record to be logged; any filter can veto
579 this and the record is then dropped. Returns a zero value if a record
580 is to be dropped, else non-zero.
582 rv = 1
583 for f in self.filters:
584 if not f.filter(record):
585 rv = 0
586 break
587 return rv
589 #---------------------------------------------------------------------------
590 # Handler classes and functions
591 #---------------------------------------------------------------------------
593 _handlers = {} #repository of handlers (for flushing when shutdown called)
594 _handlerList = [] # added to allow handlers to be removed in reverse of order initialized
596 class Handler(Filterer):
598 Handler instances dispatch logging events to specific destinations.
600 The base handler class. Acts as a placeholder which defines the Handler
601 interface. Handlers can optionally use Formatter instances to format
602 records as desired. By default, no formatter is specified; in this case,
603 the 'raw' message as determined by record.message is logged.
605 def __init__(self, level=NOTSET):
607 Initializes the instance - basically setting the formatter to None
608 and the filter list to empty.
610 Filterer.__init__(self)
611 self.level = _checkLevel(level)
612 self.formatter = None
613 #get the module data lock, as we're updating a shared structure.
614 _acquireLock()
615 try: #unlikely to raise an exception, but you never know...
616 _handlers[self] = 1
617 _handlerList.insert(0, self)
618 finally:
619 _releaseLock()
620 self.createLock()
622 def createLock(self):
624 Acquire a thread lock for serializing access to the underlying I/O.
626 if thread:
627 self.lock = threading.RLock()
628 else:
629 self.lock = None
631 def acquire(self):
633 Acquire the I/O thread lock.
635 if self.lock:
636 self.lock.acquire()
638 def release(self):
640 Release the I/O thread lock.
642 if self.lock:
643 self.lock.release()
645 def setLevel(self, level):
647 Set the logging level of this handler.
649 self.level = _checkLevel(level)
651 def format(self, record):
653 Format the specified record.
655 If a formatter is set, use it. Otherwise, use the default formatter
656 for the module.
658 if self.formatter:
659 fmt = self.formatter
660 else:
661 fmt = _defaultFormatter
662 return fmt.format(record)
664 def emit(self, record):
666 Do whatever it takes to actually log the specified logging record.
668 This version is intended to be implemented by subclasses and so
669 raises a NotImplementedError.
671 raise NotImplementedError('emit must be implemented '
672 'by Handler subclasses')
674 def handle(self, record):
676 Conditionally emit the specified logging record.
678 Emission depends on filters which may have been added to the handler.
679 Wrap the actual emission of the record with acquisition/release of
680 the I/O thread lock. Returns whether the filter passed the record for
681 emission.
683 rv = self.filter(record)
684 if rv:
685 self.acquire()
686 try:
687 self.emit(record)
688 finally:
689 self.release()
690 return rv
692 def setFormatter(self, fmt):
694 Set the formatter for this handler.
696 self.formatter = fmt
698 def flush(self):
700 Ensure all logging output has been flushed.
702 This version does nothing and is intended to be implemented by
703 subclasses.
705 pass
707 def close(self):
709 Tidy up any resources used by the handler.
711 This version does removes the handler from an internal list
712 of handlers which is closed when shutdown() is called. Subclasses
713 should ensure that this gets called from overridden close()
714 methods.
716 #get the module data lock, as we're updating a shared structure.
717 _acquireLock()
718 try: #unlikely to raise an exception, but you never know...
719 del _handlers[self]
720 _handlerList.remove(self)
721 finally:
722 _releaseLock()
724 def handleError(self, record):
726 Handle errors which occur during an emit() call.
728 This method should be called from handlers when an exception is
729 encountered during an emit() call. If raiseExceptions is false,
730 exceptions get silently ignored. This is what is mostly wanted
731 for a logging system - most users will not care about errors in
732 the logging system, they are more interested in application errors.
733 You could, however, replace this with a custom handler if you wish.
734 The record which was being processed is passed in to this method.
736 if raiseExceptions:
737 ei = sys.exc_info()
738 try:
739 traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
740 except IOError:
741 pass # see issue 5971
742 finally:
743 del ei
745 class StreamHandler(Handler):
747 A handler class which writes logging records, appropriately formatted,
748 to a stream. Note that this class does not close the stream, as
749 sys.stdout or sys.stderr may be used.
752 def __init__(self, stream=None):
754 Initialize the handler.
756 If stream is not specified, sys.stderr is used.
758 Handler.__init__(self)
759 if stream is None:
760 stream = sys.stderr
761 self.stream = stream
763 def flush(self):
765 Flushes the stream.
767 if self.stream and hasattr(self.stream, "flush"):
768 self.stream.flush()
770 def emit(self, record):
772 Emit a record.
774 If a formatter is specified, it is used to format the record.
775 The record is then written to the stream with a trailing newline. If
776 exception information is present, it is formatted using
777 traceback.print_exception and appended to the stream. If the stream
778 has an 'encoding' attribute, it is used to determine how to do the
779 output to the stream.
781 try:
782 msg = self.format(record)
783 stream = self.stream
784 fs = "%s\n"
785 if not _unicode: #if no unicode support...
786 stream.write(fs % msg)
787 else:
788 try:
789 if (isinstance(msg, unicode) and
790 getattr(stream, 'encoding', None)):
791 fs = fs.decode(stream.encoding)
792 try:
793 stream.write(fs % msg)
794 except UnicodeEncodeError:
795 #Printing to terminals sometimes fails. For example,
796 #with an encoding of 'cp1251', the above write will
797 #work if written to a stream opened or wrapped by
798 #the codecs module, but fail when writing to a
799 #terminal even when the codepage is set to cp1251.
800 #An extra encoding step seems to be needed.
801 stream.write((fs % msg).encode(stream.encoding))
802 else:
803 stream.write(fs % msg)
804 except UnicodeError:
805 stream.write(fs % msg.encode("UTF-8"))
806 self.flush()
807 except (KeyboardInterrupt, SystemExit):
808 raise
809 except:
810 self.handleError(record)
812 class FileHandler(StreamHandler):
814 A handler class which writes formatted logging records to disk files.
816 def __init__(self, filename, mode='a', encoding=None, delay=0):
818 Open the specified file and use it as the stream for logging.
820 #keep the absolute path, otherwise derived classes which use this
821 #may come a cropper when the current directory changes
822 if codecs is None:
823 encoding = None
824 self.baseFilename = os.path.abspath(filename)
825 self.mode = mode
826 self.encoding = encoding
827 if delay:
828 #We don't open the stream, but we still need to call the
829 #Handler constructor to set level, formatter, lock etc.
830 Handler.__init__(self)
831 self.stream = None
832 else:
833 StreamHandler.__init__(self, self._open())
835 def close(self):
837 Closes the stream.
839 if self.stream:
840 self.flush()
841 if hasattr(self.stream, "close"):
842 self.stream.close()
843 StreamHandler.close(self)
844 self.stream = None
846 def _open(self):
848 Open the current base file with the (original) mode and encoding.
849 Return the resulting stream.
851 if self.encoding is None:
852 stream = open(self.baseFilename, self.mode)
853 else:
854 stream = codecs.open(self.baseFilename, self.mode, self.encoding)
855 return stream
857 def emit(self, record):
859 Emit a record.
861 If the stream was not opened because 'delay' was specified in the
862 constructor, open it before calling the superclass's emit.
864 if self.stream is None:
865 self.stream = self._open()
866 StreamHandler.emit(self, record)
868 #---------------------------------------------------------------------------
869 # Manager classes and functions
870 #---------------------------------------------------------------------------
872 class PlaceHolder:
874 PlaceHolder instances are used in the Manager logger hierarchy to take
875 the place of nodes for which no loggers have been defined. This class is
876 intended for internal use only and not as part of the public API.
878 def __init__(self, alogger):
880 Initialize with the specified logger being a child of this placeholder.
882 #self.loggers = [alogger]
883 self.loggerMap = { alogger : None }
885 def append(self, alogger):
887 Add the specified logger as a child of this placeholder.
889 #if alogger not in self.loggers:
890 if alogger not in self.loggerMap:
891 #self.loggers.append(alogger)
892 self.loggerMap[alogger] = None
895 # Determine which class to use when instantiating loggers.
897 _loggerClass = None
899 def setLoggerClass(klass):
901 Set the class to be used when instantiating a logger. The class should
902 define __init__() such that only a name argument is required, and the
903 __init__() should call Logger.__init__()
905 if klass != Logger:
906 if not issubclass(klass, Logger):
907 raise TypeError("logger not derived from logging.Logger: "
908 + klass.__name__)
909 global _loggerClass
910 _loggerClass = klass
912 def getLoggerClass():
914 Return the class to be used when instantiating a logger.
917 return _loggerClass
919 class Manager:
921 There is [under normal circumstances] just one Manager instance, which
922 holds the hierarchy of loggers.
924 def __init__(self, rootnode):
926 Initialize the manager with the root node of the logger hierarchy.
928 self.root = rootnode
929 self.disable = 0
930 self.emittedNoHandlerWarning = 0
931 self.loggerDict = {}
933 def getLogger(self, name):
935 Get a logger with the specified name (channel name), creating it
936 if it doesn't yet exist. This name is a dot-separated hierarchical
937 name, such as "a", "a.b", "a.b.c" or similar.
939 If a PlaceHolder existed for the specified name [i.e. the logger
940 didn't exist but a child of it did], replace it with the created
941 logger and fix up the parent/child references which pointed to the
942 placeholder to now point to the logger.
944 rv = None
945 _acquireLock()
946 try:
947 if name in self.loggerDict:
948 rv = self.loggerDict[name]
949 if isinstance(rv, PlaceHolder):
950 ph = rv
951 rv = _loggerClass(name)
952 rv.manager = self
953 self.loggerDict[name] = rv
954 self._fixupChildren(ph, rv)
955 self._fixupParents(rv)
956 else:
957 rv = _loggerClass(name)
958 rv.manager = self
959 self.loggerDict[name] = rv
960 self._fixupParents(rv)
961 finally:
962 _releaseLock()
963 return rv
965 def _fixupParents(self, alogger):
967 Ensure that there are either loggers or placeholders all the way
968 from the specified logger to the root of the logger hierarchy.
970 name = alogger.name
971 i = name.rfind(".")
972 rv = None
973 while (i > 0) and not rv:
974 substr = name[:i]
975 if substr not in self.loggerDict:
976 self.loggerDict[substr] = PlaceHolder(alogger)
977 else:
978 obj = self.loggerDict[substr]
979 if isinstance(obj, Logger):
980 rv = obj
981 else:
982 assert isinstance(obj, PlaceHolder)
983 obj.append(alogger)
984 i = name.rfind(".", 0, i - 1)
985 if not rv:
986 rv = self.root
987 alogger.parent = rv
989 def _fixupChildren(self, ph, alogger):
991 Ensure that children of the placeholder ph are connected to the
992 specified logger.
994 name = alogger.name
995 namelen = len(name)
996 for c in ph.loggerMap.keys():
997 #The if means ... if not c.parent.name.startswith(nm)
998 if c.parent.name[:namelen] != name:
999 alogger.parent = c.parent
1000 c.parent = alogger
1002 #---------------------------------------------------------------------------
1003 # Logger classes and functions
1004 #---------------------------------------------------------------------------
1006 class Logger(Filterer):
1008 Instances of the Logger class represent a single logging channel. A
1009 "logging channel" indicates an area of an application. Exactly how an
1010 "area" is defined is up to the application developer. Since an
1011 application can have any number of areas, logging channels are identified
1012 by a unique string. Application areas can be nested (e.g. an area
1013 of "input processing" might include sub-areas "read CSV files", "read
1014 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
1015 channel names are organized into a namespace hierarchy where levels are
1016 separated by periods, much like the Java or Python package namespace. So
1017 in the instance given above, channel names might be "input" for the upper
1018 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
1019 There is no arbitrary limit to the depth of nesting.
1021 def __init__(self, name, level=NOTSET):
1023 Initialize the logger with a name and an optional level.
1025 Filterer.__init__(self)
1026 self.name = name
1027 self.level = _checkLevel(level)
1028 self.parent = None
1029 self.propagate = 1
1030 self.handlers = []
1031 self.disabled = 0
1033 def setLevel(self, level):
1035 Set the logging level of this logger.
1037 self.level = _checkLevel(level)
1039 def debug(self, msg, *args, **kwargs):
1041 Log 'msg % args' with severity 'DEBUG'.
1043 To pass exception information, use the keyword argument exc_info with
1044 a true value, e.g.
1046 logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
1048 if self.isEnabledFor(DEBUG):
1049 self._log(DEBUG, msg, args, **kwargs)
1051 def info(self, msg, *args, **kwargs):
1053 Log 'msg % args' with severity 'INFO'.
1055 To pass exception information, use the keyword argument exc_info with
1056 a true value, e.g.
1058 logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
1060 if self.isEnabledFor(INFO):
1061 self._log(INFO, msg, args, **kwargs)
1063 def warning(self, msg, *args, **kwargs):
1065 Log 'msg % args' with severity 'WARNING'.
1067 To pass exception information, use the keyword argument exc_info with
1068 a true value, e.g.
1070 logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
1072 if self.isEnabledFor(WARNING):
1073 self._log(WARNING, msg, args, **kwargs)
1075 warn = warning
1077 def error(self, msg, *args, **kwargs):
1079 Log 'msg % args' with severity 'ERROR'.
1081 To pass exception information, use the keyword argument exc_info with
1082 a true value, e.g.
1084 logger.error("Houston, we have a %s", "major problem", exc_info=1)
1086 if self.isEnabledFor(ERROR):
1087 self._log(ERROR, msg, args, **kwargs)
1089 def exception(self, msg, *args):
1091 Convenience method for logging an ERROR with exception information.
1093 self.error(msg, exc_info=1, *args)
1095 def critical(self, msg, *args, **kwargs):
1097 Log 'msg % args' with severity 'CRITICAL'.
1099 To pass exception information, use the keyword argument exc_info with
1100 a true value, e.g.
1102 logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1104 if self.isEnabledFor(CRITICAL):
1105 self._log(CRITICAL, msg, args, **kwargs)
1107 fatal = critical
1109 def log(self, level, msg, *args, **kwargs):
1111 Log 'msg % args' with the integer severity 'level'.
1113 To pass exception information, use the keyword argument exc_info with
1114 a true value, e.g.
1116 logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1118 if not isinstance(level, int):
1119 if raiseExceptions:
1120 raise TypeError("level must be an integer")
1121 else:
1122 return
1123 if self.isEnabledFor(level):
1124 self._log(level, msg, args, **kwargs)
1126 def findCaller(self):
1128 Find the stack frame of the caller so that we can note the source
1129 file name, line number and function name.
1131 f = currentframe()
1132 #On some versions of IronPython, currentframe() returns None if
1133 #IronPython isn't run with -X:Frames.
1134 if f is not None:
1135 f = f.f_back
1136 rv = "(unknown file)", 0, "(unknown function)"
1137 while hasattr(f, "f_code"):
1138 co = f.f_code
1139 filename = os.path.normcase(co.co_filename)
1140 if filename == _srcfile:
1141 f = f.f_back
1142 continue
1143 rv = (filename, f.f_lineno, co.co_name)
1144 break
1145 return rv
1147 def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
1149 A factory method which can be overridden in subclasses to create
1150 specialized LogRecords.
1152 rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
1153 if extra is not None:
1154 for key in extra:
1155 if (key in ["message", "asctime"]) or (key in rv.__dict__):
1156 raise KeyError("Attempt to overwrite %r in LogRecord" % key)
1157 rv.__dict__[key] = extra[key]
1158 return rv
1160 def _log(self, level, msg, args, exc_info=None, extra=None):
1162 Low-level logging routine which creates a LogRecord and then calls
1163 all the handlers of this logger to handle the record.
1165 if _srcfile:
1166 #IronPython doesn't track Python frames, so findCaller throws an
1167 #exception on some versions of IronPython. We trap it here so that
1168 #IronPython can use logging.
1169 try:
1170 fn, lno, func = self.findCaller()
1171 except ValueError:
1172 fn, lno, func = "(unknown file)", 0, "(unknown function)"
1173 else:
1174 fn, lno, func = "(unknown file)", 0, "(unknown function)"
1175 if exc_info:
1176 if not isinstance(exc_info, tuple):
1177 exc_info = sys.exc_info()
1178 record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
1179 self.handle(record)
1181 def handle(self, record):
1183 Call the handlers for the specified record.
1185 This method is used for unpickled records received from a socket, as
1186 well as those created locally. Logger-level filtering is applied.
1188 if (not self.disabled) and self.filter(record):
1189 self.callHandlers(record)
1191 def addHandler(self, hdlr):
1193 Add the specified handler to this logger.
1195 if not (hdlr in self.handlers):
1196 self.handlers.append(hdlr)
1198 def removeHandler(self, hdlr):
1200 Remove the specified handler from this logger.
1202 if hdlr in self.handlers:
1203 #hdlr.close()
1204 hdlr.acquire()
1205 try:
1206 self.handlers.remove(hdlr)
1207 finally:
1208 hdlr.release()
1210 def callHandlers(self, record):
1212 Pass a record to all relevant handlers.
1214 Loop through all handlers for this logger and its parents in the
1215 logger hierarchy. If no handler was found, output a one-off error
1216 message to sys.stderr. Stop searching up the hierarchy whenever a
1217 logger with the "propagate" attribute set to zero is found - that
1218 will be the last logger whose handlers are called.
1220 c = self
1221 found = 0
1222 while c:
1223 for hdlr in c.handlers:
1224 found = found + 1
1225 if record.levelno >= hdlr.level:
1226 hdlr.handle(record)
1227 if not c.propagate:
1228 c = None #break out
1229 else:
1230 c = c.parent
1231 if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
1232 sys.stderr.write("No handlers could be found for logger"
1233 " \"%s\"\n" % self.name)
1234 self.manager.emittedNoHandlerWarning = 1
1236 def getEffectiveLevel(self):
1238 Get the effective level for this logger.
1240 Loop through this logger and its parents in the logger hierarchy,
1241 looking for a non-zero logging level. Return the first one found.
1243 logger = self
1244 while logger:
1245 if logger.level:
1246 return logger.level
1247 logger = logger.parent
1248 return NOTSET
1250 def isEnabledFor(self, level):
1252 Is this logger enabled for level 'level'?
1254 if self.manager.disable >= level:
1255 return 0
1256 return level >= self.getEffectiveLevel()
1258 class RootLogger(Logger):
1260 A root logger is not that different to any other logger, except that
1261 it must have a logging level and there is only one instance of it in
1262 the hierarchy.
1264 def __init__(self, level):
1266 Initialize the logger with the name "root".
1268 Logger.__init__(self, "root", level)
1270 _loggerClass = Logger
1272 class LoggerAdapter:
1274 An adapter for loggers which makes it easier to specify contextual
1275 information in logging output.
1278 def __init__(self, logger, extra):
1280 Initialize the adapter with a logger and a dict-like object which
1281 provides contextual information. This constructor signature allows
1282 easy stacking of LoggerAdapters, if so desired.
1284 You can effectively pass keyword arguments as shown in the
1285 following example:
1287 adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
1289 self.logger = logger
1290 self.extra = extra
1292 def process(self, msg, kwargs):
1294 Process the logging message and keyword arguments passed in to
1295 a logging call to insert contextual information. You can either
1296 manipulate the message itself, the keyword args or both. Return
1297 the message and kwargs modified (or not) to suit your needs.
1299 Normally, you'll only need to override this one method in a
1300 LoggerAdapter subclass for your specific needs.
1302 kwargs["extra"] = self.extra
1303 return msg, kwargs
1305 def debug(self, msg, *args, **kwargs):
1307 Delegate a debug call to the underlying logger, after adding
1308 contextual information from this adapter instance.
1310 msg, kwargs = self.process(msg, kwargs)
1311 self.logger.debug(msg, *args, **kwargs)
1313 def info(self, msg, *args, **kwargs):
1315 Delegate an info call to the underlying logger, after adding
1316 contextual information from this adapter instance.
1318 msg, kwargs = self.process(msg, kwargs)
1319 self.logger.info(msg, *args, **kwargs)
1321 def warning(self, msg, *args, **kwargs):
1323 Delegate a warning call to the underlying logger, after adding
1324 contextual information from this adapter instance.
1326 msg, kwargs = self.process(msg, kwargs)
1327 self.logger.warning(msg, *args, **kwargs)
1329 def error(self, msg, *args, **kwargs):
1331 Delegate an error call to the underlying logger, after adding
1332 contextual information from this adapter instance.
1334 msg, kwargs = self.process(msg, kwargs)
1335 self.logger.error(msg, *args, **kwargs)
1337 def exception(self, msg, *args, **kwargs):
1339 Delegate an exception call to the underlying logger, after adding
1340 contextual information from this adapter instance.
1342 msg, kwargs = self.process(msg, kwargs)
1343 kwargs["exc_info"] = 1
1344 self.logger.error(msg, *args, **kwargs)
1346 def critical(self, msg, *args, **kwargs):
1348 Delegate a critical call to the underlying logger, after adding
1349 contextual information from this adapter instance.
1351 msg, kwargs = self.process(msg, kwargs)
1352 self.logger.critical(msg, *args, **kwargs)
1354 def log(self, level, msg, *args, **kwargs):
1356 Delegate a log call to the underlying logger, after adding
1357 contextual information from this adapter instance.
1359 msg, kwargs = self.process(msg, kwargs)
1360 self.logger.log(level, msg, *args, **kwargs)
1362 root = RootLogger(WARNING)
1363 Logger.root = root
1364 Logger.manager = Manager(Logger.root)
1366 #---------------------------------------------------------------------------
1367 # Configuration classes and functions
1368 #---------------------------------------------------------------------------
1370 BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
1372 def basicConfig(**kwargs):
1374 Do basic configuration for the logging system.
1376 This function does nothing if the root logger already has handlers
1377 configured. It is a convenience method intended for use by simple scripts
1378 to do one-shot configuration of the logging package.
1380 The default behaviour is to create a StreamHandler which writes to
1381 sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1382 add the handler to the root logger.
1384 A number of optional keyword arguments may be specified, which can alter
1385 the default behaviour.
1387 filename Specifies that a FileHandler be created, using the specified
1388 filename, rather than a StreamHandler.
1389 filemode Specifies the mode to open the file, if filename is specified
1390 (if filemode is unspecified, it defaults to 'a').
1391 format Use the specified format string for the handler.
1392 datefmt Use the specified date/time format.
1393 level Set the root logger level to the specified level.
1394 stream Use the specified stream to initialize the StreamHandler. Note
1395 that this argument is incompatible with 'filename' - if both
1396 are present, 'stream' is ignored.
1398 Note that you could specify a stream created using open(filename, mode)
1399 rather than passing the filename and mode in. However, it should be
1400 remembered that StreamHandler does not close its stream (since it may be
1401 using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1402 when the handler is closed.
1404 if len(root.handlers) == 0:
1405 filename = kwargs.get("filename")
1406 if filename:
1407 mode = kwargs.get("filemode", 'a')
1408 hdlr = FileHandler(filename, mode)
1409 else:
1410 stream = kwargs.get("stream")
1411 hdlr = StreamHandler(stream)
1412 fs = kwargs.get("format", BASIC_FORMAT)
1413 dfs = kwargs.get("datefmt", None)
1414 fmt = Formatter(fs, dfs)
1415 hdlr.setFormatter(fmt)
1416 root.addHandler(hdlr)
1417 level = kwargs.get("level")
1418 if level is not None:
1419 root.setLevel(level)
1421 #---------------------------------------------------------------------------
1422 # Utility functions at module level.
1423 # Basically delegate everything to the root logger.
1424 #---------------------------------------------------------------------------
1426 def getLogger(name=None):
1428 Return a logger with the specified name, creating it if necessary.
1430 If no name is specified, return the root logger.
1432 if name:
1433 return Logger.manager.getLogger(name)
1434 else:
1435 return root
1437 #def getRootLogger():
1438 # """
1439 # Return the root logger.
1441 # Note that getLogger('') now does the same thing, so this function is
1442 # deprecated and may disappear in the future.
1443 # """
1444 # return root
1446 def critical(msg, *args, **kwargs):
1448 Log a message with severity 'CRITICAL' on the root logger.
1450 if len(root.handlers) == 0:
1451 basicConfig()
1452 root.critical(msg, *args, **kwargs)
1454 fatal = critical
1456 def error(msg, *args, **kwargs):
1458 Log a message with severity 'ERROR' on the root logger.
1460 if len(root.handlers) == 0:
1461 basicConfig()
1462 root.error(msg, *args, **kwargs)
1464 def exception(msg, *args):
1466 Log a message with severity 'ERROR' on the root logger,
1467 with exception information.
1469 error(msg, exc_info=1, *args)
1471 def warning(msg, *args, **kwargs):
1473 Log a message with severity 'WARNING' on the root logger.
1475 if len(root.handlers) == 0:
1476 basicConfig()
1477 root.warning(msg, *args, **kwargs)
1479 warn = warning
1481 def info(msg, *args, **kwargs):
1483 Log a message with severity 'INFO' on the root logger.
1485 if len(root.handlers) == 0:
1486 basicConfig()
1487 root.info(msg, *args, **kwargs)
1489 def debug(msg, *args, **kwargs):
1491 Log a message with severity 'DEBUG' on the root logger.
1493 if len(root.handlers) == 0:
1494 basicConfig()
1495 root.debug(msg, *args, **kwargs)
1497 def log(level, msg, *args, **kwargs):
1499 Log 'msg % args' with the integer severity 'level' on the root logger.
1501 if len(root.handlers) == 0:
1502 basicConfig()
1503 root.log(level, msg, *args, **kwargs)
1505 def disable(level):
1507 Disable all logging calls less severe than 'level'.
1509 root.manager.disable = level
1511 def shutdown(handlerList=_handlerList):
1513 Perform any cleanup actions in the logging system (e.g. flushing
1514 buffers).
1516 Should be called at application exit.
1518 for h in handlerList[:]:
1519 #errors might occur, for example, if files are locked
1520 #we just ignore them if raiseExceptions is not set
1521 try:
1522 h.flush()
1523 h.close()
1524 except:
1525 if raiseExceptions:
1526 raise
1527 #else, swallow
1529 #Let's try and shutdown automatically on application exit...
1530 try:
1531 import atexit
1532 atexit.register(shutdown)
1533 except ImportError: # for Python versions < 2.0
1534 def exithook(status, old_exit=sys.exit):
1535 try:
1536 shutdown()
1537 finally:
1538 old_exit(status)
1540 sys.exit = exithook
1542 # Null handler
1544 class NullHandler(Handler):
1546 This handler does nothing. It's intended to be used to avoid the
1547 "No handlers could be found for logger XXX" one-off warning. This is
1548 important for library code, which may contain code to log events. If a user
1549 of the library does not configure logging, the one-off warning might be
1550 produced; to avoid this, the library developer simply needs to instantiate
1551 a NullHandler and add it to the top-level logger of the library module or
1552 package.
1554 def emit(self, record):
1555 pass
1557 # Warnings integration
1559 _warnings_showwarning = None
1561 def _showwarning(message, category, filename, lineno, file=None, line=None):
1563 Implementation of showwarnings which redirects to logging, which will first
1564 check to see if the file parameter is None. If a file is specified, it will
1565 delegate to the original warnings implementation of showwarning. Otherwise,
1566 it will call warnings.formatwarning and will log the resulting string to a
1567 warnings logger named "py.warnings" with level logging.WARNING.
1569 if file is not None:
1570 if _warnings_showwarning is not None:
1571 _warnings_showwarning(message, category, filename, lineno, file, line)
1572 else:
1573 s = warnings.formatwarning(message, category, filename, lineno, line)
1574 logger = getLogger("py.warnings")
1575 if not logger.handlers:
1576 logger.addHandler(NullHandler())
1577 logger.warning("%s", s)
1579 def captureWarnings(capture):
1581 If capture is true, redirect all warnings to the logging package.
1582 If capture is False, ensure that warnings are not redirected to logging
1583 but to their original destinations.
1585 global _warnings_showwarning
1586 if capture:
1587 if _warnings_showwarning is None:
1588 _warnings_showwarning = warnings.showwarning
1589 warnings.showwarning = _showwarning
1590 else:
1591 if _warnings_showwarning is not None:
1592 warnings.showwarning = _warnings_showwarning
1593 _warnings_showwarning = None