1 # Copyright 2001-2005 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.
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 Should work under Python versions >= 1.5.2, except that source line
22 information is not available unless 'sys._getframe()' is.
24 Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved.
26 To use, simply 'import logging' and log away!
29 import sys
, os
, types
, time
, string
, cStringIO
, traceback
42 __author__
= "Vinay Sajip <vinay_sajip@red-dove.com>"
44 __version__
= "0.4.9.7"
45 __date__
= "07 October 2005"
47 #---------------------------------------------------------------------------
48 # Miscellaneous module data
49 #---------------------------------------------------------------------------
52 # _srcfile is used when walking the stack to check when we've got the first
55 if hasattr(sys
, 'frozen'): #support for py2exe
56 _srcfile
= "logging%s__init__%s" % (os
.sep
, __file__
[-4:])
57 elif string
.lower(__file__
[-4:]) in ['.pyc', '.pyo']:
58 _srcfile
= __file__
[:-4] + '.py'
61 _srcfile
= os
.path
.normcase(_srcfile
)
63 # next bit filched from 1.5.2's inspect.py
65 """Return the frame object for the caller's stack frame."""
69 return sys
.exc_traceback
.tb_frame
.f_back
71 if hasattr(sys
, '_getframe'): currentframe
= sys
._getframe
74 # _srcfile is only used in conjunction with sys._getframe().
75 # To provide compatibility with older versions of Python, set _srcfile
76 # to None if _getframe() is not available; this value will prevent
77 # findCaller() from being called.
78 #if not hasattr(sys, "_getframe"):
82 #_startTime is used as the base when calculating the relative time of events
84 _startTime
= time
.time()
87 #raiseExceptions is used to see if exceptions during handling should be
92 #---------------------------------------------------------------------------
94 #---------------------------------------------------------------------------
96 # Default levels and level names, these can be replaced with any positive set
97 # of values having corresponding names. There is a pseudo-level, NOTSET, which
98 # is only really there as a lower limit for user-defined levels. Handlers and
99 # loggers are initialized with NOTSET so that they will log all messages, even
100 # at user-defined levels.
113 CRITICAL
: 'CRITICAL',
119 'CRITICAL' : CRITICAL
,
128 def getLevelName(level
):
130 Return the textual representation of logging level 'level'.
132 If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
133 INFO, DEBUG) then you get the corresponding string. If you have
134 associated levels with names using addLevelName then the name you have
135 associated with 'level' is returned.
137 If a numeric value corresponding to one of the defined levels is passed
138 in, the corresponding string representation is returned.
140 Otherwise, the string "Level %s" % level is returned.
142 return _levelNames
.get(level
, ("Level %s" % level
))
144 def addLevelName(level
, levelName
):
146 Associate 'levelName' with 'level'.
148 This is used when converting levels to text during message formatting.
151 try: #unlikely to cause an exception, but you never know...
152 _levelNames
[level
] = levelName
153 _levelNames
[levelName
] = level
157 #---------------------------------------------------------------------------
158 # Thread-related stuff
159 #---------------------------------------------------------------------------
162 #_lock is used to serialize access to shared data structures in this module.
163 #This needs to be an RLock because fileConfig() creates Handlers and so
164 #might arbitrary user threads. Since Handler.__init__() updates the shared
165 #dictionary _handlers, it needs to acquire the lock. But if configuring,
166 #the lock would already have been acquired - so we need an RLock.
167 #The same argument applies to Loggers and Manager.loggerDict.
173 Acquire the module-level lock for serializing access to shared data.
175 This should be released with _releaseLock().
178 if (not _lock
) and thread
:
179 _lock
= threading
.RLock()
185 Release the module-level lock acquired by calling _acquireLock().
190 #---------------------------------------------------------------------------
192 #---------------------------------------------------------------------------
196 A LogRecord instance represents an event being logged.
198 LogRecord instances are created every time something is logged. They
199 contain all the information pertinent to the event being logged. The
200 main information passed in is in msg and args, which are combined
201 using str(msg) % args to create the message field of the record. The
202 record also includes information such as when the record was created,
203 the source line where the logging call was made, and any exception
204 information to be logged.
206 def __init__(self
, name
, level
, pathname
, lineno
, msg
, args
, exc_info
):
208 Initialize a logging record with interesting information.
214 # The following statement allows passing of a dictionary as a sole
215 # argument, so that you can do something like
216 # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
217 # Suggested by Stefan Behnel.
218 # Note that without the test for args[0], we get a problem because
219 # during formatting, we test to see if the arg is present using
220 # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
221 # and if the passed arg fails 'if self.args:' then no formatting
222 # is done. For example, logger.warn('Value is %d', 0) would log
223 # 'Value is %d' instead of 'Value is 0'.
224 # For the use case of passing a dictionary, this should not be a
226 if args
and (len(args
) == 1) and args
[0] and (type(args
[0]) == types
.DictType
):
229 self
.levelname
= getLevelName(level
)
231 self
.pathname
= pathname
233 self
.filename
= os
.path
.basename(pathname
)
234 self
.module
= os
.path
.splitext(self
.filename
)[0]
236 self
.filename
= pathname
237 self
.module
= "Unknown module"
238 self
.exc_info
= exc_info
239 self
.exc_text
= None # used to cache the traceback text
242 self
.msecs
= (ct
- long(ct
)) * 1000
243 self
.relativeCreated
= (self
.created
- _startTime
) * 1000
245 self
.thread
= thread
.get_ident()
246 self
.threadName
= threading
.currentThread().getName()
249 self
.threadName
= None
250 if hasattr(os
, 'getpid'):
251 self
.process
= os
.getpid()
256 return '<LogRecord: %s, %s, %s, %s, "%s">'%(self
.name
, self
.levelno
,
257 self
.pathname
, self
.lineno
, self
.msg
)
259 def getMessage(self
):
261 Return the message for this LogRecord.
263 Return the message for this LogRecord after merging any user-supplied
264 arguments with the message.
266 if not hasattr(types
, "UnicodeType"): #if no unicode support...
270 if type(msg
) not in (types
.UnicodeType
, types
.StringType
):
274 msg
= self
.msg
#Defer encoding till later
276 msg
= msg
% self
.args
279 def makeLogRecord(dict):
281 Make a LogRecord whose attributes are defined by the specified dictionary,
282 This function is useful for converting a logging event received over
283 a socket connection (which is sent as a dictionary) into a LogRecord
286 rv
= LogRecord(None, None, "", 0, "", (), None)
287 rv
.__dict
__.update(dict)
290 #---------------------------------------------------------------------------
291 # Formatter classes and functions
292 #---------------------------------------------------------------------------
296 Formatter instances are used to convert a LogRecord to text.
298 Formatters need to know how a LogRecord is constructed. They are
299 responsible for converting a LogRecord to (usually) a string which can
300 be interpreted by either a human or an external system. The base Formatter
301 allows a formatting string to be specified. If none is supplied, the
302 default value of "%s(message)\\n" is used.
304 The Formatter can be initialized with a format string which makes use of
305 knowledge of the LogRecord attributes - e.g. the default value mentioned
306 above makes use of the fact that the user's message and arguments are pre-
307 formatted into a LogRecord's message attribute. Currently, the useful
308 attributes in a LogRecord are described by:
310 %(name)s Name of the logger (logging channel)
311 %(levelno)s Numeric logging level for the message (DEBUG, INFO,
312 WARNING, ERROR, CRITICAL)
313 %(levelname)s Text logging level for the message ("DEBUG", "INFO",
314 "WARNING", "ERROR", "CRITICAL")
315 %(pathname)s Full pathname of the source file where the logging
316 call was issued (if available)
317 %(filename)s Filename portion of pathname
318 %(module)s Module (name portion of filename)
319 %(lineno)d Source line number where the logging call was issued
321 %(created)f Time when the LogRecord was created (time.time()
323 %(asctime)s Textual time when the LogRecord was created
324 %(msecs)d Millisecond portion of the creation time
325 %(relativeCreated)d Time in milliseconds when the LogRecord was created,
326 relative to the time the logging module was loaded
327 (typically at application startup time)
328 %(thread)d Thread ID (if available)
329 %(threadName)s Thread name (if available)
330 %(process)d Process ID (if available)
331 %(message)s The result of record.getMessage(), computed just as
332 the record is emitted
335 converter
= time
.localtime
337 def __init__(self
, fmt
=None, datefmt
=None):
339 Initialize the formatter with specified format strings.
341 Initialize the formatter either with the specified format string, or a
342 default as described above. Allow for specialized date formatting with
343 the optional datefmt argument (if omitted, you get the ISO8601 format).
348 self
._fmt
= "%(message)s"
349 self
.datefmt
= datefmt
351 def formatTime(self
, record
, datefmt
=None):
353 Return the creation time of the specified LogRecord as formatted text.
355 This method should be called from format() by a formatter which
356 wants to make use of a formatted time. This method can be overridden
357 in formatters to provide for any specific requirement, but the
358 basic behaviour is as follows: if datefmt (a string) is specified,
359 it is used with time.strftime() to format the creation time of the
360 record. Otherwise, the ISO8601 format is used. The resulting
361 string is returned. This function uses a user-configurable function
362 to convert the creation time to a tuple. By default, time.localtime()
363 is used; to change this for a particular formatter instance, set the
364 'converter' attribute to a function with the same signature as
365 time.localtime() or time.gmtime(). To change it for all formatters,
366 for example if you want all logging times to be shown in GMT,
367 set the 'converter' attribute in the Formatter class.
369 ct
= self
.converter(record
.created
)
371 s
= time
.strftime(datefmt
, ct
)
373 t
= time
.strftime("%Y-%m-%d %H:%M:%S", ct
)
374 s
= "%s,%03d" % (t
, record
.msecs
)
377 def formatException(self
, ei
):
379 Format and return the specified exception information as a string.
381 This default implementation just uses
382 traceback.print_exception()
384 sio
= cStringIO
.StringIO()
385 traceback
.print_exception(ei
[0], ei
[1], ei
[2], None, sio
)
392 def format(self
, record
):
394 Format the specified record as text.
396 The record's attribute dictionary is used as the operand to a
397 string formatting operation which yields the returned string.
398 Before formatting the dictionary, a couple of preparatory steps
399 are carried out. The message attribute of the record is computed
400 using LogRecord.getMessage(). If the formatting string contains
401 "%(asctime)", formatTime() is called to format the event time.
402 If there is exception information, it is formatted using
403 formatException() and appended to the message.
405 record
.message
= record
.getMessage()
406 if string
.find(self
._fmt
,"%(asctime)") >= 0:
407 record
.asctime
= self
.formatTime(record
, self
.datefmt
)
408 s
= self
._fmt
% record
.__dict
__
410 # Cache the traceback text to avoid converting it multiple times
411 # (it's constant anyway)
412 if not record
.exc_text
:
413 record
.exc_text
= self
.formatException(record
.exc_info
)
417 s
= s
+ record
.exc_text
421 # The default formatter to use when no other is specified
423 _defaultFormatter
= Formatter()
425 class BufferingFormatter
:
427 A formatter suitable for formatting a number of records.
429 def __init__(self
, linefmt
=None):
431 Optionally specify a formatter which will be used to format each
435 self
.linefmt
= linefmt
437 self
.linefmt
= _defaultFormatter
439 def formatHeader(self
, records
):
441 Return the header string for the specified records.
445 def formatFooter(self
, records
):
447 Return the footer string for the specified records.
451 def format(self
, records
):
453 Format the specified records and return the result as a string.
457 rv
= rv
+ self
.formatHeader(records
)
458 for record
in records
:
459 rv
= rv
+ self
.linefmt
.format(record
)
460 rv
= rv
+ self
.formatFooter(records
)
463 #---------------------------------------------------------------------------
464 # Filter classes and functions
465 #---------------------------------------------------------------------------
469 Filter instances are used to perform arbitrary filtering of LogRecords.
471 Loggers and Handlers can optionally use Filter instances to filter
472 records as desired. The base filter class only allows events which are
473 below a certain point in the logger hierarchy. For example, a filter
474 initialized with "A.B" will allow events logged by loggers "A.B",
475 "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
476 initialized with the empty string, all events are passed.
478 def __init__(self
, name
=''):
482 Initialize with the name of the logger which, together with its
483 children, will have its events allowed through the filter. If no
484 name is specified, allow every event.
487 self
.nlen
= len(name
)
489 def filter(self
, record
):
491 Determine if the specified record is to be logged.
493 Is the specified record to be logged? Returns 0 for no, nonzero for
494 yes. If deemed appropriate, the record may be modified in-place.
498 elif self
.name
== record
.name
:
500 elif string
.find(record
.name
, self
.name
, 0, self
.nlen
) != 0:
502 return (record
.name
[self
.nlen
] == ".")
506 A base class for loggers and handlers which allows them to share
511 Initialize the list of filters to be an empty list.
515 def addFilter(self
, filter):
517 Add the specified filter to this handler.
519 if not (filter in self
.filters
):
520 self
.filters
.append(filter)
522 def removeFilter(self
, filter):
524 Remove the specified filter from this handler.
526 if filter in self
.filters
:
527 self
.filters
.remove(filter)
529 def filter(self
, record
):
531 Determine if a record is loggable by consulting all the filters.
533 The default is to allow the record to be logged; any filter can veto
534 this and the record is then dropped. Returns a zero value if a record
535 is to be dropped, else non-zero.
538 for f
in self
.filters
:
539 if not f
.filter(record
):
544 #---------------------------------------------------------------------------
545 # Handler classes and functions
546 #---------------------------------------------------------------------------
548 _handlers
= {} #repository of handlers (for flushing when shutdown called)
549 _handlerList
= [] # added to allow handlers to be removed in reverse of order initialized
551 class Handler(Filterer
):
553 Handler instances dispatch logging events to specific destinations.
555 The base handler class. Acts as a placeholder which defines the Handler
556 interface. Handlers can optionally use Formatter instances to format
557 records as desired. By default, no formatter is specified; in this case,
558 the 'raw' message as determined by record.message is logged.
560 def __init__(self
, level
=NOTSET
):
562 Initializes the instance - basically setting the formatter to None
563 and the filter list to empty.
565 Filterer
.__init
__(self
)
567 self
.formatter
= None
568 #get the module data lock, as we're updating a shared structure.
570 try: #unlikely to raise an exception, but you never know...
572 _handlerList
.insert(0, self
)
577 def createLock(self
):
579 Acquire a thread lock for serializing access to the underlying I/O.
582 self
.lock
= threading
.RLock()
588 Acquire the I/O thread lock.
595 Release the I/O thread lock.
600 def setLevel(self
, level
):
602 Set the logging level of this handler.
606 def format(self
, record
):
608 Format the specified record.
610 If a formatter is set, use it. Otherwise, use the default formatter
616 fmt
= _defaultFormatter
617 return fmt
.format(record
)
619 def emit(self
, record
):
621 Do whatever it takes to actually log the specified logging record.
623 This version is intended to be implemented by subclasses and so
624 raises a NotImplementedError.
626 raise NotImplementedError, 'emit must be implemented '\
627 'by Handler subclasses'
629 def handle(self
, record
):
631 Conditionally emit the specified logging record.
633 Emission depends on filters which may have been added to the handler.
634 Wrap the actual emission of the record with acquisition/release of
635 the I/O thread lock. Returns whether the filter passed the record for
638 rv
= self
.filter(record
)
647 def setFormatter(self
, fmt
):
649 Set the formatter for this handler.
655 Ensure all logging output has been flushed.
657 This version does nothing and is intended to be implemented by
664 Tidy up any resources used by the handler.
666 This version does removes the handler from an internal list
667 of handlers which is closed when shutdown() is called. Subclasses
668 should ensure that this gets called from overridden close()
671 #get the module data lock, as we're updating a shared structure.
673 try: #unlikely to raise an exception, but you never know...
675 _handlerList
.remove(self
)
679 def handleError(self
, record
):
681 Handle errors which occur during an emit() call.
683 This method should be called from handlers when an exception is
684 encountered during an emit() call. If raiseExceptions is false,
685 exceptions get silently ignored. This is what is mostly wanted
686 for a logging system - most users will not care about errors in
687 the logging system, they are more interested in application errors.
688 You could, however, replace this with a custom handler if you wish.
689 The record which was being processed is passed in to this method.
693 traceback
.print_exception(ei
[0], ei
[1], ei
[2], None, sys
.stderr
)
696 class StreamHandler(Handler
):
698 A handler class which writes logging records, appropriately formatted,
699 to a stream. Note that this class does not close the stream, as
700 sys.stdout or sys.stderr may be used.
702 def __init__(self
, strm
=None):
704 Initialize the handler.
706 If strm is not specified, sys.stderr is used.
708 Handler
.__init
__(self
)
712 self
.formatter
= None
720 def emit(self
, record
):
724 If a formatter is specified, it is used to format the record.
725 The record is then written to the stream with a trailing newline
726 [N.B. this may be removed depending on feedback]. If exception
727 information is present, it is formatted using
728 traceback.print_exception and appended to the stream.
731 msg
= self
.format(record
)
733 if not hasattr(types
, "UnicodeType"): #if no unicode support...
734 self
.stream
.write(fs
% msg
)
737 self
.stream
.write(fs
% msg
)
739 self
.stream
.write(fs
% msg
.encode("UTF-8"))
741 except (KeyboardInterrupt, SystemExit):
744 self
.handleError(record
)
746 class FileHandler(StreamHandler
):
748 A handler class which writes formatted logging records to disk files.
750 def __init__(self
, filename
, mode
='a', encoding
=None):
752 Open the specified file and use it as the stream for logging.
757 stream
= open(filename
, mode
)
759 stream
= codecs
.open(filename
, mode
, encoding
)
760 StreamHandler
.__init
__(self
, stream
)
761 #keep the absolute path, otherwise derived classes which use this
762 #may come a cropper when the current directory changes
763 self
.baseFilename
= os
.path
.abspath(filename
)
772 StreamHandler
.close(self
)
774 #---------------------------------------------------------------------------
775 # Manager classes and functions
776 #---------------------------------------------------------------------------
780 PlaceHolder instances are used in the Manager logger hierarchy to take
781 the place of nodes for which no loggers have been defined. This class is
782 intended for internal use only and not as part of the public API.
784 def __init__(self
, alogger
):
786 Initialize with the specified logger being a child of this placeholder.
788 #self.loggers = [alogger]
789 self
.loggerMap
= { alogger
: None }
791 def append(self
, alogger
):
793 Add the specified logger as a child of this placeholder.
795 #if alogger not in self.loggers:
796 if not self
.loggerMap
.has_key(alogger
):
797 #self.loggers.append(alogger)
798 self
.loggerMap
[alogger
] = None
801 # Determine which class to use when instantiating loggers.
805 def setLoggerClass(klass
):
807 Set the class to be used when instantiating a logger. The class should
808 define __init__() such that only a name argument is required, and the
809 __init__() should call Logger.__init__()
812 if not issubclass(klass
, Logger
):
813 raise TypeError, "logger not derived from logging.Logger: " + \
818 def getLoggerClass():
820 Return the class to be used when instantiating a logger.
827 There is [under normal circumstances] just one Manager instance, which
828 holds the hierarchy of loggers.
830 def __init__(self
, rootnode
):
832 Initialize the manager with the root node of the logger hierarchy.
836 self
.emittedNoHandlerWarning
= 0
839 def getLogger(self
, name
):
841 Get a logger with the specified name (channel name), creating it
842 if it doesn't yet exist. This name is a dot-separated hierarchical
843 name, such as "a", "a.b", "a.b.c" or similar.
845 If a PlaceHolder existed for the specified name [i.e. the logger
846 didn't exist but a child of it did], replace it with the created
847 logger and fix up the parent/child references which pointed to the
848 placeholder to now point to the logger.
853 if self
.loggerDict
.has_key(name
):
854 rv
= self
.loggerDict
[name
]
855 if isinstance(rv
, PlaceHolder
):
857 rv
= _loggerClass(name
)
859 self
.loggerDict
[name
] = rv
860 self
._fixupChildren
(ph
, rv
)
861 self
._fixupParents
(rv
)
863 rv
= _loggerClass(name
)
865 self
.loggerDict
[name
] = rv
866 self
._fixupParents
(rv
)
871 def _fixupParents(self
, alogger
):
873 Ensure that there are either loggers or placeholders all the way
874 from the specified logger to the root of the logger hierarchy.
877 i
= string
.rfind(name
, ".")
879 while (i
> 0) and not rv
:
881 if not self
.loggerDict
.has_key(substr
):
882 self
.loggerDict
[substr
] = PlaceHolder(alogger
)
884 obj
= self
.loggerDict
[substr
]
885 if isinstance(obj
, Logger
):
888 assert isinstance(obj
, PlaceHolder
)
890 i
= string
.rfind(name
, ".", 0, i
- 1)
895 def _fixupChildren(self
, ph
, alogger
):
897 Ensure that children of the placeholder ph are connected to the
900 #for c in ph.loggers:
901 for c
in ph
.loggerMap
.keys():
902 if string
.find(c
.parent
.name
, alogger
.name
) <> 0:
903 alogger
.parent
= c
.parent
906 #---------------------------------------------------------------------------
907 # Logger classes and functions
908 #---------------------------------------------------------------------------
910 class Logger(Filterer
):
912 Instances of the Logger class represent a single logging channel. A
913 "logging channel" indicates an area of an application. Exactly how an
914 "area" is defined is up to the application developer. Since an
915 application can have any number of areas, logging channels are identified
916 by a unique string. Application areas can be nested (e.g. an area
917 of "input processing" might include sub-areas "read CSV files", "read
918 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
919 channel names are organized into a namespace hierarchy where levels are
920 separated by periods, much like the Java or Python package namespace. So
921 in the instance given above, channel names might be "input" for the upper
922 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
923 There is no arbitrary limit to the depth of nesting.
925 def __init__(self
, name
, level
=NOTSET
):
927 Initialize the logger with a name and an optional level.
929 Filterer
.__init
__(self
)
937 def setLevel(self
, level
):
939 Set the logging level of this logger.
943 def debug(self
, msg
, *args
, **kwargs
):
945 Log 'msg % args' with severity 'DEBUG'.
947 To pass exception information, use the keyword argument exc_info with
950 logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
952 if self
.manager
.disable
>= DEBUG
:
954 if DEBUG
>= self
.getEffectiveLevel():
955 apply(self
._log
, (DEBUG
, msg
, args
), kwargs
)
957 def info(self
, msg
, *args
, **kwargs
):
959 Log 'msg % args' with severity 'INFO'.
961 To pass exception information, use the keyword argument exc_info with
964 logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
966 if self
.manager
.disable
>= INFO
:
968 if INFO
>= self
.getEffectiveLevel():
969 apply(self
._log
, (INFO
, msg
, args
), kwargs
)
971 def warning(self
, msg
, *args
, **kwargs
):
973 Log 'msg % args' with severity 'WARNING'.
975 To pass exception information, use the keyword argument exc_info with
978 logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
980 if self
.manager
.disable
>= WARNING
:
982 if self
.isEnabledFor(WARNING
):
983 apply(self
._log
, (WARNING
, msg
, args
), kwargs
)
987 def error(self
, msg
, *args
, **kwargs
):
989 Log 'msg % args' with severity 'ERROR'.
991 To pass exception information, use the keyword argument exc_info with
994 logger.error("Houston, we have a %s", "major problem", exc_info=1)
996 if self
.manager
.disable
>= ERROR
:
998 if self
.isEnabledFor(ERROR
):
999 apply(self
._log
, (ERROR
, msg
, args
), kwargs
)
1001 def exception(self
, msg
, *args
):
1003 Convenience method for logging an ERROR with exception information.
1005 apply(self
.error
, (msg
,) + args
, {'exc_info': 1})
1007 def critical(self
, msg
, *args
, **kwargs
):
1009 Log 'msg % args' with severity 'CRITICAL'.
1011 To pass exception information, use the keyword argument exc_info with
1014 logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1016 if self
.manager
.disable
>= CRITICAL
:
1018 if CRITICAL
>= self
.getEffectiveLevel():
1019 apply(self
._log
, (CRITICAL
, msg
, args
), kwargs
)
1023 def log(self
, level
, msg
, *args
, **kwargs
):
1025 Log 'msg % args' with the integer severity 'level'.
1027 To pass exception information, use the keyword argument exc_info with
1030 logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1032 if type(level
) != types
.IntType
:
1034 raise TypeError, "level must be an integer"
1037 if self
.manager
.disable
>= level
:
1039 if self
.isEnabledFor(level
):
1040 apply(self
._log
, (level
, msg
, args
), kwargs
)
1042 def findCaller(self
):
1044 Find the stack frame of the caller so that we can note the source
1045 file name, line number and function name.
1047 f
= currentframe().f_back
1050 filename
= os
.path
.normcase(co
.co_filename
)
1051 if filename
== _srcfile
:
1054 return filename
, f
.f_lineno
, co
.co_name
1056 def makeRecord(self
, name
, level
, fn
, lno
, msg
, args
, exc_info
):
1058 A factory method which can be overridden in subclasses to create
1059 specialized LogRecords.
1061 return LogRecord(name
, level
, fn
, lno
, msg
, args
, exc_info
)
1063 def _log(self
, level
, msg
, args
, exc_info
=None):
1065 Low-level logging routine which creates a LogRecord and then calls
1066 all the handlers of this logger to handle the record.
1069 fn
, lno
, func
= self
.findCaller()
1071 fn
, lno
, func
= "(unknown file)", 0, "(unknown function)"
1073 if type(exc_info
) != types
.TupleType
:
1074 exc_info
= sys
.exc_info()
1075 record
= self
.makeRecord(self
.name
, level
, fn
, lno
, msg
, args
, exc_info
)
1078 def handle(self
, record
):
1080 Call the handlers for the specified record.
1082 This method is used for unpickled records received from a socket, as
1083 well as those created locally. Logger-level filtering is applied.
1085 if (not self
.disabled
) and self
.filter(record
):
1086 self
.callHandlers(record
)
1088 def addHandler(self
, hdlr
):
1090 Add the specified handler to this logger.
1092 if not (hdlr
in self
.handlers
):
1093 self
.handlers
.append(hdlr
)
1095 def removeHandler(self
, hdlr
):
1097 Remove the specified handler from this logger.
1099 if hdlr
in self
.handlers
:
1103 self
.handlers
.remove(hdlr
)
1107 def callHandlers(self
, record
):
1109 Pass a record to all relevant handlers.
1111 Loop through all handlers for this logger and its parents in the
1112 logger hierarchy. If no handler was found, output a one-off error
1113 message to sys.stderr. Stop searching up the hierarchy whenever a
1114 logger with the "propagate" attribute set to zero is found - that
1115 will be the last logger whose handlers are called.
1120 for hdlr
in c
.handlers
:
1122 if record
.levelno
>= hdlr
.level
:
1128 if (found
== 0) and raiseExceptions
and not self
.manager
.emittedNoHandlerWarning
:
1129 sys
.stderr
.write("No handlers could be found for logger"
1130 " \"%s\"\n" % self
.name
)
1131 self
.manager
.emittedNoHandlerWarning
= 1
1133 def getEffectiveLevel(self
):
1135 Get the effective level for this logger.
1137 Loop through this logger and its parents in the logger hierarchy,
1138 looking for a non-zero logging level. Return the first one found.
1144 logger
= logger
.parent
1147 def isEnabledFor(self
, level
):
1149 Is this logger enabled for level 'level'?
1151 if self
.manager
.disable
>= level
:
1153 return level
>= self
.getEffectiveLevel()
1155 class RootLogger(Logger
):
1157 A root logger is not that different to any other logger, except that
1158 it must have a logging level and there is only one instance of it in
1161 def __init__(self
, level
):
1163 Initialize the logger with the name "root".
1165 Logger
.__init
__(self
, "root", level
)
1167 _loggerClass
= Logger
1169 root
= RootLogger(WARNING
)
1171 Logger
.manager
= Manager(Logger
.root
)
1173 #---------------------------------------------------------------------------
1174 # Configuration classes and functions
1175 #---------------------------------------------------------------------------
1177 BASIC_FORMAT
= "%(levelname)s:%(name)s:%(message)s"
1179 def basicConfig(**kwargs
):
1181 Do basic configuration for the logging system.
1183 This function does nothing if the root logger already has handlers
1184 configured. It is a convenience method intended for use by simple scripts
1185 to do one-shot configuration of the logging package.
1187 The default behaviour is to create a StreamHandler which writes to
1188 sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1189 add the handler to the root logger.
1191 A number of optional keyword arguments may be specified, which can alter
1192 the default behaviour.
1194 filename Specifies that a FileHandler be created, using the specified
1195 filename, rather than a StreamHandler.
1196 filemode Specifies the mode to open the file, if filename is specified
1197 (if filemode is unspecified, it defaults to 'a').
1198 format Use the specified format string for the handler.
1199 datefmt Use the specified date/time format.
1200 level Set the root logger level to the specified level.
1201 stream Use the specified stream to initialize the StreamHandler. Note
1202 that this argument is incompatible with 'filename' - if both
1203 are present, 'stream' is ignored.
1205 Note that you could specify a stream created using open(filename, mode)
1206 rather than passing the filename and mode in. However, it should be
1207 remembered that StreamHandler does not close its stream (since it may be
1208 using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1209 when the handler is closed.
1211 if len(root
.handlers
) == 0:
1212 filename
= kwargs
.get("filename")
1214 mode
= kwargs
.get("filemode", 'a')
1215 hdlr
= FileHandler(filename
, mode
)
1217 stream
= kwargs
.get("stream")
1218 hdlr
= StreamHandler(stream
)
1219 fs
= kwargs
.get("format", BASIC_FORMAT
)
1220 dfs
= kwargs
.get("datefmt", None)
1221 fmt
= Formatter(fs
, dfs
)
1222 hdlr
.setFormatter(fmt
)
1223 root
.addHandler(hdlr
)
1224 level
= kwargs
.get("level")
1226 root
.setLevel(level
)
1228 #---------------------------------------------------------------------------
1229 # Utility functions at module level.
1230 # Basically delegate everything to the root logger.
1231 #---------------------------------------------------------------------------
1233 def getLogger(name
=None):
1235 Return a logger with the specified name, creating it if necessary.
1237 If no name is specified, return the root logger.
1240 return Logger
.manager
.getLogger(name
)
1244 #def getRootLogger():
1246 # Return the root logger.
1248 # Note that getLogger('') now does the same thing, so this function is
1249 # deprecated and may disappear in the future.
1253 def critical(msg
, *args
, **kwargs
):
1255 Log a message with severity 'CRITICAL' on the root logger.
1257 if len(root
.handlers
) == 0:
1259 apply(root
.critical
, (msg
,)+args
, kwargs
)
1263 def error(msg
, *args
, **kwargs
):
1265 Log a message with severity 'ERROR' on the root logger.
1267 if len(root
.handlers
) == 0:
1269 apply(root
.error
, (msg
,)+args
, kwargs
)
1271 def exception(msg
, *args
):
1273 Log a message with severity 'ERROR' on the root logger,
1274 with exception information.
1276 apply(error
, (msg
,)+args
, {'exc_info': 1})
1278 def warning(msg
, *args
, **kwargs
):
1280 Log a message with severity 'WARNING' on the root logger.
1282 if len(root
.handlers
) == 0:
1284 apply(root
.warning
, (msg
,)+args
, kwargs
)
1288 def info(msg
, *args
, **kwargs
):
1290 Log a message with severity 'INFO' on the root logger.
1292 if len(root
.handlers
) == 0:
1294 apply(root
.info
, (msg
,)+args
, kwargs
)
1296 def debug(msg
, *args
, **kwargs
):
1298 Log a message with severity 'DEBUG' on the root logger.
1300 if len(root
.handlers
) == 0:
1302 apply(root
.debug
, (msg
,)+args
, kwargs
)
1304 def log(level
, msg
, *args
, **kwargs
):
1306 Log 'msg % args' with the integer severity 'level' on the root logger.
1308 if len(root
.handlers
) == 0:
1310 apply(root
.log
, (level
, msg
)+args
, kwargs
)
1314 Disable all logging calls less severe than 'level'.
1316 root
.manager
.disable
= level
1320 Perform any cleanup actions in the logging system (e.g. flushing
1323 Should be called at application exit.
1325 for h
in _handlerList
[:]: # was _handlers.keys():
1326 #errors might occur, for example, if files are locked
1327 #we just ignore them
1334 #Let's try and shutdown automatically on application exit...
1337 atexit
.register(shutdown
)
1338 except ImportError: # for Python versions < 2.0
1339 def exithook(status
, old_exit
=sys
.exit
):