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>"
43 __status__
= "production"
44 __version__
= "0.5.0.0"
45 __date__
= "08 January 2007"
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
93 # If you don't want threading information in the log, set this to zero
98 # If you don't want process information in the log, set this to zero
102 #---------------------------------------------------------------------------
103 # Level related stuff
104 #---------------------------------------------------------------------------
106 # Default levels and level names, these can be replaced with any positive set
107 # of values having corresponding names. There is a pseudo-level, NOTSET, which
108 # is only really there as a lower limit for user-defined levels. Handlers and
109 # loggers are initialized with NOTSET so that they will log all messages, even
110 # at user-defined levels.
123 CRITICAL
: 'CRITICAL',
129 'CRITICAL' : CRITICAL
,
138 def getLevelName(level
):
140 Return the textual representation of logging level 'level'.
142 If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
143 INFO, DEBUG) then you get the corresponding string. If you have
144 associated levels with names using addLevelName then the name you have
145 associated with 'level' is returned.
147 If a numeric value corresponding to one of the defined levels is passed
148 in, the corresponding string representation is returned.
150 Otherwise, the string "Level %s" % level is returned.
152 return _levelNames
.get(level
, ("Level %s" % level
))
154 def addLevelName(level
, levelName
):
156 Associate 'levelName' with 'level'.
158 This is used when converting levels to text during message formatting.
161 try: #unlikely to cause an exception, but you never know...
162 _levelNames
[level
] = levelName
163 _levelNames
[levelName
] = level
167 #---------------------------------------------------------------------------
168 # Thread-related stuff
169 #---------------------------------------------------------------------------
172 #_lock is used to serialize access to shared data structures in this module.
173 #This needs to be an RLock because fileConfig() creates Handlers and so
174 #might arbitrary user threads. Since Handler.__init__() updates the shared
175 #dictionary _handlers, it needs to acquire the lock. But if configuring,
176 #the lock would already have been acquired - so we need an RLock.
177 #The same argument applies to Loggers and Manager.loggerDict.
183 Acquire the module-level lock for serializing access to shared data.
185 This should be released with _releaseLock().
188 if (not _lock
) and thread
:
189 _lock
= threading
.RLock()
195 Release the module-level lock acquired by calling _acquireLock().
200 #---------------------------------------------------------------------------
202 #---------------------------------------------------------------------------
206 A LogRecord instance represents an event being logged.
208 LogRecord instances are created every time something is logged. They
209 contain all the information pertinent to the event being logged. The
210 main information passed in is in msg and args, which are combined
211 using str(msg) % args to create the message field of the record. The
212 record also includes information such as when the record was created,
213 the source line where the logging call was made, and any exception
214 information to be logged.
216 def __init__(self
, name
, level
, pathname
, lineno
,
217 msg
, args
, exc_info
, func
=None):
219 Initialize a logging record with interesting information.
225 # The following statement allows passing of a dictionary as a sole
226 # argument, so that you can do something like
227 # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
228 # Suggested by Stefan Behnel.
229 # Note that without the test for args[0], we get a problem because
230 # during formatting, we test to see if the arg is present using
231 # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
232 # and if the passed arg fails 'if self.args:' then no formatting
233 # is done. For example, logger.warn('Value is %d', 0) would log
234 # 'Value is %d' instead of 'Value is 0'.
235 # For the use case of passing a dictionary, this should not be a
237 if args
and (len(args
) == 1) and args
[0] and (type(args
[0]) == types
.DictType
):
240 self
.levelname
= getLevelName(level
)
242 self
.pathname
= pathname
244 self
.filename
= os
.path
.basename(pathname
)
245 self
.module
= os
.path
.splitext(self
.filename
)[0]
246 except (TypeError, ValueError, AttributeError):
247 self
.filename
= pathname
248 self
.module
= "Unknown module"
249 self
.exc_info
= exc_info
250 self
.exc_text
= None # used to cache the traceback text
254 self
.msecs
= (ct
- long(ct
)) * 1000
255 self
.relativeCreated
= (self
.created
- _startTime
) * 1000
256 if logThreads
and thread
:
257 self
.thread
= thread
.get_ident()
258 self
.threadName
= threading
.currentThread().getName()
261 self
.threadName
= None
262 if logProcesses
and hasattr(os
, 'getpid'):
263 self
.process
= os
.getpid()
268 return '<LogRecord: %s, %s, %s, %s, "%s">'%(self
.name
, self
.levelno
,
269 self
.pathname
, self
.lineno
, self
.msg
)
271 def getMessage(self
):
273 Return the message for this LogRecord.
275 Return the message for this LogRecord after merging any user-supplied
276 arguments with the message.
278 if not hasattr(types
, "UnicodeType"): #if no unicode support...
282 if type(msg
) not in (types
.UnicodeType
, types
.StringType
):
286 msg
= self
.msg
#Defer encoding till later
288 msg
= msg
% self
.args
291 def makeLogRecord(dict):
293 Make a LogRecord whose attributes are defined by the specified dictionary,
294 This function is useful for converting a logging event received over
295 a socket connection (which is sent as a dictionary) into a LogRecord
298 rv
= LogRecord(None, None, "", 0, "", (), None, None)
299 rv
.__dict
__.update(dict)
302 #---------------------------------------------------------------------------
303 # Formatter classes and functions
304 #---------------------------------------------------------------------------
308 Formatter instances are used to convert a LogRecord to text.
310 Formatters need to know how a LogRecord is constructed. They are
311 responsible for converting a LogRecord to (usually) a string which can
312 be interpreted by either a human or an external system. The base Formatter
313 allows a formatting string to be specified. If none is supplied, the
314 default value of "%s(message)\\n" is used.
316 The Formatter can be initialized with a format string which makes use of
317 knowledge of the LogRecord attributes - e.g. the default value mentioned
318 above makes use of the fact that the user's message and arguments are pre-
319 formatted into a LogRecord's message attribute. Currently, the useful
320 attributes in a LogRecord are described by:
322 %(name)s Name of the logger (logging channel)
323 %(levelno)s Numeric logging level for the message (DEBUG, INFO,
324 WARNING, ERROR, CRITICAL)
325 %(levelname)s Text logging level for the message ("DEBUG", "INFO",
326 "WARNING", "ERROR", "CRITICAL")
327 %(pathname)s Full pathname of the source file where the logging
328 call was issued (if available)
329 %(filename)s Filename portion of pathname
330 %(module)s Module (name portion of filename)
331 %(lineno)d Source line number where the logging call was issued
333 %(funcName)s Function name
334 %(created)f Time when the LogRecord was created (time.time()
336 %(asctime)s Textual time when the LogRecord was created
337 %(msecs)d Millisecond portion of the creation time
338 %(relativeCreated)d Time in milliseconds when the LogRecord was created,
339 relative to the time the logging module was loaded
340 (typically at application startup time)
341 %(thread)d Thread ID (if available)
342 %(threadName)s Thread name (if available)
343 %(process)d Process ID (if available)
344 %(message)s The result of record.getMessage(), computed just as
345 the record is emitted
348 converter
= time
.localtime
350 def __init__(self
, fmt
=None, datefmt
=None):
352 Initialize the formatter with specified format strings.
354 Initialize the formatter either with the specified format string, or a
355 default as described above. Allow for specialized date formatting with
356 the optional datefmt argument (if omitted, you get the ISO8601 format).
361 self
._fmt
= "%(message)s"
362 self
.datefmt
= datefmt
364 def formatTime(self
, record
, datefmt
=None):
366 Return the creation time of the specified LogRecord as formatted text.
368 This method should be called from format() by a formatter which
369 wants to make use of a formatted time. This method can be overridden
370 in formatters to provide for any specific requirement, but the
371 basic behaviour is as follows: if datefmt (a string) is specified,
372 it is used with time.strftime() to format the creation time of the
373 record. Otherwise, the ISO8601 format is used. The resulting
374 string is returned. This function uses a user-configurable function
375 to convert the creation time to a tuple. By default, time.localtime()
376 is used; to change this for a particular formatter instance, set the
377 'converter' attribute to a function with the same signature as
378 time.localtime() or time.gmtime(). To change it for all formatters,
379 for example if you want all logging times to be shown in GMT,
380 set the 'converter' attribute in the Formatter class.
382 ct
= self
.converter(record
.created
)
384 s
= time
.strftime(datefmt
, ct
)
386 t
= time
.strftime("%Y-%m-%d %H:%M:%S", ct
)
387 s
= "%s,%03d" % (t
, record
.msecs
)
390 def formatException(self
, ei
):
392 Format and return the specified exception information as a string.
394 This default implementation just uses
395 traceback.print_exception()
397 sio
= cStringIO
.StringIO()
398 traceback
.print_exception(ei
[0], ei
[1], ei
[2], None, sio
)
405 def format(self
, record
):
407 Format the specified record as text.
409 The record's attribute dictionary is used as the operand to a
410 string formatting operation which yields the returned string.
411 Before formatting the dictionary, a couple of preparatory steps
412 are carried out. The message attribute of the record is computed
413 using LogRecord.getMessage(). If the formatting string contains
414 "%(asctime)", formatTime() is called to format the event time.
415 If there is exception information, it is formatted using
416 formatException() and appended to the message.
418 record
.message
= record
.getMessage()
419 if string
.find(self
._fmt
,"%(asctime)") >= 0:
420 record
.asctime
= self
.formatTime(record
, self
.datefmt
)
421 s
= self
._fmt
% record
.__dict
__
423 # Cache the traceback text to avoid converting it multiple times
424 # (it's constant anyway)
425 if not record
.exc_text
:
426 record
.exc_text
= self
.formatException(record
.exc_info
)
430 s
= s
+ record
.exc_text
434 # The default formatter to use when no other is specified
436 _defaultFormatter
= Formatter()
438 class BufferingFormatter
:
440 A formatter suitable for formatting a number of records.
442 def __init__(self
, linefmt
=None):
444 Optionally specify a formatter which will be used to format each
448 self
.linefmt
= linefmt
450 self
.linefmt
= _defaultFormatter
452 def formatHeader(self
, records
):
454 Return the header string for the specified records.
458 def formatFooter(self
, records
):
460 Return the footer string for the specified records.
464 def format(self
, records
):
466 Format the specified records and return the result as a string.
470 rv
= rv
+ self
.formatHeader(records
)
471 for record
in records
:
472 rv
= rv
+ self
.linefmt
.format(record
)
473 rv
= rv
+ self
.formatFooter(records
)
476 #---------------------------------------------------------------------------
477 # Filter classes and functions
478 #---------------------------------------------------------------------------
482 Filter instances are used to perform arbitrary filtering of LogRecords.
484 Loggers and Handlers can optionally use Filter instances to filter
485 records as desired. The base filter class only allows events which are
486 below a certain point in the logger hierarchy. For example, a filter
487 initialized with "A.B" will allow events logged by loggers "A.B",
488 "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
489 initialized with the empty string, all events are passed.
491 def __init__(self
, name
=''):
495 Initialize with the name of the logger which, together with its
496 children, will have its events allowed through the filter. If no
497 name is specified, allow every event.
500 self
.nlen
= len(name
)
502 def filter(self
, record
):
504 Determine if the specified record is to be logged.
506 Is the specified record to be logged? Returns 0 for no, nonzero for
507 yes. If deemed appropriate, the record may be modified in-place.
511 elif self
.name
== record
.name
:
513 elif string
.find(record
.name
, self
.name
, 0, self
.nlen
) != 0:
515 return (record
.name
[self
.nlen
] == ".")
519 A base class for loggers and handlers which allows them to share
524 Initialize the list of filters to be an empty list.
528 def addFilter(self
, filter):
530 Add the specified filter to this handler.
532 if not (filter in self
.filters
):
533 self
.filters
.append(filter)
535 def removeFilter(self
, filter):
537 Remove the specified filter from this handler.
539 if filter in self
.filters
:
540 self
.filters
.remove(filter)
542 def filter(self
, record
):
544 Determine if a record is loggable by consulting all the filters.
546 The default is to allow the record to be logged; any filter can veto
547 this and the record is then dropped. Returns a zero value if a record
548 is to be dropped, else non-zero.
551 for f
in self
.filters
:
552 if not f
.filter(record
):
557 #---------------------------------------------------------------------------
558 # Handler classes and functions
559 #---------------------------------------------------------------------------
561 _handlers
= {} #repository of handlers (for flushing when shutdown called)
562 _handlerList
= [] # added to allow handlers to be removed in reverse of order initialized
564 class Handler(Filterer
):
566 Handler instances dispatch logging events to specific destinations.
568 The base handler class. Acts as a placeholder which defines the Handler
569 interface. Handlers can optionally use Formatter instances to format
570 records as desired. By default, no formatter is specified; in this case,
571 the 'raw' message as determined by record.message is logged.
573 def __init__(self
, level
=NOTSET
):
575 Initializes the instance - basically setting the formatter to None
576 and the filter list to empty.
578 Filterer
.__init
__(self
)
580 self
.formatter
= None
581 #get the module data lock, as we're updating a shared structure.
583 try: #unlikely to raise an exception, but you never know...
585 _handlerList
.insert(0, self
)
590 def createLock(self
):
592 Acquire a thread lock for serializing access to the underlying I/O.
595 self
.lock
= threading
.RLock()
601 Acquire the I/O thread lock.
608 Release the I/O thread lock.
613 def setLevel(self
, level
):
615 Set the logging level of this handler.
619 def format(self
, record
):
621 Format the specified record.
623 If a formatter is set, use it. Otherwise, use the default formatter
629 fmt
= _defaultFormatter
630 return fmt
.format(record
)
632 def emit(self
, record
):
634 Do whatever it takes to actually log the specified logging record.
636 This version is intended to be implemented by subclasses and so
637 raises a NotImplementedError.
639 raise NotImplementedError, 'emit must be implemented '\
640 'by Handler subclasses'
642 def handle(self
, record
):
644 Conditionally emit the specified logging record.
646 Emission depends on filters which may have been added to the handler.
647 Wrap the actual emission of the record with acquisition/release of
648 the I/O thread lock. Returns whether the filter passed the record for
651 rv
= self
.filter(record
)
660 def setFormatter(self
, fmt
):
662 Set the formatter for this handler.
668 Ensure all logging output has been flushed.
670 This version does nothing and is intended to be implemented by
677 Tidy up any resources used by the handler.
679 This version does removes the handler from an internal list
680 of handlers which is closed when shutdown() is called. Subclasses
681 should ensure that this gets called from overridden close()
684 #get the module data lock, as we're updating a shared structure.
686 try: #unlikely to raise an exception, but you never know...
688 _handlerList
.remove(self
)
692 def handleError(self
, record
):
694 Handle errors which occur during an emit() call.
696 This method should be called from handlers when an exception is
697 encountered during an emit() call. If raiseExceptions is false,
698 exceptions get silently ignored. This is what is mostly wanted
699 for a logging system - most users will not care about errors in
700 the logging system, they are more interested in application errors.
701 You could, however, replace this with a custom handler if you wish.
702 The record which was being processed is passed in to this method.
706 traceback
.print_exception(ei
[0], ei
[1], ei
[2], None, sys
.stderr
)
709 class StreamHandler(Handler
):
711 A handler class which writes logging records, appropriately formatted,
712 to a stream. Note that this class does not close the stream, as
713 sys.stdout or sys.stderr may be used.
715 def __init__(self
, strm
=None):
717 Initialize the handler.
719 If strm is not specified, sys.stderr is used.
721 Handler
.__init
__(self
)
725 self
.formatter
= None
733 def emit(self
, record
):
737 If a formatter is specified, it is used to format the record.
738 The record is then written to the stream with a trailing newline
739 [N.B. this may be removed depending on feedback]. If exception
740 information is present, it is formatted using
741 traceback.print_exception and appended to the stream.
744 msg
= self
.format(record
)
746 if not hasattr(types
, "UnicodeType"): #if no unicode support...
747 self
.stream
.write(fs
% msg
)
750 self
.stream
.write(fs
% msg
)
752 self
.stream
.write(fs
% msg
.encode("UTF-8"))
754 except (KeyboardInterrupt, SystemExit):
757 self
.handleError(record
)
759 class FileHandler(StreamHandler
):
761 A handler class which writes formatted logging records to disk files.
763 def __init__(self
, filename
, mode
='a', encoding
=None):
765 Open the specified file and use it as the stream for logging.
770 stream
= open(filename
, mode
)
772 stream
= codecs
.open(filename
, mode
, encoding
)
773 StreamHandler
.__init
__(self
, stream
)
774 #keep the absolute path, otherwise derived classes which use this
775 #may come a cropper when the current directory changes
776 self
.baseFilename
= os
.path
.abspath(filename
)
785 StreamHandler
.close(self
)
787 #---------------------------------------------------------------------------
788 # Manager classes and functions
789 #---------------------------------------------------------------------------
793 PlaceHolder instances are used in the Manager logger hierarchy to take
794 the place of nodes for which no loggers have been defined. This class is
795 intended for internal use only and not as part of the public API.
797 def __init__(self
, alogger
):
799 Initialize with the specified logger being a child of this placeholder.
801 #self.loggers = [alogger]
802 self
.loggerMap
= { alogger
: None }
804 def append(self
, alogger
):
806 Add the specified logger as a child of this placeholder.
808 #if alogger not in self.loggers:
809 if not self
.loggerMap
.has_key(alogger
):
810 #self.loggers.append(alogger)
811 self
.loggerMap
[alogger
] = None
814 # Determine which class to use when instantiating loggers.
818 def setLoggerClass(klass
):
820 Set the class to be used when instantiating a logger. The class should
821 define __init__() such that only a name argument is required, and the
822 __init__() should call Logger.__init__()
825 if not issubclass(klass
, Logger
):
826 raise TypeError, "logger not derived from logging.Logger: " + \
831 def getLoggerClass():
833 Return the class to be used when instantiating a logger.
840 There is [under normal circumstances] just one Manager instance, which
841 holds the hierarchy of loggers.
843 def __init__(self
, rootnode
):
845 Initialize the manager with the root node of the logger hierarchy.
849 self
.emittedNoHandlerWarning
= 0
852 def getLogger(self
, name
):
854 Get a logger with the specified name (channel name), creating it
855 if it doesn't yet exist. This name is a dot-separated hierarchical
856 name, such as "a", "a.b", "a.b.c" or similar.
858 If a PlaceHolder existed for the specified name [i.e. the logger
859 didn't exist but a child of it did], replace it with the created
860 logger and fix up the parent/child references which pointed to the
861 placeholder to now point to the logger.
866 if self
.loggerDict
.has_key(name
):
867 rv
= self
.loggerDict
[name
]
868 if isinstance(rv
, PlaceHolder
):
870 rv
= _loggerClass(name
)
872 self
.loggerDict
[name
] = rv
873 self
._fixupChildren
(ph
, rv
)
874 self
._fixupParents
(rv
)
876 rv
= _loggerClass(name
)
878 self
.loggerDict
[name
] = rv
879 self
._fixupParents
(rv
)
884 def _fixupParents(self
, alogger
):
886 Ensure that there are either loggers or placeholders all the way
887 from the specified logger to the root of the logger hierarchy.
890 i
= string
.rfind(name
, ".")
892 while (i
> 0) and not rv
:
894 if not self
.loggerDict
.has_key(substr
):
895 self
.loggerDict
[substr
] = PlaceHolder(alogger
)
897 obj
= self
.loggerDict
[substr
]
898 if isinstance(obj
, Logger
):
901 assert isinstance(obj
, PlaceHolder
)
903 i
= string
.rfind(name
, ".", 0, i
- 1)
908 def _fixupChildren(self
, ph
, alogger
):
910 Ensure that children of the placeholder ph are connected to the
915 for c
in ph
.loggerMap
.keys():
916 #The if means ... if not c.parent.name.startswith(nm)
917 #if string.find(c.parent.name, nm) <> 0:
918 if c
.parent
.name
[:namelen
] != name
:
919 alogger
.parent
= c
.parent
922 #---------------------------------------------------------------------------
923 # Logger classes and functions
924 #---------------------------------------------------------------------------
926 class Logger(Filterer
):
928 Instances of the Logger class represent a single logging channel. A
929 "logging channel" indicates an area of an application. Exactly how an
930 "area" is defined is up to the application developer. Since an
931 application can have any number of areas, logging channels are identified
932 by a unique string. Application areas can be nested (e.g. an area
933 of "input processing" might include sub-areas "read CSV files", "read
934 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
935 channel names are organized into a namespace hierarchy where levels are
936 separated by periods, much like the Java or Python package namespace. So
937 in the instance given above, channel names might be "input" for the upper
938 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
939 There is no arbitrary limit to the depth of nesting.
941 def __init__(self
, name
, level
=NOTSET
):
943 Initialize the logger with a name and an optional level.
945 Filterer
.__init
__(self
)
953 def setLevel(self
, level
):
955 Set the logging level of this logger.
959 def debug(self
, msg
, *args
, **kwargs
):
961 Log 'msg % args' with severity 'DEBUG'.
963 To pass exception information, use the keyword argument exc_info with
966 logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
968 if self
.manager
.disable
>= DEBUG
:
970 if DEBUG
>= self
.getEffectiveLevel():
971 apply(self
._log
, (DEBUG
, msg
, args
), kwargs
)
973 def info(self
, msg
, *args
, **kwargs
):
975 Log 'msg % args' with severity 'INFO'.
977 To pass exception information, use the keyword argument exc_info with
980 logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
982 if self
.manager
.disable
>= INFO
:
984 if INFO
>= self
.getEffectiveLevel():
985 apply(self
._log
, (INFO
, msg
, args
), kwargs
)
987 def warning(self
, msg
, *args
, **kwargs
):
989 Log 'msg % args' with severity 'WARNING'.
991 To pass exception information, use the keyword argument exc_info with
994 logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
996 if self
.manager
.disable
>= WARNING
:
998 if self
.isEnabledFor(WARNING
):
999 apply(self
._log
, (WARNING
, msg
, args
), kwargs
)
1003 def error(self
, msg
, *args
, **kwargs
):
1005 Log 'msg % args' with severity 'ERROR'.
1007 To pass exception information, use the keyword argument exc_info with
1010 logger.error("Houston, we have a %s", "major problem", exc_info=1)
1012 if self
.manager
.disable
>= ERROR
:
1014 if self
.isEnabledFor(ERROR
):
1015 apply(self
._log
, (ERROR
, msg
, args
), kwargs
)
1017 def exception(self
, msg
, *args
):
1019 Convenience method for logging an ERROR with exception information.
1021 apply(self
.error
, (msg
,) + args
, {'exc_info': 1})
1023 def critical(self
, msg
, *args
, **kwargs
):
1025 Log 'msg % args' with severity 'CRITICAL'.
1027 To pass exception information, use the keyword argument exc_info with
1030 logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1032 if self
.manager
.disable
>= CRITICAL
:
1034 if CRITICAL
>= self
.getEffectiveLevel():
1035 apply(self
._log
, (CRITICAL
, msg
, args
), kwargs
)
1039 def log(self
, level
, msg
, *args
, **kwargs
):
1041 Log 'msg % args' with the integer severity 'level'.
1043 To pass exception information, use the keyword argument exc_info with
1046 logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1048 if type(level
) != types
.IntType
:
1050 raise TypeError, "level must be an integer"
1053 if self
.manager
.disable
>= level
:
1055 if self
.isEnabledFor(level
):
1056 apply(self
._log
, (level
, msg
, args
), kwargs
)
1058 def findCaller(self
):
1060 Find the stack frame of the caller so that we can note the source
1061 file name, line number and function name.
1063 f
= currentframe().f_back
1064 rv
= "(unknown file)", 0, "(unknown function)"
1065 while hasattr(f
, "f_code"):
1067 filename
= os
.path
.normcase(co
.co_filename
)
1068 if filename
== _srcfile
:
1071 rv
= (filename
, f
.f_lineno
, co
.co_name
)
1075 def makeRecord(self
, name
, level
, fn
, lno
, msg
, args
, exc_info
, func
=None, extra
=None):
1077 A factory method which can be overridden in subclasses to create
1078 specialized LogRecords.
1080 rv
= LogRecord(name
, level
, fn
, lno
, msg
, args
, exc_info
, func
)
1083 if (key
in ["message", "asctime"]) or (key
in rv
.__dict
__):
1084 raise KeyError("Attempt to overwrite %r in LogRecord" % key
)
1085 rv
.__dict
__[key
] = extra
[key
]
1088 def _log(self
, level
, msg
, args
, exc_info
=None, extra
=None):
1090 Low-level logging routine which creates a LogRecord and then calls
1091 all the handlers of this logger to handle the record.
1094 fn
, lno
, func
= self
.findCaller()
1096 fn
, lno
, func
= "(unknown file)", 0, "(unknown function)"
1098 if type(exc_info
) != types
.TupleType
:
1099 exc_info
= sys
.exc_info()
1100 record
= self
.makeRecord(self
.name
, level
, fn
, lno
, msg
, args
, exc_info
, func
, extra
)
1103 def handle(self
, record
):
1105 Call the handlers for the specified record.
1107 This method is used for unpickled records received from a socket, as
1108 well as those created locally. Logger-level filtering is applied.
1110 if (not self
.disabled
) and self
.filter(record
):
1111 self
.callHandlers(record
)
1113 def addHandler(self
, hdlr
):
1115 Add the specified handler to this logger.
1117 if not (hdlr
in self
.handlers
):
1118 self
.handlers
.append(hdlr
)
1120 def removeHandler(self
, hdlr
):
1122 Remove the specified handler from this logger.
1124 if hdlr
in self
.handlers
:
1128 self
.handlers
.remove(hdlr
)
1132 def callHandlers(self
, record
):
1134 Pass a record to all relevant handlers.
1136 Loop through all handlers for this logger and its parents in the
1137 logger hierarchy. If no handler was found, output a one-off error
1138 message to sys.stderr. Stop searching up the hierarchy whenever a
1139 logger with the "propagate" attribute set to zero is found - that
1140 will be the last logger whose handlers are called.
1145 for hdlr
in c
.handlers
:
1147 if record
.levelno
>= hdlr
.level
:
1153 if (found
== 0) and raiseExceptions
and not self
.manager
.emittedNoHandlerWarning
:
1154 sys
.stderr
.write("No handlers could be found for logger"
1155 " \"%s\"\n" % self
.name
)
1156 self
.manager
.emittedNoHandlerWarning
= 1
1158 def getEffectiveLevel(self
):
1160 Get the effective level for this logger.
1162 Loop through this logger and its parents in the logger hierarchy,
1163 looking for a non-zero logging level. Return the first one found.
1169 logger
= logger
.parent
1172 def isEnabledFor(self
, level
):
1174 Is this logger enabled for level 'level'?
1176 if self
.manager
.disable
>= level
:
1178 return level
>= self
.getEffectiveLevel()
1180 class RootLogger(Logger
):
1182 A root logger is not that different to any other logger, except that
1183 it must have a logging level and there is only one instance of it in
1186 def __init__(self
, level
):
1188 Initialize the logger with the name "root".
1190 Logger
.__init
__(self
, "root", level
)
1192 _loggerClass
= Logger
1194 root
= RootLogger(WARNING
)
1196 Logger
.manager
= Manager(Logger
.root
)
1198 #---------------------------------------------------------------------------
1199 # Configuration classes and functions
1200 #---------------------------------------------------------------------------
1202 BASIC_FORMAT
= "%(levelname)s:%(name)s:%(message)s"
1204 def basicConfig(**kwargs
):
1206 Do basic configuration for the logging system.
1208 This function does nothing if the root logger already has handlers
1209 configured. It is a convenience method intended for use by simple scripts
1210 to do one-shot configuration of the logging package.
1212 The default behaviour is to create a StreamHandler which writes to
1213 sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1214 add the handler to the root logger.
1216 A number of optional keyword arguments may be specified, which can alter
1217 the default behaviour.
1219 filename Specifies that a FileHandler be created, using the specified
1220 filename, rather than a StreamHandler.
1221 filemode Specifies the mode to open the file, if filename is specified
1222 (if filemode is unspecified, it defaults to 'a').
1223 format Use the specified format string for the handler.
1224 datefmt Use the specified date/time format.
1225 level Set the root logger level to the specified level.
1226 stream Use the specified stream to initialize the StreamHandler. Note
1227 that this argument is incompatible with 'filename' - if both
1228 are present, 'stream' is ignored.
1230 Note that you could specify a stream created using open(filename, mode)
1231 rather than passing the filename and mode in. However, it should be
1232 remembered that StreamHandler does not close its stream (since it may be
1233 using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1234 when the handler is closed.
1236 if len(root
.handlers
) == 0:
1237 filename
= kwargs
.get("filename")
1239 mode
= kwargs
.get("filemode", 'a')
1240 hdlr
= FileHandler(filename
, mode
)
1242 stream
= kwargs
.get("stream")
1243 hdlr
= StreamHandler(stream
)
1244 fs
= kwargs
.get("format", BASIC_FORMAT
)
1245 dfs
= kwargs
.get("datefmt", None)
1246 fmt
= Formatter(fs
, dfs
)
1247 hdlr
.setFormatter(fmt
)
1248 root
.addHandler(hdlr
)
1249 level
= kwargs
.get("level")
1251 root
.setLevel(level
)
1253 #---------------------------------------------------------------------------
1254 # Utility functions at module level.
1255 # Basically delegate everything to the root logger.
1256 #---------------------------------------------------------------------------
1258 def getLogger(name
=None):
1260 Return a logger with the specified name, creating it if necessary.
1262 If no name is specified, return the root logger.
1265 return Logger
.manager
.getLogger(name
)
1269 #def getRootLogger():
1271 # Return the root logger.
1273 # Note that getLogger('') now does the same thing, so this function is
1274 # deprecated and may disappear in the future.
1278 def critical(msg
, *args
, **kwargs
):
1280 Log a message with severity 'CRITICAL' on the root logger.
1282 if len(root
.handlers
) == 0:
1284 apply(root
.critical
, (msg
,)+args
, kwargs
)
1288 def error(msg
, *args
, **kwargs
):
1290 Log a message with severity 'ERROR' on the root logger.
1292 if len(root
.handlers
) == 0:
1294 apply(root
.error
, (msg
,)+args
, kwargs
)
1296 def exception(msg
, *args
):
1298 Log a message with severity 'ERROR' on the root logger,
1299 with exception information.
1301 apply(error
, (msg
,)+args
, {'exc_info': 1})
1303 def warning(msg
, *args
, **kwargs
):
1305 Log a message with severity 'WARNING' on the root logger.
1307 if len(root
.handlers
) == 0:
1309 apply(root
.warning
, (msg
,)+args
, kwargs
)
1313 def info(msg
, *args
, **kwargs
):
1315 Log a message with severity 'INFO' on the root logger.
1317 if len(root
.handlers
) == 0:
1319 apply(root
.info
, (msg
,)+args
, kwargs
)
1321 def debug(msg
, *args
, **kwargs
):
1323 Log a message with severity 'DEBUG' on the root logger.
1325 if len(root
.handlers
) == 0:
1327 apply(root
.debug
, (msg
,)+args
, kwargs
)
1329 def log(level
, msg
, *args
, **kwargs
):
1331 Log 'msg % args' with the integer severity 'level' on the root logger.
1333 if len(root
.handlers
) == 0:
1335 apply(root
.log
, (level
, msg
)+args
, kwargs
)
1339 Disable all logging calls less severe than 'level'.
1341 root
.manager
.disable
= level
1343 def shutdown(handlerList
=_handlerList
):
1345 Perform any cleanup actions in the logging system (e.g. flushing
1348 Should be called at application exit.
1350 for h
in handlerList
[:]:
1351 #errors might occur, for example, if files are locked
1352 #we just ignore them if raiseExceptions is not set
1361 #Let's try and shutdown automatically on application exit...
1364 atexit
.register(shutdown
)
1365 except ImportError: # for Python versions < 2.0
1366 def exithook(status
, old_exit
=sys
.exit
):