Tidied up name of parameter in StreamHandler
[python.git] / Lib / logging / __init__.py
blob9c72542c2b162bc3438ef829fef9194759632211
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 __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
27 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO',
28 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler',
29 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig',
30 'captureWarnings', 'critical', 'debug', 'disable', 'error',
31 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass',
32 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning']
34 import sys, os, types, time, string, cStringIO, traceback, warnings
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.8"
50 __date__ = "27 April 2009"
52 #---------------------------------------------------------------------------
53 # Miscellaneous module data
54 #---------------------------------------------------------------------------
57 # _srcfile is used when walking the stack to check when we've got the first
58 # caller stack frame.
60 if hasattr(sys, 'frozen'): #support for py2exe
61 _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
62 elif string.lower(__file__[-4:]) in ['.pyc', '.pyo']:
63 _srcfile = __file__[:-4] + '.py'
64 else:
65 _srcfile = __file__
66 _srcfile = os.path.normcase(_srcfile)
68 # next bit filched from 1.5.2's inspect.py
69 def currentframe():
70 """Return the frame object for the caller's stack frame."""
71 try:
72 raise Exception
73 except:
74 return sys.exc_traceback.tb_frame.f_back
76 if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
77 # done filching
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
87 #_startTime is used as the base when calculating the relative time of events
89 _startTime = time.time()
92 #raiseExceptions is used to see if exceptions during handling should be
93 #propagated
95 raiseExceptions = 1
98 # If you don't want threading information in the log, set this to zero
100 logThreads = 1
103 # If you don't want multiprocessing information in the log, set this to zero
105 logMultiprocessing = 1
108 # If you don't want process information in the log, set this to zero
110 logProcesses = 1
112 #---------------------------------------------------------------------------
113 # Level related stuff
114 #---------------------------------------------------------------------------
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.
123 CRITICAL = 50
124 FATAL = CRITICAL
125 ERROR = 40
126 WARNING = 30
127 WARN = WARNING
128 INFO = 20
129 DEBUG = 10
130 NOTSET = 0
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,
148 def getLevelName(level):
150 Return the textual representation of logging level 'level'.
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.
157 If a numeric value corresponding to one of the defined levels is passed
158 in, the corresponding string representation is returned.
160 Otherwise, the string "Level %s" % level is returned.
162 return _levelNames.get(level, ("Level %s" % level))
164 def addLevelName(level, levelName):
166 Associate 'levelName' with 'level'.
168 This is used when converting levels to text during message formatting.
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()
177 def _checkLevel(level):
178 if isinstance(level, int):
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
188 #---------------------------------------------------------------------------
189 # Thread-related stuff
190 #---------------------------------------------------------------------------
193 #_lock is used to serialize access to shared data structures in this module.
194 #This needs to be an RLock because fileConfig() creates Handlers and so
195 #might arbitrary user threads. Since Handler.__init__() updates the shared
196 #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.
200 _lock = None
202 def _acquireLock():
204 Acquire the module-level lock for serializing access to shared data.
206 This should be released with _releaseLock().
208 global _lock
209 if (not _lock) and thread:
210 _lock = threading.RLock()
211 if _lock:
212 _lock.acquire()
214 def _releaseLock():
216 Release the module-level lock acquired by calling _acquireLock().
218 if _lock:
219 _lock.release()
221 #---------------------------------------------------------------------------
222 # The logging record
223 #---------------------------------------------------------------------------
225 class LogRecord:
227 A LogRecord instance represents an event being logged.
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.
237 def __init__(self, name, level, pathname, lineno,
238 msg, args, exc_info, func=None):
240 Initialize a logging record with interesting information.
242 ct = time.time()
243 self.name = name
244 self.msg = msg
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 if args and len(args) == 1 and (
259 type(args[0]) == types.DictType
260 ) and args[0]:
261 args = args[0]
262 self.args = args
263 self.levelname = getLevelName(level)
264 self.levelno = level
265 self.pathname = pathname
266 try:
267 self.filename = os.path.basename(pathname)
268 self.module = os.path.splitext(self.filename)[0]
269 except (TypeError, ValueError, AttributeError):
270 self.filename = pathname
271 self.module = "Unknown module"
272 self.exc_info = exc_info
273 self.exc_text = None # used to cache the traceback text
274 self.lineno = lineno
275 self.funcName = func
276 self.created = ct
277 self.msecs = (ct - long(ct)) * 1000
278 self.relativeCreated = (self.created - _startTime) * 1000
279 if logThreads and thread:
280 self.thread = thread.get_ident()
281 self.threadName = threading.current_thread().name
282 else:
283 self.thread = None
284 self.threadName = None
285 if logMultiprocessing:
286 from multiprocessing import current_process
287 self.processName = current_process().name
288 else:
289 self.processName = None
290 if logProcesses and hasattr(os, 'getpid'):
291 self.process = os.getpid()
292 else:
293 self.process = None
295 def __str__(self):
296 return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
297 self.pathname, self.lineno, self.msg)
299 def getMessage(self):
301 Return the message for this LogRecord.
303 Return the message for this LogRecord after merging any user-supplied
304 arguments with the message.
306 if not hasattr(types, "UnicodeType"): #if no unicode support...
307 msg = str(self.msg)
308 else:
309 msg = self.msg
310 if type(msg) not in (types.UnicodeType, types.StringType):
311 try:
312 msg = str(self.msg)
313 except UnicodeError:
314 msg = self.msg #Defer encoding till later
315 if self.args:
316 msg = msg % self.args
317 return msg
319 def makeLogRecord(dict):
321 Make a LogRecord whose attributes are defined by the specified dictionary,
322 This function is useful for converting a logging event received over
323 a socket connection (which is sent as a dictionary) into a LogRecord
324 instance.
326 rv = LogRecord(None, None, "", 0, "", (), None, None)
327 rv.__dict__.update(dict)
328 return rv
330 #---------------------------------------------------------------------------
331 # Formatter classes and functions
332 #---------------------------------------------------------------------------
334 class Formatter:
336 Formatter instances are used to convert a LogRecord to text.
338 Formatters need to know how a LogRecord is constructed. They are
339 responsible for converting a LogRecord to (usually) a string which can
340 be interpreted by either a human or an external system. The base Formatter
341 allows a formatting string to be specified. If none is supplied, the
342 default value of "%s(message)\\n" is used.
344 The Formatter can be initialized with a format string which makes use of
345 knowledge of the LogRecord attributes - e.g. the default value mentioned
346 above makes use of the fact that the user's message and arguments are pre-
347 formatted into a LogRecord's message attribute. Currently, the useful
348 attributes in a LogRecord are described by:
350 %(name)s Name of the logger (logging channel)
351 %(levelno)s Numeric logging level for the message (DEBUG, INFO,
352 WARNING, ERROR, CRITICAL)
353 %(levelname)s Text logging level for the message ("DEBUG", "INFO",
354 "WARNING", "ERROR", "CRITICAL")
355 %(pathname)s Full pathname of the source file where the logging
356 call was issued (if available)
357 %(filename)s Filename portion of pathname
358 %(module)s Module (name portion of filename)
359 %(lineno)d Source line number where the logging call was issued
360 (if available)
361 %(funcName)s Function name
362 %(created)f Time when the LogRecord was created (time.time()
363 return value)
364 %(asctime)s Textual time when the LogRecord was created
365 %(msecs)d Millisecond portion of the creation time
366 %(relativeCreated)d Time in milliseconds when the LogRecord was created,
367 relative to the time the logging module was loaded
368 (typically at application startup time)
369 %(thread)d Thread ID (if available)
370 %(threadName)s Thread name (if available)
371 %(process)d Process ID (if available)
372 %(message)s The result of record.getMessage(), computed just as
373 the record is emitted
376 converter = time.localtime
378 def __init__(self, fmt=None, datefmt=None):
380 Initialize the formatter with specified format strings.
382 Initialize the formatter either with the specified format string, or a
383 default as described above. Allow for specialized date formatting with
384 the optional datefmt argument (if omitted, you get the ISO8601 format).
386 if fmt:
387 self._fmt = fmt
388 else:
389 self._fmt = "%(message)s"
390 self.datefmt = datefmt
392 def formatTime(self, record, datefmt=None):
394 Return the creation time of the specified LogRecord as formatted text.
396 This method should be called from format() by a formatter which
397 wants to make use of a formatted time. This method can be overridden
398 in formatters to provide for any specific requirement, but the
399 basic behaviour is as follows: if datefmt (a string) is specified,
400 it is used with time.strftime() to format the creation time of the
401 record. Otherwise, the ISO8601 format is used. The resulting
402 string is returned. This function uses a user-configurable function
403 to convert the creation time to a tuple. By default, time.localtime()
404 is used; to change this for a particular formatter instance, set the
405 'converter' attribute to a function with the same signature as
406 time.localtime() or time.gmtime(). To change it for all formatters,
407 for example if you want all logging times to be shown in GMT,
408 set the 'converter' attribute in the Formatter class.
410 ct = self.converter(record.created)
411 if datefmt:
412 s = time.strftime(datefmt, ct)
413 else:
414 t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
415 s = "%s,%03d" % (t, record.msecs)
416 return s
418 def formatException(self, ei):
420 Format and return the specified exception information as a string.
422 This default implementation just uses
423 traceback.print_exception()
425 sio = cStringIO.StringIO()
426 traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
427 s = sio.getvalue()
428 sio.close()
429 if s[-1:] == "\n":
430 s = s[:-1]
431 return s
433 def format(self, record):
435 Format the specified record as text.
437 The record's attribute dictionary is used as the operand to a
438 string formatting operation which yields the returned string.
439 Before formatting the dictionary, a couple of preparatory steps
440 are carried out. The message attribute of the record is computed
441 using LogRecord.getMessage(). If the formatting string contains
442 "%(asctime)", formatTime() is called to format the event time.
443 If there is exception information, it is formatted using
444 formatException() and appended to the message.
446 record.message = record.getMessage()
447 if string.find(self._fmt,"%(asctime)") >= 0:
448 record.asctime = self.formatTime(record, self.datefmt)
449 s = self._fmt % record.__dict__
450 if record.exc_info:
451 # Cache the traceback text to avoid converting it multiple times
452 # (it's constant anyway)
453 if not record.exc_text:
454 record.exc_text = self.formatException(record.exc_info)
455 if record.exc_text:
456 if s[-1:] != "\n":
457 s = s + "\n"
458 s = s + record.exc_text
459 return s
462 # The default formatter to use when no other is specified
464 _defaultFormatter = Formatter()
466 class BufferingFormatter:
468 A formatter suitable for formatting a number of records.
470 def __init__(self, linefmt=None):
472 Optionally specify a formatter which will be used to format each
473 individual record.
475 if linefmt:
476 self.linefmt = linefmt
477 else:
478 self.linefmt = _defaultFormatter
480 def formatHeader(self, records):
482 Return the header string for the specified records.
484 return ""
486 def formatFooter(self, records):
488 Return the footer string for the specified records.
490 return ""
492 def format(self, records):
494 Format the specified records and return the result as a string.
496 rv = ""
497 if len(records) > 0:
498 rv = rv + self.formatHeader(records)
499 for record in records:
500 rv = rv + self.linefmt.format(record)
501 rv = rv + self.formatFooter(records)
502 return rv
504 #---------------------------------------------------------------------------
505 # Filter classes and functions
506 #---------------------------------------------------------------------------
508 class Filter:
510 Filter instances are used to perform arbitrary filtering of LogRecords.
512 Loggers and Handlers can optionally use Filter instances to filter
513 records as desired. The base filter class only allows events which are
514 below a certain point in the logger hierarchy. For example, a filter
515 initialized with "A.B" will allow events logged by loggers "A.B",
516 "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
517 initialized with the empty string, all events are passed.
519 def __init__(self, name=''):
521 Initialize a filter.
523 Initialize with the name of the logger which, together with its
524 children, will have its events allowed through the filter. If no
525 name is specified, allow every event.
527 self.name = name
528 self.nlen = len(name)
530 def filter(self, record):
532 Determine if the specified record is to be logged.
534 Is the specified record to be logged? Returns 0 for no, nonzero for
535 yes. If deemed appropriate, the record may be modified in-place.
537 if self.nlen == 0:
538 return 1
539 elif self.name == record.name:
540 return 1
541 elif string.find(record.name, self.name, 0, self.nlen) != 0:
542 return 0
543 return (record.name[self.nlen] == ".")
545 class Filterer:
547 A base class for loggers and handlers which allows them to share
548 common code.
550 def __init__(self):
552 Initialize the list of filters to be an empty list.
554 self.filters = []
556 def addFilter(self, filter):
558 Add the specified filter to this handler.
560 if not (filter in self.filters):
561 self.filters.append(filter)
563 def removeFilter(self, filter):
565 Remove the specified filter from this handler.
567 if filter in self.filters:
568 self.filters.remove(filter)
570 def filter(self, record):
572 Determine if a record is loggable by consulting all the filters.
574 The default is to allow the record to be logged; any filter can veto
575 this and the record is then dropped. Returns a zero value if a record
576 is to be dropped, else non-zero.
578 rv = 1
579 for f in self.filters:
580 if not f.filter(record):
581 rv = 0
582 break
583 return rv
585 #---------------------------------------------------------------------------
586 # Handler classes and functions
587 #---------------------------------------------------------------------------
589 _handlers = {} #repository of handlers (for flushing when shutdown called)
590 _handlerList = [] # added to allow handlers to be removed in reverse of order initialized
592 class Handler(Filterer):
594 Handler instances dispatch logging events to specific destinations.
596 The base handler class. Acts as a placeholder which defines the Handler
597 interface. Handlers can optionally use Formatter instances to format
598 records as desired. By default, no formatter is specified; in this case,
599 the 'raw' message as determined by record.message is logged.
601 def __init__(self, level=NOTSET):
603 Initializes the instance - basically setting the formatter to None
604 and the filter list to empty.
606 Filterer.__init__(self)
607 self.level = _checkLevel(level)
608 self.formatter = None
609 #get the module data lock, as we're updating a shared structure.
610 _acquireLock()
611 try: #unlikely to raise an exception, but you never know...
612 _handlers[self] = 1
613 _handlerList.insert(0, self)
614 finally:
615 _releaseLock()
616 self.createLock()
618 def createLock(self):
620 Acquire a thread lock for serializing access to the underlying I/O.
622 if thread:
623 self.lock = threading.RLock()
624 else:
625 self.lock = None
627 def acquire(self):
629 Acquire the I/O thread lock.
631 if self.lock:
632 self.lock.acquire()
634 def release(self):
636 Release the I/O thread lock.
638 if self.lock:
639 self.lock.release()
641 def setLevel(self, level):
643 Set the logging level of this handler.
645 self.level = _checkLevel(level)
647 def format(self, record):
649 Format the specified record.
651 If a formatter is set, use it. Otherwise, use the default formatter
652 for the module.
654 if self.formatter:
655 fmt = self.formatter
656 else:
657 fmt = _defaultFormatter
658 return fmt.format(record)
660 def emit(self, record):
662 Do whatever it takes to actually log the specified logging record.
664 This version is intended to be implemented by subclasses and so
665 raises a NotImplementedError.
667 raise NotImplementedError, 'emit must be implemented '\
668 'by Handler subclasses'
670 def handle(self, record):
672 Conditionally emit the specified logging record.
674 Emission depends on filters which may have been added to the handler.
675 Wrap the actual emission of the record with acquisition/release of
676 the I/O thread lock. Returns whether the filter passed the record for
677 emission.
679 rv = self.filter(record)
680 if rv:
681 self.acquire()
682 try:
683 self.emit(record)
684 finally:
685 self.release()
686 return rv
688 def setFormatter(self, fmt):
690 Set the formatter for this handler.
692 self.formatter = fmt
694 def flush(self):
696 Ensure all logging output has been flushed.
698 This version does nothing and is intended to be implemented by
699 subclasses.
701 pass
703 def close(self):
705 Tidy up any resources used by the handler.
707 This version does removes the handler from an internal list
708 of handlers which is closed when shutdown() is called. Subclasses
709 should ensure that this gets called from overridden close()
710 methods.
712 #get the module data lock, as we're updating a shared structure.
713 _acquireLock()
714 try: #unlikely to raise an exception, but you never know...
715 del _handlers[self]
716 _handlerList.remove(self)
717 finally:
718 _releaseLock()
720 def handleError(self, record):
722 Handle errors which occur during an emit() call.
724 This method should be called from handlers when an exception is
725 encountered during an emit() call. If raiseExceptions is false,
726 exceptions get silently ignored. This is what is mostly wanted
727 for a logging system - most users will not care about errors in
728 the logging system, they are more interested in application errors.
729 You could, however, replace this with a custom handler if you wish.
730 The record which was being processed is passed in to this method.
732 if raiseExceptions:
733 ei = sys.exc_info()
734 try:
735 traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
736 except IOError:
737 pass # see issue 5971
738 finally:
739 del ei
741 class StreamHandler(Handler):
743 A handler class which writes logging records, appropriately formatted,
744 to a stream. Note that this class does not close the stream, as
745 sys.stdout or sys.stderr may be used.
748 def __init__(self, stream=None):
750 Initialize the handler.
752 If stream is not specified, sys.stderr is used.
754 Handler.__init__(self)
755 if stream is None:
756 stream = sys.stderr
757 self.stream = stream
759 def flush(self):
761 Flushes the stream.
763 if self.stream and hasattr(self.stream, "flush"):
764 self.stream.flush()
766 def emit(self, record):
768 Emit a record.
770 If a formatter is specified, it is used to format the record.
771 The record is then written to the stream with a trailing newline. If
772 exception information is present, it is formatted using
773 traceback.print_exception and appended to the stream. If the stream
774 has an 'encoding' attribute, it is used to determine how to do the
775 output to the stream.
777 try:
778 msg = self.format(record)
779 stream = self.stream
780 fs = "%s\n"
781 if not hasattr(types, "UnicodeType"): #if no unicode support...
782 stream.write(fs % msg)
783 else:
784 try:
785 if (isinstance(msg, unicode) and
786 getattr(stream, 'encoding', None)):
787 fs = fs.decode(stream.encoding)
788 try:
789 stream.write(fs % msg)
790 except UnicodeEncodeError:
791 #Printing to terminals sometimes fails. For example,
792 #with an encoding of 'cp1251', the above write will
793 #work if written to a stream opened or wrapped by
794 #the codecs module, but fail when writing to a
795 #terminal even when the codepage is set to cp1251.
796 #An extra encoding step seems to be needed.
797 stream.write((fs % msg).encode(stream.encoding))
798 else:
799 stream.write(fs % msg)
800 except UnicodeError:
801 stream.write(fs % msg.encode("UTF-8"))
802 self.flush()
803 except (KeyboardInterrupt, SystemExit):
804 raise
805 except:
806 self.handleError(record)
808 class FileHandler(StreamHandler):
810 A handler class which writes formatted logging records to disk files.
812 def __init__(self, filename, mode='a', encoding=None, delay=0):
814 Open the specified file and use it as the stream for logging.
816 #keep the absolute path, otherwise derived classes which use this
817 #may come a cropper when the current directory changes
818 if codecs is None:
819 encoding = None
820 self.baseFilename = os.path.abspath(filename)
821 self.mode = mode
822 self.encoding = encoding
823 if delay:
824 #We don't open the stream, but we still need to call the
825 #Handler constructor to set level, formatter, lock etc.
826 Handler.__init__(self)
827 self.stream = None
828 else:
829 StreamHandler.__init__(self, self._open())
831 def close(self):
833 Closes the stream.
835 if self.stream:
836 self.flush()
837 if hasattr(self.stream, "close"):
838 self.stream.close()
839 StreamHandler.close(self)
840 self.stream = None
842 def _open(self):
844 Open the current base file with the (original) mode and encoding.
845 Return the resulting stream.
847 if self.encoding is None:
848 stream = open(self.baseFilename, self.mode)
849 else:
850 stream = codecs.open(self.baseFilename, self.mode, self.encoding)
851 return stream
853 def emit(self, record):
855 Emit a record.
857 If the stream was not opened because 'delay' was specified in the
858 constructor, open it before calling the superclass's emit.
860 if self.stream is None:
861 self.stream = self._open()
862 StreamHandler.emit(self, record)
864 #---------------------------------------------------------------------------
865 # Manager classes and functions
866 #---------------------------------------------------------------------------
868 class PlaceHolder:
870 PlaceHolder instances are used in the Manager logger hierarchy to take
871 the place of nodes for which no loggers have been defined. This class is
872 intended for internal use only and not as part of the public API.
874 def __init__(self, alogger):
876 Initialize with the specified logger being a child of this placeholder.
878 #self.loggers = [alogger]
879 self.loggerMap = { alogger : None }
881 def append(self, alogger):
883 Add the specified logger as a child of this placeholder.
885 #if alogger not in self.loggers:
886 if alogger not in self.loggerMap:
887 #self.loggers.append(alogger)
888 self.loggerMap[alogger] = None
891 # Determine which class to use when instantiating loggers.
893 _loggerClass = None
895 def setLoggerClass(klass):
897 Set the class to be used when instantiating a logger. The class should
898 define __init__() such that only a name argument is required, and the
899 __init__() should call Logger.__init__()
901 if klass != Logger:
902 if not issubclass(klass, Logger):
903 raise TypeError, "logger not derived from logging.Logger: " + \
904 klass.__name__
905 global _loggerClass
906 _loggerClass = klass
908 def getLoggerClass():
910 Return the class to be used when instantiating a logger.
913 return _loggerClass
915 class Manager:
917 There is [under normal circumstances] just one Manager instance, which
918 holds the hierarchy of loggers.
920 def __init__(self, rootnode):
922 Initialize the manager with the root node of the logger hierarchy.
924 self.root = rootnode
925 self.disable = 0
926 self.emittedNoHandlerWarning = 0
927 self.loggerDict = {}
929 def getLogger(self, name):
931 Get a logger with the specified name (channel name), creating it
932 if it doesn't yet exist. This name is a dot-separated hierarchical
933 name, such as "a", "a.b", "a.b.c" or similar.
935 If a PlaceHolder existed for the specified name [i.e. the logger
936 didn't exist but a child of it did], replace it with the created
937 logger and fix up the parent/child references which pointed to the
938 placeholder to now point to the logger.
940 rv = None
941 _acquireLock()
942 try:
943 if name in self.loggerDict:
944 rv = self.loggerDict[name]
945 if isinstance(rv, PlaceHolder):
946 ph = rv
947 rv = _loggerClass(name)
948 rv.manager = self
949 self.loggerDict[name] = rv
950 self._fixupChildren(ph, rv)
951 self._fixupParents(rv)
952 else:
953 rv = _loggerClass(name)
954 rv.manager = self
955 self.loggerDict[name] = rv
956 self._fixupParents(rv)
957 finally:
958 _releaseLock()
959 return rv
961 def _fixupParents(self, alogger):
963 Ensure that there are either loggers or placeholders all the way
964 from the specified logger to the root of the logger hierarchy.
966 name = alogger.name
967 i = string.rfind(name, ".")
968 rv = None
969 while (i > 0) and not rv:
970 substr = name[:i]
971 if substr not in self.loggerDict:
972 self.loggerDict[substr] = PlaceHolder(alogger)
973 else:
974 obj = self.loggerDict[substr]
975 if isinstance(obj, Logger):
976 rv = obj
977 else:
978 assert isinstance(obj, PlaceHolder)
979 obj.append(alogger)
980 i = string.rfind(name, ".", 0, i - 1)
981 if not rv:
982 rv = self.root
983 alogger.parent = rv
985 def _fixupChildren(self, ph, alogger):
987 Ensure that children of the placeholder ph are connected to the
988 specified logger.
990 name = alogger.name
991 namelen = len(name)
992 for c in ph.loggerMap.keys():
993 #The if means ... if not c.parent.name.startswith(nm)
994 #if string.find(c.parent.name, nm) <> 0:
995 if c.parent.name[:namelen] != name:
996 alogger.parent = c.parent
997 c.parent = alogger
999 #---------------------------------------------------------------------------
1000 # Logger classes and functions
1001 #---------------------------------------------------------------------------
1003 class Logger(Filterer):
1005 Instances of the Logger class represent a single logging channel. A
1006 "logging channel" indicates an area of an application. Exactly how an
1007 "area" is defined is up to the application developer. Since an
1008 application can have any number of areas, logging channels are identified
1009 by a unique string. Application areas can be nested (e.g. an area
1010 of "input processing" might include sub-areas "read CSV files", "read
1011 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
1012 channel names are organized into a namespace hierarchy where levels are
1013 separated by periods, much like the Java or Python package namespace. So
1014 in the instance given above, channel names might be "input" for the upper
1015 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
1016 There is no arbitrary limit to the depth of nesting.
1018 def __init__(self, name, level=NOTSET):
1020 Initialize the logger with a name and an optional level.
1022 Filterer.__init__(self)
1023 self.name = name
1024 self.level = _checkLevel(level)
1025 self.parent = None
1026 self.propagate = 1
1027 self.handlers = []
1028 self.disabled = 0
1030 def setLevel(self, level):
1032 Set the logging level of this logger.
1034 self.level = _checkLevel(level)
1036 def debug(self, msg, *args, **kwargs):
1038 Log 'msg % args' with severity 'DEBUG'.
1040 To pass exception information, use the keyword argument exc_info with
1041 a true value, e.g.
1043 logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
1045 if self.isEnabledFor(DEBUG):
1046 self._log(DEBUG, msg, args, **kwargs)
1048 def info(self, msg, *args, **kwargs):
1050 Log 'msg % args' with severity 'INFO'.
1052 To pass exception information, use the keyword argument exc_info with
1053 a true value, e.g.
1055 logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
1057 if self.isEnabledFor(INFO):
1058 self._log(INFO, msg, args, **kwargs)
1060 def warning(self, msg, *args, **kwargs):
1062 Log 'msg % args' with severity 'WARNING'.
1064 To pass exception information, use the keyword argument exc_info with
1065 a true value, e.g.
1067 logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
1069 if self.isEnabledFor(WARNING):
1070 self._log(WARNING, msg, args, **kwargs)
1072 warn = warning
1074 def error(self, msg, *args, **kwargs):
1076 Log 'msg % args' with severity 'ERROR'.
1078 To pass exception information, use the keyword argument exc_info with
1079 a true value, e.g.
1081 logger.error("Houston, we have a %s", "major problem", exc_info=1)
1083 if self.isEnabledFor(ERROR):
1084 self._log(ERROR, msg, args, **kwargs)
1086 def exception(self, msg, *args):
1088 Convenience method for logging an ERROR with exception information.
1090 self.error(*((msg,) + args), **{'exc_info': 1})
1092 def critical(self, msg, *args, **kwargs):
1094 Log 'msg % args' with severity 'CRITICAL'.
1096 To pass exception information, use the keyword argument exc_info with
1097 a true value, e.g.
1099 logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1101 if self.isEnabledFor(CRITICAL):
1102 self._log(CRITICAL, msg, args, **kwargs)
1104 fatal = critical
1106 def log(self, level, msg, *args, **kwargs):
1108 Log 'msg % args' with the integer severity 'level'.
1110 To pass exception information, use the keyword argument exc_info with
1111 a true value, e.g.
1113 logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1115 if type(level) != types.IntType:
1116 if raiseExceptions:
1117 raise TypeError, "level must be an integer"
1118 else:
1119 return
1120 if self.isEnabledFor(level):
1121 self._log(level, msg, args, **kwargs)
1123 def findCaller(self):
1125 Find the stack frame of the caller so that we can note the source
1126 file name, line number and function name.
1128 f = currentframe().f_back
1129 rv = "(unknown file)", 0, "(unknown function)"
1130 while hasattr(f, "f_code"):
1131 co = f.f_code
1132 filename = os.path.normcase(co.co_filename)
1133 if filename == _srcfile:
1134 f = f.f_back
1135 continue
1136 rv = (filename, f.f_lineno, co.co_name)
1137 break
1138 return rv
1140 def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
1142 A factory method which can be overridden in subclasses to create
1143 specialized LogRecords.
1145 rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
1146 if extra is not None:
1147 for key in extra:
1148 if (key in ["message", "asctime"]) or (key in rv.__dict__):
1149 raise KeyError("Attempt to overwrite %r in LogRecord" % key)
1150 rv.__dict__[key] = extra[key]
1151 return rv
1153 def _log(self, level, msg, args, exc_info=None, extra=None):
1155 Low-level logging routine which creates a LogRecord and then calls
1156 all the handlers of this logger to handle the record.
1158 if _srcfile:
1159 #IronPython doesn't track Python frames, so findCaller throws an
1160 #exception. We trap it here so that IronPython can use logging.
1161 try:
1162 fn, lno, func = self.findCaller()
1163 except ValueError:
1164 fn, lno, func = "(unknown file)", 0, "(unknown function)"
1165 else:
1166 fn, lno, func = "(unknown file)", 0, "(unknown function)"
1167 if exc_info:
1168 if type(exc_info) != types.TupleType:
1169 exc_info = sys.exc_info()
1170 record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
1171 self.handle(record)
1173 def handle(self, record):
1175 Call the handlers for the specified record.
1177 This method is used for unpickled records received from a socket, as
1178 well as those created locally. Logger-level filtering is applied.
1180 if (not self.disabled) and self.filter(record):
1181 self.callHandlers(record)
1183 def addHandler(self, hdlr):
1185 Add the specified handler to this logger.
1187 if not (hdlr in self.handlers):
1188 self.handlers.append(hdlr)
1190 def removeHandler(self, hdlr):
1192 Remove the specified handler from this logger.
1194 if hdlr in self.handlers:
1195 #hdlr.close()
1196 hdlr.acquire()
1197 try:
1198 self.handlers.remove(hdlr)
1199 finally:
1200 hdlr.release()
1202 def callHandlers(self, record):
1204 Pass a record to all relevant handlers.
1206 Loop through all handlers for this logger and its parents in the
1207 logger hierarchy. If no handler was found, output a one-off error
1208 message to sys.stderr. Stop searching up the hierarchy whenever a
1209 logger with the "propagate" attribute set to zero is found - that
1210 will be the last logger whose handlers are called.
1212 c = self
1213 found = 0
1214 while c:
1215 for hdlr in c.handlers:
1216 found = found + 1
1217 if record.levelno >= hdlr.level:
1218 hdlr.handle(record)
1219 if not c.propagate:
1220 c = None #break out
1221 else:
1222 c = c.parent
1223 if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
1224 sys.stderr.write("No handlers could be found for logger"
1225 " \"%s\"\n" % self.name)
1226 self.manager.emittedNoHandlerWarning = 1
1228 def getEffectiveLevel(self):
1230 Get the effective level for this logger.
1232 Loop through this logger and its parents in the logger hierarchy,
1233 looking for a non-zero logging level. Return the first one found.
1235 logger = self
1236 while logger:
1237 if logger.level:
1238 return logger.level
1239 logger = logger.parent
1240 return NOTSET
1242 def isEnabledFor(self, level):
1244 Is this logger enabled for level 'level'?
1246 if self.manager.disable >= level:
1247 return 0
1248 return level >= self.getEffectiveLevel()
1250 class RootLogger(Logger):
1252 A root logger is not that different to any other logger, except that
1253 it must have a logging level and there is only one instance of it in
1254 the hierarchy.
1256 def __init__(self, level):
1258 Initialize the logger with the name "root".
1260 Logger.__init__(self, "root", level)
1262 _loggerClass = Logger
1264 class LoggerAdapter:
1266 An adapter for loggers which makes it easier to specify contextual
1267 information in logging output.
1270 def __init__(self, logger, extra):
1272 Initialize the adapter with a logger and a dict-like object which
1273 provides contextual information. This constructor signature allows
1274 easy stacking of LoggerAdapters, if so desired.
1276 You can effectively pass keyword arguments as shown in the
1277 following example:
1279 adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
1281 self.logger = logger
1282 self.extra = extra
1284 def process(self, msg, kwargs):
1286 Process the logging message and keyword arguments passed in to
1287 a logging call to insert contextual information. You can either
1288 manipulate the message itself, the keyword args or both. Return
1289 the message and kwargs modified (or not) to suit your needs.
1291 Normally, you'll only need to override this one method in a
1292 LoggerAdapter subclass for your specific needs.
1294 kwargs["extra"] = self.extra
1295 return msg, kwargs
1297 def debug(self, msg, *args, **kwargs):
1299 Delegate a debug call to the underlying logger, after adding
1300 contextual information from this adapter instance.
1302 msg, kwargs = self.process(msg, kwargs)
1303 self.logger.debug(msg, *args, **kwargs)
1305 def info(self, msg, *args, **kwargs):
1307 Delegate an info call to the underlying logger, after adding
1308 contextual information from this adapter instance.
1310 msg, kwargs = self.process(msg, kwargs)
1311 self.logger.info(msg, *args, **kwargs)
1313 def warning(self, msg, *args, **kwargs):
1315 Delegate a warning call to the underlying logger, after adding
1316 contextual information from this adapter instance.
1318 msg, kwargs = self.process(msg, kwargs)
1319 self.logger.warning(msg, *args, **kwargs)
1321 def error(self, msg, *args, **kwargs):
1323 Delegate an error call to the underlying logger, after adding
1324 contextual information from this adapter instance.
1326 msg, kwargs = self.process(msg, kwargs)
1327 self.logger.error(msg, *args, **kwargs)
1329 def exception(self, msg, *args, **kwargs):
1331 Delegate an exception call to the underlying logger, after adding
1332 contextual information from this adapter instance.
1334 msg, kwargs = self.process(msg, kwargs)
1335 kwargs["exc_info"] = 1
1336 self.logger.error(msg, *args, **kwargs)
1338 def critical(self, msg, *args, **kwargs):
1340 Delegate a critical call to the underlying logger, after adding
1341 contextual information from this adapter instance.
1343 msg, kwargs = self.process(msg, kwargs)
1344 self.logger.critical(msg, *args, **kwargs)
1346 def log(self, level, msg, *args, **kwargs):
1348 Delegate a log call to the underlying logger, after adding
1349 contextual information from this adapter instance.
1351 msg, kwargs = self.process(msg, kwargs)
1352 self.logger.log(level, msg, *args, **kwargs)
1354 root = RootLogger(WARNING)
1355 Logger.root = root
1356 Logger.manager = Manager(Logger.root)
1358 #---------------------------------------------------------------------------
1359 # Configuration classes and functions
1360 #---------------------------------------------------------------------------
1362 BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
1364 def basicConfig(**kwargs):
1366 Do basic configuration for the logging system.
1368 This function does nothing if the root logger already has handlers
1369 configured. It is a convenience method intended for use by simple scripts
1370 to do one-shot configuration of the logging package.
1372 The default behaviour is to create a StreamHandler which writes to
1373 sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1374 add the handler to the root logger.
1376 A number of optional keyword arguments may be specified, which can alter
1377 the default behaviour.
1379 filename Specifies that a FileHandler be created, using the specified
1380 filename, rather than a StreamHandler.
1381 filemode Specifies the mode to open the file, if filename is specified
1382 (if filemode is unspecified, it defaults to 'a').
1383 format Use the specified format string for the handler.
1384 datefmt Use the specified date/time format.
1385 level Set the root logger level to the specified level.
1386 stream Use the specified stream to initialize the StreamHandler. Note
1387 that this argument is incompatible with 'filename' - if both
1388 are present, 'stream' is ignored.
1390 Note that you could specify a stream created using open(filename, mode)
1391 rather than passing the filename and mode in. However, it should be
1392 remembered that StreamHandler does not close its stream (since it may be
1393 using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1394 when the handler is closed.
1396 if len(root.handlers) == 0:
1397 filename = kwargs.get("filename")
1398 if filename:
1399 mode = kwargs.get("filemode", 'a')
1400 hdlr = FileHandler(filename, mode)
1401 else:
1402 stream = kwargs.get("stream")
1403 hdlr = StreamHandler(stream)
1404 fs = kwargs.get("format", BASIC_FORMAT)
1405 dfs = kwargs.get("datefmt", None)
1406 fmt = Formatter(fs, dfs)
1407 hdlr.setFormatter(fmt)
1408 root.addHandler(hdlr)
1409 level = kwargs.get("level")
1410 if level is not None:
1411 root.setLevel(level)
1413 #---------------------------------------------------------------------------
1414 # Utility functions at module level.
1415 # Basically delegate everything to the root logger.
1416 #---------------------------------------------------------------------------
1418 def getLogger(name=None):
1420 Return a logger with the specified name, creating it if necessary.
1422 If no name is specified, return the root logger.
1424 if name:
1425 return Logger.manager.getLogger(name)
1426 else:
1427 return root
1429 #def getRootLogger():
1430 # """
1431 # Return the root logger.
1433 # Note that getLogger('') now does the same thing, so this function is
1434 # deprecated and may disappear in the future.
1435 # """
1436 # return root
1438 def critical(msg, *args, **kwargs):
1440 Log a message with severity 'CRITICAL' on the root logger.
1442 if len(root.handlers) == 0:
1443 basicConfig()
1444 root.critical(*((msg,)+args), **kwargs)
1446 fatal = critical
1448 def error(msg, *args, **kwargs):
1450 Log a message with severity 'ERROR' on the root logger.
1452 if len(root.handlers) == 0:
1453 basicConfig()
1454 root.error(*((msg,)+args), **kwargs)
1456 def exception(msg, *args):
1458 Log a message with severity 'ERROR' on the root logger,
1459 with exception information.
1461 error(*((msg,)+args), **{'exc_info': 1})
1463 def warning(msg, *args, **kwargs):
1465 Log a message with severity 'WARNING' on the root logger.
1467 if len(root.handlers) == 0:
1468 basicConfig()
1469 root.warning(*((msg,)+args), **kwargs)
1471 warn = warning
1473 def info(msg, *args, **kwargs):
1475 Log a message with severity 'INFO' on the root logger.
1477 if len(root.handlers) == 0:
1478 basicConfig()
1479 root.info(*((msg,)+args), **kwargs)
1481 def debug(msg, *args, **kwargs):
1483 Log a message with severity 'DEBUG' on the root logger.
1485 if len(root.handlers) == 0:
1486 basicConfig()
1487 root.debug(*((msg,)+args), **kwargs)
1489 def log(level, msg, *args, **kwargs):
1491 Log 'msg % args' with the integer severity 'level' on the root logger.
1493 if len(root.handlers) == 0:
1494 basicConfig()
1495 root.log(*((level, msg)+args), **kwargs)
1497 def disable(level):
1499 Disable all logging calls less severe than 'level'.
1501 root.manager.disable = level
1503 def shutdown(handlerList=_handlerList):
1505 Perform any cleanup actions in the logging system (e.g. flushing
1506 buffers).
1508 Should be called at application exit.
1510 for h in handlerList[:]:
1511 #errors might occur, for example, if files are locked
1512 #we just ignore them if raiseExceptions is not set
1513 try:
1514 h.flush()
1515 h.close()
1516 except:
1517 if raiseExceptions:
1518 raise
1519 #else, swallow
1521 #Let's try and shutdown automatically on application exit...
1522 try:
1523 import atexit
1524 atexit.register(shutdown)
1525 except ImportError: # for Python versions < 2.0
1526 def exithook(status, old_exit=sys.exit):
1527 try:
1528 shutdown()
1529 finally:
1530 old_exit(status)
1532 sys.exit = exithook
1534 # Null handler
1536 class NullHandler(Handler):
1538 This handler does nothing. It's intended to be used to avoid the
1539 "No handlers could be found for logger XXX" one-off warning. This is
1540 important for library code, which may contain code to log events. If a user
1541 of the library does not configure logging, the one-off warning might be
1542 produced; to avoid this, the library developer simply needs to instantiate
1543 a NullHandler and add it to the top-level logger of the library module or
1544 package.
1546 def emit(self, record):
1547 pass
1549 # Warnings integration
1551 _warnings_showwarning = None
1553 def _showwarning(message, category, filename, lineno, file=None, line=None):
1555 Implementation of showwarnings which redirects to logging, which will first
1556 check to see if the file parameter is None. If a file is specified, it will
1557 delegate to the original warnings implementation of showwarning. Otherwise,
1558 it will call warnings.formatwarning and will log the resulting string to a
1559 warnings logger named "py.warnings" with level logging.WARNING.
1561 if file is not None:
1562 if _warnings_showwarning is not None:
1563 _warnings_showwarning(message, category, filename, lineno, file, line)
1564 else:
1565 s = warnings.formatwarning(message, category, filename, lineno, line)
1566 logger = getLogger("py.warnings")
1567 if not logger.handlers:
1568 logger.addHandler(NullHandler())
1569 logger.warning("%s", s)
1571 def captureWarnings(capture):
1573 If capture is true, redirect all warnings to the logging package.
1574 If capture is False, ensure that warnings are not redirected to logging
1575 but to their original destinations.
1577 global _warnings_showwarning
1578 if capture:
1579 if _warnings_showwarning is None:
1580 _warnings_showwarning = warnings.showwarning
1581 warnings.showwarning = _showwarning
1582 else:
1583 if _warnings_showwarning is not None:
1584 warnings.showwarning = _warnings_showwarning
1585 _warnings_showwarning = None