blob: 4eb0392930763d7fa5d53db885dc04c9c401f620 [file] [log] [blame]
Thomas Wouterscf297e42007-02-23 15:07:44 +00001# Copyright 2001-2007 by Vinay Sajip. All Rights Reserved.
Guido van Rossum57102f82002-11-13 16:15:58 +00002#
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.
Guido van Rossum57102f82002-11-13 16:15:58 +000016
17"""
18Logging package for Python. Based on PEP 282 and comments thereto in
19comp.lang.python, and influenced by Apache's log4j system.
20
21Should work under Python versions >= 1.5.2, except that source line
Jeremy Hylton250684d2003-01-23 18:29:29 +000022information is not available unless 'sys._getframe()' is.
Guido van Rossum57102f82002-11-13 16:15:58 +000023
Thomas Wouterscf297e42007-02-23 15:07:44 +000024Copyright (C) 2001-2007 Vinay Sajip. All Rights Reserved.
Guido van Rossum57102f82002-11-13 16:15:58 +000025
26To use, simply 'import logging' and log away!
27"""
28
Neal Norwitz9d72bb42007-04-17 08:48:32 +000029import sys, os, types, time, cStringIO, traceback
Vinay Sajipb89e7c92005-03-13 09:54:31 +000030
31try:
32 import codecs
33except ImportError:
34 codecs = None
Guido van Rossum57102f82002-11-13 16:15:58 +000035
36try:
37 import thread
38 import threading
39except ImportError:
40 thread = None
Guido van Rossum57102f82002-11-13 16:15:58 +000041
42__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
Thomas Wouters477c8d52006-05-27 19:21:47 +000043__status__ = "production"
Thomas Wouterscf297e42007-02-23 15:07:44 +000044__version__ = "0.5.0.2"
45__date__ = "16 February 2007"
Guido van Rossum57102f82002-11-13 16:15:58 +000046
47#---------------------------------------------------------------------------
48# Miscellaneous module data
49#---------------------------------------------------------------------------
50
51#
Vinay Sajip829dc512005-02-18 11:53:32 +000052# _srcfile is used when walking the stack to check when we've got the first
Guido van Rossum57102f82002-11-13 16:15:58 +000053# caller stack frame.
Neal Norwitz6fa635d2003-02-18 14:20:07 +000054#
Vinay Sajipc384fc22005-09-02 11:20:33 +000055if hasattr(sys, 'frozen'): #support for py2exe
56 _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
Neal Norwitz9d72bb42007-04-17 08:48:32 +000057elif __file__[-4:].lower() in ['.pyc', '.pyo']:
Guido van Rossum455ab772002-11-13 16:18:29 +000058 _srcfile = __file__[:-4] + '.py'
Guido van Rossum57102f82002-11-13 16:15:58 +000059else:
Guido van Rossum455ab772002-11-13 16:18:29 +000060 _srcfile = __file__
61_srcfile = os.path.normcase(_srcfile)
Guido van Rossum57102f82002-11-13 16:15:58 +000062
Vinay Sajip829dc512005-02-18 11:53:32 +000063# next bit filched from 1.5.2's inspect.py
64def currentframe():
65 """Return the frame object for the caller's stack frame."""
66 try:
Neal Norwitz1e8659b2005-10-21 06:00:24 +000067 raise Exception
Vinay Sajip829dc512005-02-18 11:53:32 +000068 except:
69 return sys.exc_traceback.tb_frame.f_back
70
Thomas Wouterscf297e42007-02-23 15:07:44 +000071if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
Vinay Sajip829dc512005-02-18 11:53:32 +000072# done filching
73
Jeremy Hylton250684d2003-01-23 18:29:29 +000074# _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.
Vinay Sajip829dc512005-02-18 11:53:32 +000078#if not hasattr(sys, "_getframe"):
79# _srcfile = None
Jeremy Hylton250684d2003-01-23 18:29:29 +000080
Guido van Rossum57102f82002-11-13 16:15:58 +000081#
82#_startTime is used as the base when calculating the relative time of events
83#
84_startTime = time.time()
85
86#
87#raiseExceptions is used to see if exceptions during handling should be
88#propagated
89#
90raiseExceptions = 1
91
Vinay Sajipd364a072006-03-13 22:05:28 +000092#
93# If you don't want threading information in the log, set this to zero
94#
95logThreads = 1
96
97#
98# If you don't want process information in the log, set this to zero
99#
100logProcesses = 1
101
Guido van Rossum57102f82002-11-13 16:15:58 +0000102#---------------------------------------------------------------------------
103# Level related stuff
104#---------------------------------------------------------------------------
105#
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.
111#
Vinay Sajipb89e7c92005-03-13 09:54:31 +0000112
Guido van Rossum57102f82002-11-13 16:15:58 +0000113CRITICAL = 50
114FATAL = CRITICAL
115ERROR = 40
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000116WARNING = 30
117WARN = WARNING
Guido van Rossum57102f82002-11-13 16:15:58 +0000118INFO = 20
119DEBUG = 10
120NOTSET = 0
121
122_levelNames = {
123 CRITICAL : 'CRITICAL',
124 ERROR : 'ERROR',
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000125 WARNING : 'WARNING',
Guido van Rossum57102f82002-11-13 16:15:58 +0000126 INFO : 'INFO',
127 DEBUG : 'DEBUG',
128 NOTSET : 'NOTSET',
129 'CRITICAL' : CRITICAL,
130 'ERROR' : ERROR,
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000131 'WARN' : WARNING,
132 'WARNING' : WARNING,
Guido van Rossum57102f82002-11-13 16:15:58 +0000133 'INFO' : INFO,
134 'DEBUG' : DEBUG,
135 'NOTSET' : NOTSET,
136}
137
138def getLevelName(level):
139 """
140 Return the textual representation of logging level 'level'.
141
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000142 If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
Guido van Rossum57102f82002-11-13 16:15:58 +0000143 INFO, DEBUG) then you get the corresponding string. If you have
144 associated levels with names using addLevelName then the name you have
Vinay Sajip779e0c92004-07-03 11:47:26 +0000145 associated with 'level' is returned.
146
147 If a numeric value corresponding to one of the defined levels is passed
148 in, the corresponding string representation is returned.
149
150 Otherwise, the string "Level %s" % level is returned.
Guido van Rossum57102f82002-11-13 16:15:58 +0000151 """
152 return _levelNames.get(level, ("Level %s" % level))
153
154def addLevelName(level, levelName):
155 """
156 Associate 'levelName' with 'level'.
157
158 This is used when converting levels to text during message formatting.
159 """
160 _acquireLock()
161 try: #unlikely to cause an exception, but you never know...
162 _levelNames[level] = levelName
163 _levelNames[levelName] = level
164 finally:
165 _releaseLock()
166
167#---------------------------------------------------------------------------
168# Thread-related stuff
169#---------------------------------------------------------------------------
170
171#
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.
178#
179_lock = None
180
181def _acquireLock():
182 """
183 Acquire the module-level lock for serializing access to shared data.
184
185 This should be released with _releaseLock().
186 """
187 global _lock
188 if (not _lock) and thread:
189 _lock = threading.RLock()
190 if _lock:
191 _lock.acquire()
192
193def _releaseLock():
194 """
195 Release the module-level lock acquired by calling _acquireLock().
196 """
197 if _lock:
198 _lock.release()
199
200#---------------------------------------------------------------------------
201# The logging record
202#---------------------------------------------------------------------------
203
204class LogRecord:
205 """
206 A LogRecord instance represents an event being logged.
207
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.
215 """
Vinay Sajiped1992f2006-02-09 08:48:36 +0000216 def __init__(self, name, level, pathname, lineno,
Thomas Wouters89f507f2006-12-13 04:49:30 +0000217 msg, args, exc_info, func=None):
Guido van Rossum57102f82002-11-13 16:15:58 +0000218 """
219 Initialize a logging record with interesting information.
220 """
221 ct = time.time()
222 self.name = name
223 self.msg = msg
Vinay Sajip4ed315a2004-10-20 08:39:40 +0000224 #
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
236 # problem.
Vinay Sajipdccd4322004-10-21 21:24:27 +0000237 if args and (len(args) == 1) and args[0] and (type(args[0]) == types.DictType):
Vinay Sajip4ed315a2004-10-20 08:39:40 +0000238 args = args[0]
Guido van Rossum57102f82002-11-13 16:15:58 +0000239 self.args = args
240 self.levelname = getLevelName(level)
241 self.levelno = level
242 self.pathname = pathname
243 try:
244 self.filename = os.path.basename(pathname)
245 self.module = os.path.splitext(self.filename)[0]
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000246 except (TypeError, ValueError, AttributeError):
Guido van Rossum57102f82002-11-13 16:15:58 +0000247 self.filename = pathname
248 self.module = "Unknown module"
249 self.exc_info = exc_info
Vinay Sajiped6bb142004-02-20 13:18:36 +0000250 self.exc_text = None # used to cache the traceback text
Guido van Rossum57102f82002-11-13 16:15:58 +0000251 self.lineno = lineno
Vinay Sajiped1992f2006-02-09 08:48:36 +0000252 self.funcName = func
Guido van Rossum57102f82002-11-13 16:15:58 +0000253 self.created = ct
Guido van Rossume2a383d2007-01-15 16:59:06 +0000254 self.msecs = (ct - int(ct)) * 1000
Guido van Rossum57102f82002-11-13 16:15:58 +0000255 self.relativeCreated = (self.created - _startTime) * 1000
Vinay Sajipd364a072006-03-13 22:05:28 +0000256 if logThreads and thread:
Guido van Rossum57102f82002-11-13 16:15:58 +0000257 self.thread = thread.get_ident()
Vinay Sajip4a704862005-03-31 20:16:55 +0000258 self.threadName = threading.currentThread().getName()
Guido van Rossum57102f82002-11-13 16:15:58 +0000259 else:
260 self.thread = None
Vinay Sajip4a704862005-03-31 20:16:55 +0000261 self.threadName = None
Vinay Sajipd364a072006-03-13 22:05:28 +0000262 if logProcesses and hasattr(os, 'getpid'):
Jack Jansen4c641d02003-02-21 22:29:45 +0000263 self.process = os.getpid()
264 else:
265 self.process = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000266
267 def __str__(self):
268 return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
269 self.pathname, self.lineno, self.msg)
270
271 def getMessage(self):
272 """
273 Return the message for this LogRecord.
274
275 Return the message for this LogRecord after merging any user-supplied
276 arguments with the message.
277 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000278 if not hasattr(types, "UnicodeType"): #if no unicode support...
279 msg = str(self.msg)
280 else:
Vinay Sajip43d6e812005-10-07 08:35:36 +0000281 msg = self.msg
282 if type(msg) not in (types.UnicodeType, types.StringType):
283 try:
284 msg = str(self.msg)
285 except UnicodeError:
286 msg = self.msg #Defer encoding till later
Guido van Rossum57102f82002-11-13 16:15:58 +0000287 if self.args:
288 msg = msg % self.args
289 return msg
290
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +0000291def makeLogRecord(dict):
292 """
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
296 instance.
297 """
Vinay Sajiped1992f2006-02-09 08:48:36 +0000298 rv = LogRecord(None, None, "", 0, "", (), None, None)
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +0000299 rv.__dict__.update(dict)
300 return rv
301
Guido van Rossum57102f82002-11-13 16:15:58 +0000302#---------------------------------------------------------------------------
303# Formatter classes and functions
304#---------------------------------------------------------------------------
305
306class Formatter:
307 """
308 Formatter instances are used to convert a LogRecord to text.
309
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.
315
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:
321
322 %(name)s Name of the logger (logging channel)
323 %(levelno)s Numeric logging level for the message (DEBUG, INFO,
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000324 WARNING, ERROR, CRITICAL)
Guido van Rossum57102f82002-11-13 16:15:58 +0000325 %(levelname)s Text logging level for the message ("DEBUG", "INFO",
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000326 "WARNING", "ERROR", "CRITICAL")
Guido van Rossum57102f82002-11-13 16:15:58 +0000327 %(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
332 (if available)
Vinay Sajiped1992f2006-02-09 08:48:36 +0000333 %(funcName)s Function name
Guido van Rossum57102f82002-11-13 16:15:58 +0000334 %(created)f Time when the LogRecord was created (time.time()
335 return value)
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)
Vinay Sajip4a704862005-03-31 20:16:55 +0000342 %(threadName)s Thread name (if available)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000343 %(process)d Process ID (if available)
Guido van Rossum57102f82002-11-13 16:15:58 +0000344 %(message)s The result of record.getMessage(), computed just as
345 the record is emitted
346 """
347
348 converter = time.localtime
349
350 def __init__(self, fmt=None, datefmt=None):
351 """
352 Initialize the formatter with specified format strings.
353
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).
357 """
358 if fmt:
359 self._fmt = fmt
360 else:
361 self._fmt = "%(message)s"
362 self.datefmt = datefmt
363
364 def formatTime(self, record, datefmt=None):
365 """
366 Return the creation time of the specified LogRecord as formatted text.
367
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.
381 """
382 ct = self.converter(record.created)
383 if datefmt:
384 s = time.strftime(datefmt, ct)
385 else:
386 t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
387 s = "%s,%03d" % (t, record.msecs)
388 return s
389
390 def formatException(self, ei):
391 """
392 Format and return the specified exception information as a string.
393
394 This default implementation just uses
395 traceback.print_exception()
396 """
Guido van Rossum57102f82002-11-13 16:15:58 +0000397 sio = cStringIO.StringIO()
398 traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
399 s = sio.getvalue()
400 sio.close()
401 if s[-1] == "\n":
402 s = s[:-1]
403 return s
404
405 def format(self, record):
406 """
407 Format the specified record as text.
408
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.
417 """
418 record.message = record.getMessage()
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000419 if self._fmt.find("%(asctime)") >= 0:
Guido van Rossum57102f82002-11-13 16:15:58 +0000420 record.asctime = self.formatTime(record, self.datefmt)
421 s = self._fmt % record.__dict__
422 if record.exc_info:
Vinay Sajiped6bb142004-02-20 13:18:36 +0000423 # 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)
427 if record.exc_text:
Guido van Rossum57102f82002-11-13 16:15:58 +0000428 if s[-1] != "\n":
429 s = s + "\n"
Vinay Sajiped6bb142004-02-20 13:18:36 +0000430 s = s + record.exc_text
Guido van Rossum57102f82002-11-13 16:15:58 +0000431 return s
432
433#
434# The default formatter to use when no other is specified
435#
436_defaultFormatter = Formatter()
437
438class BufferingFormatter:
439 """
440 A formatter suitable for formatting a number of records.
441 """
442 def __init__(self, linefmt=None):
443 """
444 Optionally specify a formatter which will be used to format each
445 individual record.
446 """
447 if linefmt:
448 self.linefmt = linefmt
449 else:
450 self.linefmt = _defaultFormatter
451
452 def formatHeader(self, records):
453 """
454 Return the header string for the specified records.
455 """
456 return ""
457
458 def formatFooter(self, records):
459 """
460 Return the footer string for the specified records.
461 """
462 return ""
463
464 def format(self, records):
465 """
466 Format the specified records and return the result as a string.
467 """
468 rv = ""
469 if len(records) > 0:
470 rv = rv + self.formatHeader(records)
471 for record in records:
472 rv = rv + self.linefmt.format(record)
473 rv = rv + self.formatFooter(records)
474 return rv
475
476#---------------------------------------------------------------------------
477# Filter classes and functions
478#---------------------------------------------------------------------------
479
480class Filter:
481 """
482 Filter instances are used to perform arbitrary filtering of LogRecords.
483
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.
490 """
491 def __init__(self, name=''):
492 """
493 Initialize a filter.
494
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.
498 """
499 self.name = name
500 self.nlen = len(name)
501
502 def filter(self, record):
503 """
504 Determine if the specified record is to be logged.
505
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.
508 """
509 if self.nlen == 0:
510 return 1
511 elif self.name == record.name:
512 return 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000513 elif record.name.find(self.name, 0, self.nlen) != 0:
Guido van Rossum57102f82002-11-13 16:15:58 +0000514 return 0
515 return (record.name[self.nlen] == ".")
516
517class Filterer:
518 """
519 A base class for loggers and handlers which allows them to share
520 common code.
521 """
522 def __init__(self):
523 """
524 Initialize the list of filters to be an empty list.
525 """
526 self.filters = []
527
528 def addFilter(self, filter):
529 """
530 Add the specified filter to this handler.
531 """
532 if not (filter in self.filters):
533 self.filters.append(filter)
534
535 def removeFilter(self, filter):
536 """
537 Remove the specified filter from this handler.
538 """
539 if filter in self.filters:
540 self.filters.remove(filter)
541
542 def filter(self, record):
543 """
544 Determine if a record is loggable by consulting all the filters.
545
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.
549 """
550 rv = 1
551 for f in self.filters:
552 if not f.filter(record):
553 rv = 0
554 break
555 return rv
556
557#---------------------------------------------------------------------------
558# Handler classes and functions
559#---------------------------------------------------------------------------
560
561_handlers = {} #repository of handlers (for flushing when shutdown called)
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000562_handlerList = [] # added to allow handlers to be removed in reverse of order initialized
Guido van Rossum57102f82002-11-13 16:15:58 +0000563
564class Handler(Filterer):
565 """
566 Handler instances dispatch logging events to specific destinations.
567
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.
572 """
573 def __init__(self, level=NOTSET):
574 """
575 Initializes the instance - basically setting the formatter to None
576 and the filter list to empty.
577 """
578 Filterer.__init__(self)
579 self.level = level
580 self.formatter = None
581 #get the module data lock, as we're updating a shared structure.
582 _acquireLock()
583 try: #unlikely to raise an exception, but you never know...
584 _handlers[self] = 1
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000585 _handlerList.insert(0, self)
Guido van Rossum57102f82002-11-13 16:15:58 +0000586 finally:
587 _releaseLock()
588 self.createLock()
589
590 def createLock(self):
591 """
592 Acquire a thread lock for serializing access to the underlying I/O.
593 """
594 if thread:
Vinay Sajip4a704862005-03-31 20:16:55 +0000595 self.lock = threading.RLock()
Guido van Rossum57102f82002-11-13 16:15:58 +0000596 else:
597 self.lock = None
598
599 def acquire(self):
600 """
601 Acquire the I/O thread lock.
602 """
603 if self.lock:
604 self.lock.acquire()
605
606 def release(self):
607 """
608 Release the I/O thread lock.
609 """
610 if self.lock:
611 self.lock.release()
612
613 def setLevel(self, level):
614 """
615 Set the logging level of this handler.
616 """
617 self.level = level
618
619 def format(self, record):
620 """
621 Format the specified record.
622
623 If a formatter is set, use it. Otherwise, use the default formatter
624 for the module.
625 """
626 if self.formatter:
627 fmt = self.formatter
628 else:
629 fmt = _defaultFormatter
630 return fmt.format(record)
631
632 def emit(self, record):
633 """
634 Do whatever it takes to actually log the specified logging record.
635
636 This version is intended to be implemented by subclasses and so
637 raises a NotImplementedError.
638 """
639 raise NotImplementedError, 'emit must be implemented '\
640 'by Handler subclasses'
641
642 def handle(self, record):
643 """
644 Conditionally emit the specified logging record.
645
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
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000648 the I/O thread lock. Returns whether the filter passed the record for
649 emission.
Guido van Rossum57102f82002-11-13 16:15:58 +0000650 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000651 rv = self.filter(record)
652 if rv:
Guido van Rossum57102f82002-11-13 16:15:58 +0000653 self.acquire()
654 try:
655 self.emit(record)
656 finally:
657 self.release()
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000658 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +0000659
660 def setFormatter(self, fmt):
661 """
662 Set the formatter for this handler.
663 """
664 self.formatter = fmt
665
666 def flush(self):
667 """
668 Ensure all logging output has been flushed.
669
670 This version does nothing and is intended to be implemented by
671 subclasses.
672 """
673 pass
674
675 def close(self):
676 """
677 Tidy up any resources used by the handler.
678
Vinay Sajiped6bb142004-02-20 13:18:36 +0000679 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()
682 methods.
Guido van Rossum57102f82002-11-13 16:15:58 +0000683 """
Vinay Sajiped6bb142004-02-20 13:18:36 +0000684 #get the module data lock, as we're updating a shared structure.
685 _acquireLock()
686 try: #unlikely to raise an exception, but you never know...
Vinay Sajipe0f85922006-02-07 13:55:52 +0000687 del _handlers[self]
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000688 _handlerList.remove(self)
Vinay Sajiped6bb142004-02-20 13:18:36 +0000689 finally:
690 _releaseLock()
Guido van Rossum57102f82002-11-13 16:15:58 +0000691
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000692 def handleError(self, record):
Guido van Rossum57102f82002-11-13 16:15:58 +0000693 """
694 Handle errors which occur during an emit() call.
695
696 This method should be called from handlers when an exception is
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000697 encountered during an emit() call. If raiseExceptions is false,
Guido van Rossum57102f82002-11-13 16:15:58 +0000698 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.
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000702 The record which was being processed is passed in to this method.
Guido van Rossum57102f82002-11-13 16:15:58 +0000703 """
704 if raiseExceptions:
Guido van Rossum57102f82002-11-13 16:15:58 +0000705 ei = sys.exc_info()
706 traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
707 del ei
708
709class StreamHandler(Handler):
710 """
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.
714 """
715 def __init__(self, strm=None):
716 """
717 Initialize the handler.
718
719 If strm is not specified, sys.stderr is used.
720 """
721 Handler.__init__(self)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000722 if strm is None:
Guido van Rossum57102f82002-11-13 16:15:58 +0000723 strm = sys.stderr
724 self.stream = strm
725 self.formatter = None
726
727 def flush(self):
728 """
729 Flushes the stream.
730 """
731 self.stream.flush()
732
733 def emit(self, record):
734 """
735 Emit a record.
736
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.
742 """
743 try:
744 msg = self.format(record)
Vinay Sajipb9591172004-09-22 12:39:26 +0000745 fs = "%s\n"
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000746 if not hasattr(types, "UnicodeType"): #if no unicode support...
Vinay Sajipb9591172004-09-22 12:39:26 +0000747 self.stream.write(fs % msg)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000748 else:
749 try:
Vinay Sajipb9591172004-09-22 12:39:26 +0000750 self.stream.write(fs % msg)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000751 except UnicodeError:
Vinay Sajipb9591172004-09-22 12:39:26 +0000752 self.stream.write(fs % msg.encode("UTF-8"))
Guido van Rossum57102f82002-11-13 16:15:58 +0000753 self.flush()
Vinay Sajip85c19092005-10-31 13:14:19 +0000754 except (KeyboardInterrupt, SystemExit):
755 raise
Guido van Rossum57102f82002-11-13 16:15:58 +0000756 except:
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000757 self.handleError(record)
Guido van Rossum57102f82002-11-13 16:15:58 +0000758
759class FileHandler(StreamHandler):
760 """
761 A handler class which writes formatted logging records to disk files.
762 """
Vinay Sajipb89e7c92005-03-13 09:54:31 +0000763 def __init__(self, filename, mode='a', encoding=None):
Guido van Rossum57102f82002-11-13 16:15:58 +0000764 """
765 Open the specified file and use it as the stream for logging.
766 """
Vinay Sajip4bbab2b2004-07-08 10:22:35 +0000767 #keep the absolute path, otherwise derived classes which use this
768 #may come a cropper when the current directory changes
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000769 if codecs is None:
770 encoding = None
Vinay Sajip4bbab2b2004-07-08 10:22:35 +0000771 self.baseFilename = os.path.abspath(filename)
Guido van Rossum57102f82002-11-13 16:15:58 +0000772 self.mode = mode
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000773 self.encoding = encoding
774 stream = self._open()
775 StreamHandler.__init__(self, stream)
Guido van Rossum57102f82002-11-13 16:15:58 +0000776
777 def close(self):
778 """
779 Closes the stream.
780 """
Vinay Sajip3f9f84d2004-02-21 22:12:32 +0000781 self.flush()
Guido van Rossum57102f82002-11-13 16:15:58 +0000782 self.stream.close()
Vinay Sajiped6bb142004-02-20 13:18:36 +0000783 StreamHandler.close(self)
Guido van Rossum57102f82002-11-13 16:15:58 +0000784
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000785 def _open(self):
786 """
787 Open the current base file with the (original) mode and encoding.
788 Return the resulting stream.
789 """
790 if self.encoding is None:
791 stream = open(self.baseFilename, self.mode)
792 else:
793 stream = codecs.open(self.baseFilename, self.mode, self.encoding)
794 return stream
795
Guido van Rossum57102f82002-11-13 16:15:58 +0000796#---------------------------------------------------------------------------
797# Manager classes and functions
798#---------------------------------------------------------------------------
799
800class PlaceHolder:
801 """
802 PlaceHolder instances are used in the Manager logger hierarchy to take
Vinay Sajip3f742842004-02-28 16:07:46 +0000803 the place of nodes for which no loggers have been defined. This class is
804 intended for internal use only and not as part of the public API.
Guido van Rossum57102f82002-11-13 16:15:58 +0000805 """
806 def __init__(self, alogger):
807 """
808 Initialize with the specified logger being a child of this placeholder.
809 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000810 #self.loggers = [alogger]
811 self.loggerMap = { alogger : None }
Guido van Rossum57102f82002-11-13 16:15:58 +0000812
813 def append(self, alogger):
814 """
815 Add the specified logger as a child of this placeholder.
816 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000817 #if alogger not in self.loggers:
Guido van Rossum93662412006-08-19 16:09:41 +0000818 if alogger not in self.loggerMap:
Vinay Sajip239322b2005-10-14 09:36:35 +0000819 #self.loggers.append(alogger)
820 self.loggerMap[alogger] = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000821
822#
823# Determine which class to use when instantiating loggers.
824#
825_loggerClass = None
826
827def setLoggerClass(klass):
828 """
829 Set the class to be used when instantiating a logger. The class should
830 define __init__() such that only a name argument is required, and the
831 __init__() should call Logger.__init__()
832 """
833 if klass != Logger:
Guido van Rossum57102f82002-11-13 16:15:58 +0000834 if not issubclass(klass, Logger):
835 raise TypeError, "logger not derived from logging.Logger: " + \
836 klass.__name__
837 global _loggerClass
838 _loggerClass = klass
839
Vinay Sajipb9591172004-09-22 12:39:26 +0000840def getLoggerClass():
841 """
842 Return the class to be used when instantiating a logger.
843 """
844
845 return _loggerClass
846
Guido van Rossum57102f82002-11-13 16:15:58 +0000847class Manager:
848 """
849 There is [under normal circumstances] just one Manager instance, which
850 holds the hierarchy of loggers.
851 """
Neal Norwitzd1cade02002-11-15 23:31:28 +0000852 def __init__(self, rootnode):
Guido van Rossum57102f82002-11-13 16:15:58 +0000853 """
854 Initialize the manager with the root node of the logger hierarchy.
855 """
Neal Norwitzd1cade02002-11-15 23:31:28 +0000856 self.root = rootnode
Guido van Rossum57102f82002-11-13 16:15:58 +0000857 self.disable = 0
858 self.emittedNoHandlerWarning = 0
859 self.loggerDict = {}
860
861 def getLogger(self, name):
862 """
863 Get a logger with the specified name (channel name), creating it
Vinay Sajipb9591172004-09-22 12:39:26 +0000864 if it doesn't yet exist. This name is a dot-separated hierarchical
865 name, such as "a", "a.b", "a.b.c" or similar.
Guido van Rossum57102f82002-11-13 16:15:58 +0000866
867 If a PlaceHolder existed for the specified name [i.e. the logger
868 didn't exist but a child of it did], replace it with the created
869 logger and fix up the parent/child references which pointed to the
870 placeholder to now point to the logger.
871 """
872 rv = None
873 _acquireLock()
874 try:
Guido van Rossum93662412006-08-19 16:09:41 +0000875 if name in self.loggerDict:
Guido van Rossum57102f82002-11-13 16:15:58 +0000876 rv = self.loggerDict[name]
877 if isinstance(rv, PlaceHolder):
878 ph = rv
879 rv = _loggerClass(name)
880 rv.manager = self
881 self.loggerDict[name] = rv
882 self._fixupChildren(ph, rv)
883 self._fixupParents(rv)
884 else:
885 rv = _loggerClass(name)
886 rv.manager = self
887 self.loggerDict[name] = rv
888 self._fixupParents(rv)
889 finally:
890 _releaseLock()
891 return rv
892
893 def _fixupParents(self, alogger):
894 """
895 Ensure that there are either loggers or placeholders all the way
896 from the specified logger to the root of the logger hierarchy.
897 """
898 name = alogger.name
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000899 i = name.rfind(".")
Guido van Rossum57102f82002-11-13 16:15:58 +0000900 rv = None
901 while (i > 0) and not rv:
902 substr = name[:i]
Guido van Rossum93662412006-08-19 16:09:41 +0000903 if substr not in self.loggerDict:
Guido van Rossum57102f82002-11-13 16:15:58 +0000904 self.loggerDict[substr] = PlaceHolder(alogger)
905 else:
906 obj = self.loggerDict[substr]
907 if isinstance(obj, Logger):
908 rv = obj
909 else:
910 assert isinstance(obj, PlaceHolder)
911 obj.append(alogger)
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000912 i = name.rfind(".", 0, i - 1)
Guido van Rossum57102f82002-11-13 16:15:58 +0000913 if not rv:
914 rv = self.root
915 alogger.parent = rv
916
917 def _fixupChildren(self, ph, alogger):
918 """
919 Ensure that children of the placeholder ph are connected to the
920 specified logger.
921 """
Thomas Wouters89f507f2006-12-13 04:49:30 +0000922 name = alogger.name
923 namelen = len(name)
Vinay Sajip239322b2005-10-14 09:36:35 +0000924 for c in ph.loggerMap.keys():
Thomas Wouters89f507f2006-12-13 04:49:30 +0000925 #The if means ... if not c.parent.name.startswith(nm)
926 if c.parent.name[:namelen] != name:
Guido van Rossum57102f82002-11-13 16:15:58 +0000927 alogger.parent = c.parent
928 c.parent = alogger
929
930#---------------------------------------------------------------------------
931# Logger classes and functions
932#---------------------------------------------------------------------------
933
934class Logger(Filterer):
935 """
936 Instances of the Logger class represent a single logging channel. A
937 "logging channel" indicates an area of an application. Exactly how an
938 "area" is defined is up to the application developer. Since an
939 application can have any number of areas, logging channels are identified
940 by a unique string. Application areas can be nested (e.g. an area
941 of "input processing" might include sub-areas "read CSV files", "read
942 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
943 channel names are organized into a namespace hierarchy where levels are
944 separated by periods, much like the Java or Python package namespace. So
945 in the instance given above, channel names might be "input" for the upper
946 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
947 There is no arbitrary limit to the depth of nesting.
948 """
949 def __init__(self, name, level=NOTSET):
950 """
951 Initialize the logger with a name and an optional level.
952 """
953 Filterer.__init__(self)
954 self.name = name
955 self.level = level
956 self.parent = None
957 self.propagate = 1
958 self.handlers = []
959 self.disabled = 0
960
961 def setLevel(self, level):
962 """
963 Set the logging level of this logger.
964 """
965 self.level = level
966
Guido van Rossum57102f82002-11-13 16:15:58 +0000967 def debug(self, msg, *args, **kwargs):
968 """
969 Log 'msg % args' with severity 'DEBUG'.
970
971 To pass exception information, use the keyword argument exc_info with
972 a true value, e.g.
973
974 logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
975 """
976 if self.manager.disable >= DEBUG:
977 return
978 if DEBUG >= self.getEffectiveLevel():
Neal Norwitzd9108552006-03-17 08:00:19 +0000979 self._log(DEBUG, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +0000980
981 def info(self, msg, *args, **kwargs):
982 """
983 Log 'msg % args' with severity 'INFO'.
984
985 To pass exception information, use the keyword argument exc_info with
986 a true value, e.g.
987
988 logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
989 """
990 if self.manager.disable >= INFO:
991 return
992 if INFO >= self.getEffectiveLevel():
Neal Norwitzd9108552006-03-17 08:00:19 +0000993 self._log(INFO, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +0000994
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000995 def warning(self, msg, *args, **kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +0000996 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000997 Log 'msg % args' with severity 'WARNING'.
Guido van Rossum57102f82002-11-13 16:15:58 +0000998
999 To pass exception information, use the keyword argument exc_info with
1000 a true value, e.g.
1001
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001002 logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
Guido van Rossum57102f82002-11-13 16:15:58 +00001003 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001004 if self.manager.disable >= WARNING:
Guido van Rossum57102f82002-11-13 16:15:58 +00001005 return
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001006 if self.isEnabledFor(WARNING):
Neal Norwitzd9108552006-03-17 08:00:19 +00001007 self._log(WARNING, msg, args, **kwargs)
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001008
1009 warn = warning
Guido van Rossum57102f82002-11-13 16:15:58 +00001010
1011 def error(self, msg, *args, **kwargs):
1012 """
1013 Log 'msg % args' with severity 'ERROR'.
1014
1015 To pass exception information, use the keyword argument exc_info with
1016 a true value, e.g.
1017
1018 logger.error("Houston, we have a %s", "major problem", exc_info=1)
1019 """
1020 if self.manager.disable >= ERROR:
1021 return
1022 if self.isEnabledFor(ERROR):
Neal Norwitzd9108552006-03-17 08:00:19 +00001023 self._log(ERROR, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001024
1025 def exception(self, msg, *args):
1026 """
1027 Convenience method for logging an ERROR with exception information.
1028 """
Neal Norwitz7c307242006-03-17 08:28:24 +00001029 self.error(msg, exc_info=1, *args)
Guido van Rossum57102f82002-11-13 16:15:58 +00001030
1031 def critical(self, msg, *args, **kwargs):
1032 """
1033 Log 'msg % args' with severity 'CRITICAL'.
1034
1035 To pass exception information, use the keyword argument exc_info with
1036 a true value, e.g.
1037
1038 logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1039 """
1040 if self.manager.disable >= CRITICAL:
1041 return
1042 if CRITICAL >= self.getEffectiveLevel():
Neal Norwitzd9108552006-03-17 08:00:19 +00001043 self._log(CRITICAL, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001044
1045 fatal = critical
1046
1047 def log(self, level, msg, *args, **kwargs):
1048 """
Vinay Sajipeb477d02004-08-04 08:38:08 +00001049 Log 'msg % args' with the integer severity 'level'.
Guido van Rossum57102f82002-11-13 16:15:58 +00001050
1051 To pass exception information, use the keyword argument exc_info with
1052 a true value, e.g.
1053
1054 logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1055 """
Vinay Sajip779e0c92004-07-03 11:47:26 +00001056 if type(level) != types.IntType:
1057 if raiseExceptions:
1058 raise TypeError, "level must be an integer"
1059 else:
1060 return
Guido van Rossum57102f82002-11-13 16:15:58 +00001061 if self.manager.disable >= level:
1062 return
1063 if self.isEnabledFor(level):
Neal Norwitzd9108552006-03-17 08:00:19 +00001064 self._log(level, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001065
1066 def findCaller(self):
1067 """
1068 Find the stack frame of the caller so that we can note the source
Vinay Sajip829dc512005-02-18 11:53:32 +00001069 file name, line number and function name.
Guido van Rossum57102f82002-11-13 16:15:58 +00001070 """
Vinay Sajip829dc512005-02-18 11:53:32 +00001071 f = currentframe().f_back
Thomas Woutersa9773292006-04-21 09:43:23 +00001072 rv = "(unknown file)", 0, "(unknown function)"
1073 while hasattr(f, "f_code"):
Jeremy Hylton250684d2003-01-23 18:29:29 +00001074 co = f.f_code
1075 filename = os.path.normcase(co.co_filename)
1076 if filename == _srcfile:
1077 f = f.f_back
1078 continue
Thomas Woutersa9773292006-04-21 09:43:23 +00001079 rv = (filename, f.f_lineno, co.co_name)
1080 break
1081 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +00001082
Vinay Sajiped1992f2006-02-09 08:48:36 +00001083 def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
Guido van Rossum57102f82002-11-13 16:15:58 +00001084 """
1085 A factory method which can be overridden in subclasses to create
1086 specialized LogRecords.
1087 """
Vinay Sajiped1992f2006-02-09 08:48:36 +00001088 rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
Vinay Sajip260ce432006-02-09 08:34:14 +00001089 if extra:
1090 for key in extra:
1091 if (key in ["message", "asctime"]) or (key in rv.__dict__):
1092 raise KeyError("Attempt to overwrite %r in LogRecord" % key)
1093 rv.__dict__[key] = extra[key]
1094 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +00001095
Vinay Sajip260ce432006-02-09 08:34:14 +00001096 def _log(self, level, msg, args, exc_info=None, extra=None):
Guido van Rossum57102f82002-11-13 16:15:58 +00001097 """
1098 Low-level logging routine which creates a LogRecord and then calls
1099 all the handlers of this logger to handle the record.
1100 """
Jeremy Hylton250684d2003-01-23 18:29:29 +00001101 if _srcfile:
Vinay Sajip829dc512005-02-18 11:53:32 +00001102 fn, lno, func = self.findCaller()
Guido van Rossum57102f82002-11-13 16:15:58 +00001103 else:
Vinay Sajip829dc512005-02-18 11:53:32 +00001104 fn, lno, func = "(unknown file)", 0, "(unknown function)"
Guido van Rossum57102f82002-11-13 16:15:58 +00001105 if exc_info:
Vinay Sajiped6bb142004-02-20 13:18:36 +00001106 if type(exc_info) != types.TupleType:
1107 exc_info = sys.exc_info()
Vinay Sajiped1992f2006-02-09 08:48:36 +00001108 record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
Guido van Rossum57102f82002-11-13 16:15:58 +00001109 self.handle(record)
1110
1111 def handle(self, record):
1112 """
1113 Call the handlers for the specified record.
1114
1115 This method is used for unpickled records received from a socket, as
1116 well as those created locally. Logger-level filtering is applied.
1117 """
1118 if (not self.disabled) and self.filter(record):
1119 self.callHandlers(record)
1120
1121 def addHandler(self, hdlr):
1122 """
1123 Add the specified handler to this logger.
1124 """
1125 if not (hdlr in self.handlers):
1126 self.handlers.append(hdlr)
1127
1128 def removeHandler(self, hdlr):
1129 """
1130 Remove the specified handler from this logger.
1131 """
1132 if hdlr in self.handlers:
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001133 #hdlr.close()
Vinay Sajip116f16e2005-09-16 10:33:40 +00001134 hdlr.acquire()
1135 try:
1136 self.handlers.remove(hdlr)
1137 finally:
1138 hdlr.release()
Guido van Rossum57102f82002-11-13 16:15:58 +00001139
1140 def callHandlers(self, record):
1141 """
1142 Pass a record to all relevant handlers.
1143
1144 Loop through all handlers for this logger and its parents in the
1145 logger hierarchy. If no handler was found, output a one-off error
1146 message to sys.stderr. Stop searching up the hierarchy whenever a
1147 logger with the "propagate" attribute set to zero is found - that
1148 will be the last logger whose handlers are called.
1149 """
1150 c = self
1151 found = 0
1152 while c:
1153 for hdlr in c.handlers:
1154 found = found + 1
1155 if record.levelno >= hdlr.level:
1156 hdlr.handle(record)
1157 if not c.propagate:
1158 c = None #break out
1159 else:
1160 c = c.parent
Vinay Sajip1e86beb2005-10-23 22:32:59 +00001161 if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
Guido van Rossum57102f82002-11-13 16:15:58 +00001162 sys.stderr.write("No handlers could be found for logger"
1163 " \"%s\"\n" % self.name)
1164 self.manager.emittedNoHandlerWarning = 1
1165
1166 def getEffectiveLevel(self):
1167 """
1168 Get the effective level for this logger.
1169
1170 Loop through this logger and its parents in the logger hierarchy,
1171 looking for a non-zero logging level. Return the first one found.
1172 """
1173 logger = self
1174 while logger:
1175 if logger.level:
1176 return logger.level
1177 logger = logger.parent
1178 return NOTSET
1179
1180 def isEnabledFor(self, level):
1181 """
1182 Is this logger enabled for level 'level'?
1183 """
1184 if self.manager.disable >= level:
1185 return 0
1186 return level >= self.getEffectiveLevel()
1187
1188class RootLogger(Logger):
1189 """
1190 A root logger is not that different to any other logger, except that
1191 it must have a logging level and there is only one instance of it in
1192 the hierarchy.
1193 """
1194 def __init__(self, level):
1195 """
1196 Initialize the logger with the name "root".
1197 """
1198 Logger.__init__(self, "root", level)
1199
1200_loggerClass = Logger
1201
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001202root = RootLogger(WARNING)
Guido van Rossum57102f82002-11-13 16:15:58 +00001203Logger.root = root
1204Logger.manager = Manager(Logger.root)
1205
1206#---------------------------------------------------------------------------
1207# Configuration classes and functions
1208#---------------------------------------------------------------------------
1209
1210BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
1211
Vinay Sajip779e0c92004-07-03 11:47:26 +00001212def basicConfig(**kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001213 """
Vinay Sajip779e0c92004-07-03 11:47:26 +00001214 Do basic configuration for the logging system.
1215
1216 This function does nothing if the root logger already has handlers
1217 configured. It is a convenience method intended for use by simple scripts
1218 to do one-shot configuration of the logging package.
1219
1220 The default behaviour is to create a StreamHandler which writes to
1221 sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1222 add the handler to the root logger.
1223
1224 A number of optional keyword arguments may be specified, which can alter
1225 the default behaviour.
1226
1227 filename Specifies that a FileHandler be created, using the specified
1228 filename, rather than a StreamHandler.
1229 filemode Specifies the mode to open the file, if filename is specified
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001230 (if filemode is unspecified, it defaults to 'a').
Vinay Sajip779e0c92004-07-03 11:47:26 +00001231 format Use the specified format string for the handler.
1232 datefmt Use the specified date/time format.
1233 level Set the root logger level to the specified level.
1234 stream Use the specified stream to initialize the StreamHandler. Note
1235 that this argument is incompatible with 'filename' - if both
1236 are present, 'stream' is ignored.
1237
1238 Note that you could specify a stream created using open(filename, mode)
1239 rather than passing the filename and mode in. However, it should be
1240 remembered that StreamHandler does not close its stream (since it may be
1241 using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1242 when the handler is closed.
Guido van Rossum57102f82002-11-13 16:15:58 +00001243 """
1244 if len(root.handlers) == 0:
Vinay Sajip779e0c92004-07-03 11:47:26 +00001245 filename = kwargs.get("filename")
1246 if filename:
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001247 mode = kwargs.get("filemode", 'a')
Vinay Sajip779e0c92004-07-03 11:47:26 +00001248 hdlr = FileHandler(filename, mode)
1249 else:
1250 stream = kwargs.get("stream")
1251 hdlr = StreamHandler(stream)
1252 fs = kwargs.get("format", BASIC_FORMAT)
1253 dfs = kwargs.get("datefmt", None)
1254 fmt = Formatter(fs, dfs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001255 hdlr.setFormatter(fmt)
1256 root.addHandler(hdlr)
Vinay Sajip779e0c92004-07-03 11:47:26 +00001257 level = kwargs.get("level")
1258 if level:
Tim Peters4e0e1b62004-07-07 20:54:48 +00001259 root.setLevel(level)
Guido van Rossum57102f82002-11-13 16:15:58 +00001260
1261#---------------------------------------------------------------------------
1262# Utility functions at module level.
1263# Basically delegate everything to the root logger.
1264#---------------------------------------------------------------------------
1265
1266def getLogger(name=None):
1267 """
1268 Return a logger with the specified name, creating it if necessary.
1269
1270 If no name is specified, return the root logger.
1271 """
1272 if name:
1273 return Logger.manager.getLogger(name)
1274 else:
1275 return root
1276
1277#def getRootLogger():
1278# """
1279# Return the root logger.
1280#
1281# Note that getLogger('') now does the same thing, so this function is
1282# deprecated and may disappear in the future.
1283# """
1284# return root
1285
1286def critical(msg, *args, **kwargs):
1287 """
1288 Log a message with severity 'CRITICAL' on the root logger.
1289 """
1290 if len(root.handlers) == 0:
1291 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001292 root.critical(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001293
1294fatal = critical
1295
1296def error(msg, *args, **kwargs):
1297 """
1298 Log a message with severity 'ERROR' on the root logger.
1299 """
1300 if len(root.handlers) == 0:
1301 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001302 root.error(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001303
1304def exception(msg, *args):
1305 """
1306 Log a message with severity 'ERROR' on the root logger,
1307 with exception information.
1308 """
Neal Norwitz7c307242006-03-17 08:28:24 +00001309 error(msg, exc_info=1, *args)
Guido van Rossum57102f82002-11-13 16:15:58 +00001310
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001311def warning(msg, *args, **kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001312 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001313 Log a message with severity 'WARNING' on the root logger.
Guido van Rossum57102f82002-11-13 16:15:58 +00001314 """
1315 if len(root.handlers) == 0:
1316 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001317 root.warning(msg, *args, **kwargs)
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001318
1319warn = warning
Guido van Rossum57102f82002-11-13 16:15:58 +00001320
1321def info(msg, *args, **kwargs):
1322 """
1323 Log a message with severity 'INFO' on the root logger.
1324 """
1325 if len(root.handlers) == 0:
1326 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001327 root.info(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001328
1329def debug(msg, *args, **kwargs):
1330 """
1331 Log a message with severity 'DEBUG' on the root logger.
1332 """
1333 if len(root.handlers) == 0:
1334 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001335 root.debug(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001336
Vinay Sajipb2635b22004-09-24 11:45:52 +00001337def log(level, msg, *args, **kwargs):
1338 """
1339 Log 'msg % args' with the integer severity 'level' on the root logger.
1340 """
1341 if len(root.handlers) == 0:
1342 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001343 root.log(level, msg, *args, **kwargs)
Vinay Sajipb2635b22004-09-24 11:45:52 +00001344
Guido van Rossum57102f82002-11-13 16:15:58 +00001345def disable(level):
1346 """
1347 Disable all logging calls less severe than 'level'.
1348 """
1349 root.manager.disable = level
1350
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001351def shutdown(handlerList=_handlerList):
Guido van Rossum57102f82002-11-13 16:15:58 +00001352 """
1353 Perform any cleanup actions in the logging system (e.g. flushing
1354 buffers).
1355
1356 Should be called at application exit.
1357 """
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001358 for h in handlerList[:]:
Vinay Sajipe12f7152004-07-29 09:19:30 +00001359 #errors might occur, for example, if files are locked
Vinay Sajip260ce432006-02-09 08:34:14 +00001360 #we just ignore them if raiseExceptions is not set
Vinay Sajipe12f7152004-07-29 09:19:30 +00001361 try:
1362 h.flush()
1363 h.close()
1364 except:
Vinay Sajip260ce432006-02-09 08:34:14 +00001365 if raiseExceptions:
1366 raise
1367 #else, swallow
Vinay Sajiped6bb142004-02-20 13:18:36 +00001368
1369#Let's try and shutdown automatically on application exit...
1370try:
1371 import atexit
1372 atexit.register(shutdown)
1373except ImportError: # for Python versions < 2.0
1374 def exithook(status, old_exit=sys.exit):
1375 try:
1376 shutdown()
1377 finally:
1378 old_exit(status)
1379
1380 sys.exit = exithook