blob: fecca2b14c5bfb898a2aac1b55c5fa5b038fc986 [file] [log] [blame]
Vinay Sajipb672b6d2009-02-19 12:36:11 +00001# Copyright 2001-2009 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
Vinay Sajip6268cbc2009-01-21 00:19:28 +000021Copyright (C) 2001-2009 Vinay Sajip. All Rights Reserved.
Guido van Rossum57102f82002-11-13 16:15:58 +000022
23To use, simply 'import logging' and log away!
24"""
25
Georg Brandlf9734072008-12-07 15:30:06 +000026import sys, os, time, io, traceback, warnings
27
Christian Heimes18c66892008-02-17 13:31:39 +000028__all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
Vinay Sajipad5fa2f2009-04-27 13:55:05 +000029 'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO',
30 'LogRecord', 'Logger', 'LoggerAdapter', 'NOTSET', 'NullHandler',
31 'StreamHandler', 'WARN', 'WARNING', 'addLevelName', 'basicConfig',
32 'captureWarnings', 'critical', 'debug', 'disable', 'error',
33 'exception', 'fatal', 'getLevelName', 'getLogger', 'getLoggerClass',
34 'info', 'log', 'makeLogRecord', 'setLoggerClass', 'warn', 'warning']
Vinay Sajipb89e7c92005-03-13 09:54:31 +000035
36try:
37 import codecs
38except ImportError:
39 codecs = None
Guido van Rossum57102f82002-11-13 16:15:58 +000040
41try:
Georg Brandl2067bfd2008-05-25 13:05:15 +000042 import _thread as thread
Guido van Rossum57102f82002-11-13 16:15:58 +000043 import threading
44except ImportError:
45 thread = None
Guido van Rossum57102f82002-11-13 16:15:58 +000046
47__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
Thomas Wouters477c8d52006-05-27 19:21:47 +000048__status__ = "production"
Vinay Sajip6268cbc2009-01-21 00:19:28 +000049__version__ = "0.5.0.7"
50__date__ = "20 January 2009"
Guido van Rossum57102f82002-11-13 16:15:58 +000051
52#---------------------------------------------------------------------------
53# Miscellaneous module data
54#---------------------------------------------------------------------------
55
Guido van Rossum13257902007-06-07 23:15:56 +000056_unicode = 'unicode' in dir(__builtins__)
57
Guido van Rossum57102f82002-11-13 16:15:58 +000058#
Vinay Sajip829dc512005-02-18 11:53:32 +000059# _srcfile is used when walking the stack to check when we've got the first
Guido van Rossum57102f82002-11-13 16:15:58 +000060# caller stack frame.
Neal Norwitz6fa635d2003-02-18 14:20:07 +000061#
Vinay Sajipc384fc22005-09-02 11:20:33 +000062if hasattr(sys, 'frozen'): #support for py2exe
63 _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
Neal Norwitz9d72bb42007-04-17 08:48:32 +000064elif __file__[-4:].lower() in ['.pyc', '.pyo']:
Guido van Rossum455ab772002-11-13 16:18:29 +000065 _srcfile = __file__[:-4] + '.py'
Guido van Rossum57102f82002-11-13 16:15:58 +000066else:
Guido van Rossum455ab772002-11-13 16:18:29 +000067 _srcfile = __file__
68_srcfile = os.path.normcase(_srcfile)
Guido van Rossum57102f82002-11-13 16:15:58 +000069
Vinay Sajip829dc512005-02-18 11:53:32 +000070# next bit filched from 1.5.2's inspect.py
71def currentframe():
72 """Return the frame object for the caller's stack frame."""
73 try:
Neal Norwitz1e8659b2005-10-21 06:00:24 +000074 raise Exception
Vinay Sajip829dc512005-02-18 11:53:32 +000075 except:
Guido van Rossume7ba4952007-06-06 23:52:48 +000076 return sys.exc_info()[2].tb_frame.f_back
Vinay Sajip829dc512005-02-18 11:53:32 +000077
Thomas Wouterscf297e42007-02-23 15:07:44 +000078if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
Vinay Sajip829dc512005-02-18 11:53:32 +000079# done filching
80
Jeremy Hylton250684d2003-01-23 18:29:29 +000081# _srcfile is only used in conjunction with sys._getframe().
82# To provide compatibility with older versions of Python, set _srcfile
83# to None if _getframe() is not available; this value will prevent
84# findCaller() from being called.
Vinay Sajip829dc512005-02-18 11:53:32 +000085#if not hasattr(sys, "_getframe"):
86# _srcfile = None
Jeremy Hylton250684d2003-01-23 18:29:29 +000087
Guido van Rossum57102f82002-11-13 16:15:58 +000088#
89#_startTime is used as the base when calculating the relative time of events
90#
91_startTime = time.time()
92
93#
94#raiseExceptions is used to see if exceptions during handling should be
95#propagated
96#
97raiseExceptions = 1
98
Vinay Sajipd364a072006-03-13 22:05:28 +000099#
100# If you don't want threading information in the log, set this to zero
101#
102logThreads = 1
103
104#
Jesse Noller9a0fc972009-01-18 21:12:58 +0000105# If you don't want multiprocessing information in the log, set this to zero
106#
107logMultiprocessing = 1
108
109#
Vinay Sajipd364a072006-03-13 22:05:28 +0000110# If you don't want process information in the log, set this to zero
111#
112logProcesses = 1
113
Guido van Rossum57102f82002-11-13 16:15:58 +0000114#---------------------------------------------------------------------------
115# Level related stuff
116#---------------------------------------------------------------------------
117#
118# Default levels and level names, these can be replaced with any positive set
119# of values having corresponding names. There is a pseudo-level, NOTSET, which
120# is only really there as a lower limit for user-defined levels. Handlers and
121# loggers are initialized with NOTSET so that they will log all messages, even
122# at user-defined levels.
123#
Vinay Sajipb89e7c92005-03-13 09:54:31 +0000124
Guido van Rossum57102f82002-11-13 16:15:58 +0000125CRITICAL = 50
126FATAL = CRITICAL
127ERROR = 40
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000128WARNING = 30
129WARN = WARNING
Guido van Rossum57102f82002-11-13 16:15:58 +0000130INFO = 20
131DEBUG = 10
132NOTSET = 0
133
134_levelNames = {
135 CRITICAL : 'CRITICAL',
136 ERROR : 'ERROR',
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000137 WARNING : 'WARNING',
Guido van Rossum57102f82002-11-13 16:15:58 +0000138 INFO : 'INFO',
139 DEBUG : 'DEBUG',
140 NOTSET : 'NOTSET',
141 'CRITICAL' : CRITICAL,
142 'ERROR' : ERROR,
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000143 'WARN' : WARNING,
144 'WARNING' : WARNING,
Guido van Rossum57102f82002-11-13 16:15:58 +0000145 'INFO' : INFO,
146 'DEBUG' : DEBUG,
147 'NOTSET' : NOTSET,
148}
149
150def getLevelName(level):
151 """
152 Return the textual representation of logging level 'level'.
153
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000154 If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
Guido van Rossum57102f82002-11-13 16:15:58 +0000155 INFO, DEBUG) then you get the corresponding string. If you have
156 associated levels with names using addLevelName then the name you have
Vinay Sajip779e0c92004-07-03 11:47:26 +0000157 associated with 'level' is returned.
158
159 If a numeric value corresponding to one of the defined levels is passed
160 in, the corresponding string representation is returned.
161
162 Otherwise, the string "Level %s" % level is returned.
Guido van Rossum57102f82002-11-13 16:15:58 +0000163 """
164 return _levelNames.get(level, ("Level %s" % level))
165
166def addLevelName(level, levelName):
167 """
168 Associate 'levelName' with 'level'.
169
170 This is used when converting levels to text during message formatting.
171 """
172 _acquireLock()
173 try: #unlikely to cause an exception, but you never know...
174 _levelNames[level] = levelName
175 _levelNames[levelName] = level
176 finally:
177 _releaseLock()
178
179#---------------------------------------------------------------------------
180# Thread-related stuff
181#---------------------------------------------------------------------------
182
183#
184#_lock is used to serialize access to shared data structures in this module.
185#This needs to be an RLock because fileConfig() creates Handlers and so
186#might arbitrary user threads. Since Handler.__init__() updates the shared
187#dictionary _handlers, it needs to acquire the lock. But if configuring,
188#the lock would already have been acquired - so we need an RLock.
189#The same argument applies to Loggers and Manager.loggerDict.
190#
191_lock = None
192
193def _acquireLock():
194 """
195 Acquire the module-level lock for serializing access to shared data.
196
197 This should be released with _releaseLock().
198 """
199 global _lock
200 if (not _lock) and thread:
201 _lock = threading.RLock()
202 if _lock:
203 _lock.acquire()
204
205def _releaseLock():
206 """
207 Release the module-level lock acquired by calling _acquireLock().
208 """
209 if _lock:
210 _lock.release()
211
212#---------------------------------------------------------------------------
213# The logging record
214#---------------------------------------------------------------------------
215
216class LogRecord:
217 """
218 A LogRecord instance represents an event being logged.
219
220 LogRecord instances are created every time something is logged. They
221 contain all the information pertinent to the event being logged. The
222 main information passed in is in msg and args, which are combined
223 using str(msg) % args to create the message field of the record. The
224 record also includes information such as when the record was created,
225 the source line where the logging call was made, and any exception
226 information to be logged.
227 """
Vinay Sajiped1992f2006-02-09 08:48:36 +0000228 def __init__(self, name, level, pathname, lineno,
Thomas Wouters89f507f2006-12-13 04:49:30 +0000229 msg, args, exc_info, func=None):
Guido van Rossum57102f82002-11-13 16:15:58 +0000230 """
231 Initialize a logging record with interesting information.
232 """
233 ct = time.time()
234 self.name = name
235 self.msg = msg
Vinay Sajip4ed315a2004-10-20 08:39:40 +0000236 #
237 # The following statement allows passing of a dictionary as a sole
238 # argument, so that you can do something like
239 # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
240 # Suggested by Stefan Behnel.
241 # Note that without the test for args[0], we get a problem because
242 # during formatting, we test to see if the arg is present using
243 # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
244 # and if the passed arg fails 'if self.args:' then no formatting
245 # is done. For example, logger.warn('Value is %d', 0) would log
246 # 'Value is %d' instead of 'Value is 0'.
247 # For the use case of passing a dictionary, this should not be a
248 # problem.
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000249 if args and len(args) == 1 and isinstance(args[0], dict) and args[0]:
Vinay Sajip4ed315a2004-10-20 08:39:40 +0000250 args = args[0]
Guido van Rossum57102f82002-11-13 16:15:58 +0000251 self.args = args
252 self.levelname = getLevelName(level)
253 self.levelno = level
254 self.pathname = pathname
255 try:
256 self.filename = os.path.basename(pathname)
257 self.module = os.path.splitext(self.filename)[0]
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000258 except (TypeError, ValueError, AttributeError):
Guido van Rossum57102f82002-11-13 16:15:58 +0000259 self.filename = pathname
260 self.module = "Unknown module"
261 self.exc_info = exc_info
Vinay Sajiped6bb142004-02-20 13:18:36 +0000262 self.exc_text = None # used to cache the traceback text
Guido van Rossum57102f82002-11-13 16:15:58 +0000263 self.lineno = lineno
Vinay Sajiped1992f2006-02-09 08:48:36 +0000264 self.funcName = func
Guido van Rossum57102f82002-11-13 16:15:58 +0000265 self.created = ct
Guido van Rossume2a383d2007-01-15 16:59:06 +0000266 self.msecs = (ct - int(ct)) * 1000
Guido van Rossum57102f82002-11-13 16:15:58 +0000267 self.relativeCreated = (self.created - _startTime) * 1000
Vinay Sajipd364a072006-03-13 22:05:28 +0000268 if logThreads and thread:
Guido van Rossum57102f82002-11-13 16:15:58 +0000269 self.thread = thread.get_ident()
Benjamin Peterson72753702008-08-18 18:09:21 +0000270 self.threadName = threading.current_thread().name
Guido van Rossum57102f82002-11-13 16:15:58 +0000271 else:
272 self.thread = None
Vinay Sajip4a704862005-03-31 20:16:55 +0000273 self.threadName = None
Benjamin Petersonf3d7dbe2009-10-04 14:54:52 +0000274 if not logMultiprocessing:
Jesse Noller9a0fc972009-01-18 21:12:58 +0000275 self.processName = None
Benjamin Petersonf3d7dbe2009-10-04 14:54:52 +0000276 else:
277 try:
278 from multiprocessing import current_process
279 self.processName = current_process().name
280 except ImportError:
281 self.processName = None
Vinay Sajipd364a072006-03-13 22:05:28 +0000282 if logProcesses and hasattr(os, 'getpid'):
Jack Jansen4c641d02003-02-21 22:29:45 +0000283 self.process = os.getpid()
284 else:
285 self.process = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000286
287 def __str__(self):
288 return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
289 self.pathname, self.lineno, self.msg)
290
291 def getMessage(self):
292 """
293 Return the message for this LogRecord.
294
295 Return the message for this LogRecord after merging any user-supplied
296 arguments with the message.
297 """
Guido van Rossum13257902007-06-07 23:15:56 +0000298 if not _unicode: #if no unicode support...
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000299 msg = str(self.msg)
300 else:
Vinay Sajip43d6e812005-10-07 08:35:36 +0000301 msg = self.msg
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000302 if not isinstance(msg, str):
Vinay Sajip43d6e812005-10-07 08:35:36 +0000303 try:
304 msg = str(self.msg)
305 except UnicodeError:
306 msg = self.msg #Defer encoding till later
Guido van Rossum57102f82002-11-13 16:15:58 +0000307 if self.args:
308 msg = msg % self.args
309 return msg
310
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +0000311def makeLogRecord(dict):
312 """
313 Make a LogRecord whose attributes are defined by the specified dictionary,
314 This function is useful for converting a logging event received over
315 a socket connection (which is sent as a dictionary) into a LogRecord
316 instance.
317 """
Vinay Sajiped1992f2006-02-09 08:48:36 +0000318 rv = LogRecord(None, None, "", 0, "", (), None, None)
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +0000319 rv.__dict__.update(dict)
320 return rv
321
Guido van Rossum57102f82002-11-13 16:15:58 +0000322#---------------------------------------------------------------------------
323# Formatter classes and functions
324#---------------------------------------------------------------------------
325
326class Formatter:
327 """
328 Formatter instances are used to convert a LogRecord to text.
329
330 Formatters need to know how a LogRecord is constructed. They are
331 responsible for converting a LogRecord to (usually) a string which can
332 be interpreted by either a human or an external system. The base Formatter
333 allows a formatting string to be specified. If none is supplied, the
334 default value of "%s(message)\\n" is used.
335
336 The Formatter can be initialized with a format string which makes use of
337 knowledge of the LogRecord attributes - e.g. the default value mentioned
338 above makes use of the fact that the user's message and arguments are pre-
339 formatted into a LogRecord's message attribute. Currently, the useful
340 attributes in a LogRecord are described by:
341
342 %(name)s Name of the logger (logging channel)
343 %(levelno)s Numeric logging level for the message (DEBUG, INFO,
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000344 WARNING, ERROR, CRITICAL)
Guido van Rossum57102f82002-11-13 16:15:58 +0000345 %(levelname)s Text logging level for the message ("DEBUG", "INFO",
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000346 "WARNING", "ERROR", "CRITICAL")
Guido van Rossum57102f82002-11-13 16:15:58 +0000347 %(pathname)s Full pathname of the source file where the logging
348 call was issued (if available)
349 %(filename)s Filename portion of pathname
350 %(module)s Module (name portion of filename)
351 %(lineno)d Source line number where the logging call was issued
352 (if available)
Vinay Sajiped1992f2006-02-09 08:48:36 +0000353 %(funcName)s Function name
Guido van Rossum57102f82002-11-13 16:15:58 +0000354 %(created)f Time when the LogRecord was created (time.time()
355 return value)
356 %(asctime)s Textual time when the LogRecord was created
357 %(msecs)d Millisecond portion of the creation time
358 %(relativeCreated)d Time in milliseconds when the LogRecord was created,
359 relative to the time the logging module was loaded
360 (typically at application startup time)
361 %(thread)d Thread ID (if available)
Vinay Sajip4a704862005-03-31 20:16:55 +0000362 %(threadName)s Thread name (if available)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000363 %(process)d Process ID (if available)
Guido van Rossum57102f82002-11-13 16:15:58 +0000364 %(message)s The result of record.getMessage(), computed just as
365 the record is emitted
366 """
367
368 converter = time.localtime
369
370 def __init__(self, fmt=None, datefmt=None):
371 """
372 Initialize the formatter with specified format strings.
373
374 Initialize the formatter either with the specified format string, or a
375 default as described above. Allow for specialized date formatting with
376 the optional datefmt argument (if omitted, you get the ISO8601 format).
377 """
378 if fmt:
379 self._fmt = fmt
380 else:
381 self._fmt = "%(message)s"
382 self.datefmt = datefmt
383
384 def formatTime(self, record, datefmt=None):
385 """
386 Return the creation time of the specified LogRecord as formatted text.
387
388 This method should be called from format() by a formatter which
389 wants to make use of a formatted time. This method can be overridden
390 in formatters to provide for any specific requirement, but the
391 basic behaviour is as follows: if datefmt (a string) is specified,
392 it is used with time.strftime() to format the creation time of the
393 record. Otherwise, the ISO8601 format is used. The resulting
394 string is returned. This function uses a user-configurable function
395 to convert the creation time to a tuple. By default, time.localtime()
396 is used; to change this for a particular formatter instance, set the
397 'converter' attribute to a function with the same signature as
398 time.localtime() or time.gmtime(). To change it for all formatters,
399 for example if you want all logging times to be shown in GMT,
400 set the 'converter' attribute in the Formatter class.
401 """
402 ct = self.converter(record.created)
403 if datefmt:
404 s = time.strftime(datefmt, ct)
405 else:
406 t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
407 s = "%s,%03d" % (t, record.msecs)
408 return s
409
410 def formatException(self, ei):
411 """
412 Format and return the specified exception information as a string.
413
414 This default implementation just uses
415 traceback.print_exception()
416 """
Guido van Rossum34d19282007-08-09 01:03:29 +0000417 sio = io.StringIO()
Guido van Rossum57102f82002-11-13 16:15:58 +0000418 traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
419 s = sio.getvalue()
420 sio.close()
Guido van Rossum486364b2007-06-30 05:01:58 +0000421 if s[-1:] == "\n":
Guido van Rossum57102f82002-11-13 16:15:58 +0000422 s = s[:-1]
423 return s
424
425 def format(self, record):
426 """
427 Format the specified record as text.
428
429 The record's attribute dictionary is used as the operand to a
430 string formatting operation which yields the returned string.
431 Before formatting the dictionary, a couple of preparatory steps
432 are carried out. The message attribute of the record is computed
433 using LogRecord.getMessage(). If the formatting string contains
434 "%(asctime)", formatTime() is called to format the event time.
435 If there is exception information, it is formatted using
436 formatException() and appended to the message.
437 """
438 record.message = record.getMessage()
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000439 if self._fmt.find("%(asctime)") >= 0:
Guido van Rossum57102f82002-11-13 16:15:58 +0000440 record.asctime = self.formatTime(record, self.datefmt)
441 s = self._fmt % record.__dict__
442 if record.exc_info:
Vinay Sajiped6bb142004-02-20 13:18:36 +0000443 # Cache the traceback text to avoid converting it multiple times
444 # (it's constant anyway)
445 if not record.exc_text:
446 record.exc_text = self.formatException(record.exc_info)
447 if record.exc_text:
Guido van Rossum486364b2007-06-30 05:01:58 +0000448 if s[-1:] != "\n":
Guido van Rossum57102f82002-11-13 16:15:58 +0000449 s = s + "\n"
Vinay Sajiped6bb142004-02-20 13:18:36 +0000450 s = s + record.exc_text
Guido van Rossum57102f82002-11-13 16:15:58 +0000451 return s
452
453#
454# The default formatter to use when no other is specified
455#
456_defaultFormatter = Formatter()
457
458class BufferingFormatter:
459 """
460 A formatter suitable for formatting a number of records.
461 """
462 def __init__(self, linefmt=None):
463 """
464 Optionally specify a formatter which will be used to format each
465 individual record.
466 """
467 if linefmt:
468 self.linefmt = linefmt
469 else:
470 self.linefmt = _defaultFormatter
471
472 def formatHeader(self, records):
473 """
474 Return the header string for the specified records.
475 """
476 return ""
477
478 def formatFooter(self, records):
479 """
480 Return the footer string for the specified records.
481 """
482 return ""
483
484 def format(self, records):
485 """
486 Format the specified records and return the result as a string.
487 """
488 rv = ""
489 if len(records) > 0:
490 rv = rv + self.formatHeader(records)
491 for record in records:
492 rv = rv + self.linefmt.format(record)
493 rv = rv + self.formatFooter(records)
494 return rv
495
496#---------------------------------------------------------------------------
497# Filter classes and functions
498#---------------------------------------------------------------------------
499
500class Filter:
501 """
502 Filter instances are used to perform arbitrary filtering of LogRecords.
503
504 Loggers and Handlers can optionally use Filter instances to filter
505 records as desired. The base filter class only allows events which are
506 below a certain point in the logger hierarchy. For example, a filter
507 initialized with "A.B" will allow events logged by loggers "A.B",
508 "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
509 initialized with the empty string, all events are passed.
510 """
511 def __init__(self, name=''):
512 """
513 Initialize a filter.
514
515 Initialize with the name of the logger which, together with its
516 children, will have its events allowed through the filter. If no
517 name is specified, allow every event.
518 """
519 self.name = name
520 self.nlen = len(name)
521
522 def filter(self, record):
523 """
524 Determine if the specified record is to be logged.
525
526 Is the specified record to be logged? Returns 0 for no, nonzero for
527 yes. If deemed appropriate, the record may be modified in-place.
528 """
529 if self.nlen == 0:
530 return 1
531 elif self.name == record.name:
532 return 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000533 elif record.name.find(self.name, 0, self.nlen) != 0:
Guido van Rossum57102f82002-11-13 16:15:58 +0000534 return 0
535 return (record.name[self.nlen] == ".")
536
537class Filterer:
538 """
539 A base class for loggers and handlers which allows them to share
540 common code.
541 """
542 def __init__(self):
543 """
544 Initialize the list of filters to be an empty list.
545 """
546 self.filters = []
547
548 def addFilter(self, filter):
549 """
550 Add the specified filter to this handler.
551 """
552 if not (filter in self.filters):
553 self.filters.append(filter)
554
555 def removeFilter(self, filter):
556 """
557 Remove the specified filter from this handler.
558 """
559 if filter in self.filters:
560 self.filters.remove(filter)
561
562 def filter(self, record):
563 """
564 Determine if a record is loggable by consulting all the filters.
565
566 The default is to allow the record to be logged; any filter can veto
567 this and the record is then dropped. Returns a zero value if a record
568 is to be dropped, else non-zero.
569 """
570 rv = 1
571 for f in self.filters:
572 if not f.filter(record):
573 rv = 0
574 break
575 return rv
576
577#---------------------------------------------------------------------------
578# Handler classes and functions
579#---------------------------------------------------------------------------
580
581_handlers = {} #repository of handlers (for flushing when shutdown called)
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000582_handlerList = [] # added to allow handlers to be removed in reverse of order initialized
Guido van Rossum57102f82002-11-13 16:15:58 +0000583
584class Handler(Filterer):
585 """
586 Handler instances dispatch logging events to specific destinations.
587
588 The base handler class. Acts as a placeholder which defines the Handler
589 interface. Handlers can optionally use Formatter instances to format
590 records as desired. By default, no formatter is specified; in this case,
591 the 'raw' message as determined by record.message is logged.
592 """
593 def __init__(self, level=NOTSET):
594 """
595 Initializes the instance - basically setting the formatter to None
596 and the filter list to empty.
597 """
598 Filterer.__init__(self)
599 self.level = level
600 self.formatter = None
601 #get the module data lock, as we're updating a shared structure.
602 _acquireLock()
603 try: #unlikely to raise an exception, but you never know...
604 _handlers[self] = 1
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000605 _handlerList.insert(0, self)
Guido van Rossum57102f82002-11-13 16:15:58 +0000606 finally:
607 _releaseLock()
608 self.createLock()
609
610 def createLock(self):
611 """
612 Acquire a thread lock for serializing access to the underlying I/O.
613 """
614 if thread:
Vinay Sajip4a704862005-03-31 20:16:55 +0000615 self.lock = threading.RLock()
Guido van Rossum57102f82002-11-13 16:15:58 +0000616 else:
617 self.lock = None
618
619 def acquire(self):
620 """
621 Acquire the I/O thread lock.
622 """
623 if self.lock:
624 self.lock.acquire()
625
626 def release(self):
627 """
628 Release the I/O thread lock.
629 """
630 if self.lock:
631 self.lock.release()
632
633 def setLevel(self, level):
634 """
635 Set the logging level of this handler.
636 """
637 self.level = level
638
639 def format(self, record):
640 """
641 Format the specified record.
642
643 If a formatter is set, use it. Otherwise, use the default formatter
644 for the module.
645 """
646 if self.formatter:
647 fmt = self.formatter
648 else:
649 fmt = _defaultFormatter
650 return fmt.format(record)
651
652 def emit(self, record):
653 """
654 Do whatever it takes to actually log the specified logging record.
655
656 This version is intended to be implemented by subclasses and so
657 raises a NotImplementedError.
658 """
Collin Winterce36ad82007-08-30 01:19:48 +0000659 raise NotImplementedError('emit must be implemented '
660 'by Handler subclasses')
Guido van Rossum57102f82002-11-13 16:15:58 +0000661
662 def handle(self, record):
663 """
664 Conditionally emit the specified logging record.
665
666 Emission depends on filters which may have been added to the handler.
667 Wrap the actual emission of the record with acquisition/release of
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000668 the I/O thread lock. Returns whether the filter passed the record for
669 emission.
Guido van Rossum57102f82002-11-13 16:15:58 +0000670 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000671 rv = self.filter(record)
672 if rv:
Guido van Rossum57102f82002-11-13 16:15:58 +0000673 self.acquire()
674 try:
675 self.emit(record)
676 finally:
677 self.release()
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000678 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +0000679
680 def setFormatter(self, fmt):
681 """
682 Set the formatter for this handler.
683 """
684 self.formatter = fmt
685
686 def flush(self):
687 """
688 Ensure all logging output has been flushed.
689
690 This version does nothing and is intended to be implemented by
691 subclasses.
692 """
693 pass
694
695 def close(self):
696 """
697 Tidy up any resources used by the handler.
698
Vinay Sajiped6bb142004-02-20 13:18:36 +0000699 This version does removes the handler from an internal list
700 of handlers which is closed when shutdown() is called. Subclasses
701 should ensure that this gets called from overridden close()
702 methods.
Guido van Rossum57102f82002-11-13 16:15:58 +0000703 """
Vinay Sajiped6bb142004-02-20 13:18:36 +0000704 #get the module data lock, as we're updating a shared structure.
705 _acquireLock()
706 try: #unlikely to raise an exception, but you never know...
Vinay Sajipe0f85922006-02-07 13:55:52 +0000707 del _handlers[self]
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000708 _handlerList.remove(self)
Vinay Sajiped6bb142004-02-20 13:18:36 +0000709 finally:
710 _releaseLock()
Guido van Rossum57102f82002-11-13 16:15:58 +0000711
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000712 def handleError(self, record):
Guido van Rossum57102f82002-11-13 16:15:58 +0000713 """
714 Handle errors which occur during an emit() call.
715
716 This method should be called from handlers when an exception is
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000717 encountered during an emit() call. If raiseExceptions is false,
Guido van Rossum57102f82002-11-13 16:15:58 +0000718 exceptions get silently ignored. This is what is mostly wanted
719 for a logging system - most users will not care about errors in
720 the logging system, they are more interested in application errors.
721 You could, however, replace this with a custom handler if you wish.
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000722 The record which was being processed is passed in to this method.
Guido van Rossum57102f82002-11-13 16:15:58 +0000723 """
724 if raiseExceptions:
Guido van Rossum57102f82002-11-13 16:15:58 +0000725 ei = sys.exc_info()
Benjamin Petersonfa0d7032009-06-01 22:42:33 +0000726 try:
727 traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
728 except IOError:
729 pass # see issue 5971
730 finally:
731 del ei
Guido van Rossum57102f82002-11-13 16:15:58 +0000732
733class StreamHandler(Handler):
734 """
735 A handler class which writes logging records, appropriately formatted,
736 to a stream. Note that this class does not close the stream, as
737 sys.stdout or sys.stderr may be used.
738 """
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000739
Benjamin Petersonf3d7dbe2009-10-04 14:54:52 +0000740 def __init__(self, stream=None):
Guido van Rossum57102f82002-11-13 16:15:58 +0000741 """
742 Initialize the handler.
743
Benjamin Petersonf3d7dbe2009-10-04 14:54:52 +0000744 If stream is not specified, sys.stderr is used.
Guido van Rossum57102f82002-11-13 16:15:58 +0000745 """
746 Handler.__init__(self)
Benjamin Petersonf3d7dbe2009-10-04 14:54:52 +0000747 if stream is None:
748 stream = sys.stderr
749 self.stream = stream
Guido van Rossum57102f82002-11-13 16:15:58 +0000750
751 def flush(self):
752 """
753 Flushes the stream.
754 """
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +0000755 if self.stream and hasattr(self.stream, "flush"):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000756 self.stream.flush()
Guido van Rossum57102f82002-11-13 16:15:58 +0000757
758 def emit(self, record):
759 """
760 Emit a record.
761
762 If a formatter is specified, it is used to format the record.
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000763 The record is then written to the stream with a trailing newline. If
764 exception information is present, it is formatted using
765 traceback.print_exception and appended to the stream. If the stream
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000766 has an 'encoding' attribute, it is used to determine how to do the
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000767 output to the stream.
Guido van Rossum57102f82002-11-13 16:15:58 +0000768 """
769 try:
770 msg = self.format(record)
Benjamin Petersonf91df042009-02-13 02:50:59 +0000771 stream = self.stream
Vinay Sajipb9591172004-09-22 12:39:26 +0000772 fs = "%s\n"
Guido van Rossum13257902007-06-07 23:15:56 +0000773 if not _unicode: #if no unicode support...
Benjamin Petersonf91df042009-02-13 02:50:59 +0000774 stream.write(fs % msg)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000775 else:
776 try:
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000777 if (isinstance(msg, unicode) and
778 getattr(stream, 'encoding', None)):
779 fs = fs.decode(stream.encoding)
780 try:
781 stream.write(fs % msg)
782 except UnicodeEncodeError:
783 #Printing to terminals sometimes fails. For example,
784 #with an encoding of 'cp1251', the above write will
785 #work if written to a stream opened or wrapped by
786 #the codecs module, but fail when writing to a
787 #terminal even when the codepage is set to cp1251.
788 #An extra encoding step seems to be needed.
789 stream.write((fs % msg).encode(stream.encoding))
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000790 else:
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000791 stream.write(fs % msg)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000792 except UnicodeError:
Benjamin Petersonf91df042009-02-13 02:50:59 +0000793 stream.write(fs % msg.encode("UTF-8"))
Guido van Rossum57102f82002-11-13 16:15:58 +0000794 self.flush()
Vinay Sajip85c19092005-10-31 13:14:19 +0000795 except (KeyboardInterrupt, SystemExit):
796 raise
Guido van Rossum57102f82002-11-13 16:15:58 +0000797 except:
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000798 self.handleError(record)
Guido van Rossum57102f82002-11-13 16:15:58 +0000799
800class FileHandler(StreamHandler):
801 """
802 A handler class which writes formatted logging records to disk files.
803 """
Christian Heimese7a15bb2008-01-24 16:21:45 +0000804 def __init__(self, filename, mode='a', encoding=None, delay=0):
Guido van Rossum57102f82002-11-13 16:15:58 +0000805 """
806 Open the specified file and use it as the stream for logging.
807 """
Vinay Sajip4bbab2b2004-07-08 10:22:35 +0000808 #keep the absolute path, otherwise derived classes which use this
809 #may come a cropper when the current directory changes
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000810 if codecs is None:
811 encoding = None
Vinay Sajip4bbab2b2004-07-08 10:22:35 +0000812 self.baseFilename = os.path.abspath(filename)
Guido van Rossum57102f82002-11-13 16:15:58 +0000813 self.mode = mode
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000814 self.encoding = encoding
Christian Heimese7a15bb2008-01-24 16:21:45 +0000815 if delay:
Vinay Sajip6268cbc2009-01-21 00:19:28 +0000816 #We don't open the stream, but we still need to call the
817 #Handler constructor to set level, formatter, lock etc.
818 Handler.__init__(self)
Christian Heimese7a15bb2008-01-24 16:21:45 +0000819 self.stream = None
820 else:
Vinay Sajip6268cbc2009-01-21 00:19:28 +0000821 StreamHandler.__init__(self, self._open())
Guido van Rossum57102f82002-11-13 16:15:58 +0000822
823 def close(self):
824 """
825 Closes the stream.
826 """
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000827 if self.stream:
828 self.flush()
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +0000829 if hasattr(self.stream, "close"):
830 self.stream.close()
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000831 StreamHandler.close(self)
832 self.stream = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000833
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000834 def _open(self):
835 """
836 Open the current base file with the (original) mode and encoding.
837 Return the resulting stream.
838 """
839 if self.encoding is None:
840 stream = open(self.baseFilename, self.mode)
841 else:
842 stream = codecs.open(self.baseFilename, self.mode, self.encoding)
843 return stream
844
Christian Heimese7a15bb2008-01-24 16:21:45 +0000845 def emit(self, record):
846 """
847 Emit a record.
848
849 If the stream was not opened because 'delay' was specified in the
850 constructor, open it before calling the superclass's emit.
851 """
852 if self.stream is None:
Vinay Sajip6268cbc2009-01-21 00:19:28 +0000853 self.stream = self._open()
Christian Heimese7a15bb2008-01-24 16:21:45 +0000854 StreamHandler.emit(self, record)
855
Guido van Rossum57102f82002-11-13 16:15:58 +0000856#---------------------------------------------------------------------------
857# Manager classes and functions
858#---------------------------------------------------------------------------
859
860class PlaceHolder:
861 """
862 PlaceHolder instances are used in the Manager logger hierarchy to take
Vinay Sajip3f742842004-02-28 16:07:46 +0000863 the place of nodes for which no loggers have been defined. This class is
864 intended for internal use only and not as part of the public API.
Guido van Rossum57102f82002-11-13 16:15:58 +0000865 """
866 def __init__(self, alogger):
867 """
868 Initialize with the specified logger being a child of this placeholder.
869 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000870 #self.loggers = [alogger]
871 self.loggerMap = { alogger : None }
Guido van Rossum57102f82002-11-13 16:15:58 +0000872
873 def append(self, alogger):
874 """
875 Add the specified logger as a child of this placeholder.
876 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000877 #if alogger not in self.loggers:
Guido van Rossum93662412006-08-19 16:09:41 +0000878 if alogger not in self.loggerMap:
Vinay Sajip239322b2005-10-14 09:36:35 +0000879 #self.loggers.append(alogger)
880 self.loggerMap[alogger] = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000881
882#
883# Determine which class to use when instantiating loggers.
884#
885_loggerClass = None
886
887def setLoggerClass(klass):
888 """
889 Set the class to be used when instantiating a logger. The class should
890 define __init__() such that only a name argument is required, and the
891 __init__() should call Logger.__init__()
892 """
893 if klass != Logger:
Guido van Rossum57102f82002-11-13 16:15:58 +0000894 if not issubclass(klass, Logger):
Collin Winterce36ad82007-08-30 01:19:48 +0000895 raise TypeError("logger not derived from logging.Logger: "
896 + klass.__name__)
Guido van Rossum57102f82002-11-13 16:15:58 +0000897 global _loggerClass
898 _loggerClass = klass
899
Vinay Sajipb9591172004-09-22 12:39:26 +0000900def getLoggerClass():
901 """
902 Return the class to be used when instantiating a logger.
903 """
904
905 return _loggerClass
906
Guido van Rossum57102f82002-11-13 16:15:58 +0000907class Manager:
908 """
909 There is [under normal circumstances] just one Manager instance, which
910 holds the hierarchy of loggers.
911 """
Neal Norwitzd1cade02002-11-15 23:31:28 +0000912 def __init__(self, rootnode):
Guido van Rossum57102f82002-11-13 16:15:58 +0000913 """
914 Initialize the manager with the root node of the logger hierarchy.
915 """
Neal Norwitzd1cade02002-11-15 23:31:28 +0000916 self.root = rootnode
Guido van Rossum57102f82002-11-13 16:15:58 +0000917 self.disable = 0
918 self.emittedNoHandlerWarning = 0
919 self.loggerDict = {}
920
921 def getLogger(self, name):
922 """
923 Get a logger with the specified name (channel name), creating it
Vinay Sajipb9591172004-09-22 12:39:26 +0000924 if it doesn't yet exist. This name is a dot-separated hierarchical
925 name, such as "a", "a.b", "a.b.c" or similar.
Guido van Rossum57102f82002-11-13 16:15:58 +0000926
927 If a PlaceHolder existed for the specified name [i.e. the logger
928 didn't exist but a child of it did], replace it with the created
929 logger and fix up the parent/child references which pointed to the
930 placeholder to now point to the logger.
931 """
932 rv = None
933 _acquireLock()
934 try:
Guido van Rossum93662412006-08-19 16:09:41 +0000935 if name in self.loggerDict:
Guido van Rossum57102f82002-11-13 16:15:58 +0000936 rv = self.loggerDict[name]
937 if isinstance(rv, PlaceHolder):
938 ph = rv
939 rv = _loggerClass(name)
940 rv.manager = self
941 self.loggerDict[name] = rv
942 self._fixupChildren(ph, rv)
943 self._fixupParents(rv)
944 else:
945 rv = _loggerClass(name)
946 rv.manager = self
947 self.loggerDict[name] = rv
948 self._fixupParents(rv)
949 finally:
950 _releaseLock()
951 return rv
952
953 def _fixupParents(self, alogger):
954 """
955 Ensure that there are either loggers or placeholders all the way
956 from the specified logger to the root of the logger hierarchy.
957 """
958 name = alogger.name
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000959 i = name.rfind(".")
Guido van Rossum57102f82002-11-13 16:15:58 +0000960 rv = None
961 while (i > 0) and not rv:
962 substr = name[:i]
Guido van Rossum93662412006-08-19 16:09:41 +0000963 if substr not in self.loggerDict:
Guido van Rossum57102f82002-11-13 16:15:58 +0000964 self.loggerDict[substr] = PlaceHolder(alogger)
965 else:
966 obj = self.loggerDict[substr]
967 if isinstance(obj, Logger):
968 rv = obj
969 else:
970 assert isinstance(obj, PlaceHolder)
971 obj.append(alogger)
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000972 i = name.rfind(".", 0, i - 1)
Guido van Rossum57102f82002-11-13 16:15:58 +0000973 if not rv:
974 rv = self.root
975 alogger.parent = rv
976
977 def _fixupChildren(self, ph, alogger):
978 """
979 Ensure that children of the placeholder ph are connected to the
980 specified logger.
981 """
Thomas Wouters89f507f2006-12-13 04:49:30 +0000982 name = alogger.name
983 namelen = len(name)
Vinay Sajip239322b2005-10-14 09:36:35 +0000984 for c in ph.loggerMap.keys():
Thomas Wouters89f507f2006-12-13 04:49:30 +0000985 #The if means ... if not c.parent.name.startswith(nm)
986 if c.parent.name[:namelen] != name:
Guido van Rossum57102f82002-11-13 16:15:58 +0000987 alogger.parent = c.parent
988 c.parent = alogger
989
990#---------------------------------------------------------------------------
991# Logger classes and functions
992#---------------------------------------------------------------------------
993
994class Logger(Filterer):
995 """
996 Instances of the Logger class represent a single logging channel. A
997 "logging channel" indicates an area of an application. Exactly how an
998 "area" is defined is up to the application developer. Since an
999 application can have any number of areas, logging channels are identified
1000 by a unique string. Application areas can be nested (e.g. an area
1001 of "input processing" might include sub-areas "read CSV files", "read
1002 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
1003 channel names are organized into a namespace hierarchy where levels are
1004 separated by periods, much like the Java or Python package namespace. So
1005 in the instance given above, channel names might be "input" for the upper
1006 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
1007 There is no arbitrary limit to the depth of nesting.
1008 """
1009 def __init__(self, name, level=NOTSET):
1010 """
1011 Initialize the logger with a name and an optional level.
1012 """
1013 Filterer.__init__(self)
1014 self.name = name
1015 self.level = level
1016 self.parent = None
1017 self.propagate = 1
1018 self.handlers = []
1019 self.disabled = 0
1020
1021 def setLevel(self, level):
1022 """
1023 Set the logging level of this logger.
1024 """
1025 self.level = level
1026
Guido van Rossum57102f82002-11-13 16:15:58 +00001027 def debug(self, msg, *args, **kwargs):
1028 """
1029 Log 'msg % args' with severity 'DEBUG'.
1030
1031 To pass exception information, use the keyword argument exc_info with
1032 a true value, e.g.
1033
1034 logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
1035 """
Guido van Rossum04110fb2007-08-24 16:32:05 +00001036 if self.isEnabledFor(DEBUG):
Neal Norwitzd9108552006-03-17 08:00:19 +00001037 self._log(DEBUG, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001038
1039 def info(self, msg, *args, **kwargs):
1040 """
1041 Log 'msg % args' with severity 'INFO'.
1042
1043 To pass exception information, use the keyword argument exc_info with
1044 a true value, e.g.
1045
1046 logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
1047 """
Guido van Rossum04110fb2007-08-24 16:32:05 +00001048 if self.isEnabledFor(INFO):
Neal Norwitzd9108552006-03-17 08:00:19 +00001049 self._log(INFO, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001050
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001051 def warning(self, msg, *args, **kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001052 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001053 Log 'msg % args' with severity 'WARNING'.
Guido van Rossum57102f82002-11-13 16:15:58 +00001054
1055 To pass exception information, use the keyword argument exc_info with
1056 a true value, e.g.
1057
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001058 logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
Guido van Rossum57102f82002-11-13 16:15:58 +00001059 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001060 if self.isEnabledFor(WARNING):
Neal Norwitzd9108552006-03-17 08:00:19 +00001061 self._log(WARNING, msg, args, **kwargs)
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001062
1063 warn = warning
Guido van Rossum57102f82002-11-13 16:15:58 +00001064
1065 def error(self, msg, *args, **kwargs):
1066 """
1067 Log 'msg % args' with severity 'ERROR'.
1068
1069 To pass exception information, use the keyword argument exc_info with
1070 a true value, e.g.
1071
1072 logger.error("Houston, we have a %s", "major problem", exc_info=1)
1073 """
Guido van Rossum57102f82002-11-13 16:15:58 +00001074 if self.isEnabledFor(ERROR):
Neal Norwitzd9108552006-03-17 08:00:19 +00001075 self._log(ERROR, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001076
1077 def exception(self, msg, *args):
1078 """
1079 Convenience method for logging an ERROR with exception information.
1080 """
Neal Norwitz7c307242006-03-17 08:28:24 +00001081 self.error(msg, exc_info=1, *args)
Guido van Rossum57102f82002-11-13 16:15:58 +00001082
1083 def critical(self, msg, *args, **kwargs):
1084 """
1085 Log 'msg % args' with severity 'CRITICAL'.
1086
1087 To pass exception information, use the keyword argument exc_info with
1088 a true value, e.g.
1089
1090 logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1091 """
Guido van Rossum04110fb2007-08-24 16:32:05 +00001092 if self.isEnabledFor(CRITICAL):
Neal Norwitzd9108552006-03-17 08:00:19 +00001093 self._log(CRITICAL, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001094
1095 fatal = critical
1096
1097 def log(self, level, msg, *args, **kwargs):
1098 """
Vinay Sajipeb477d02004-08-04 08:38:08 +00001099 Log 'msg % args' with the integer severity 'level'.
Guido van Rossum57102f82002-11-13 16:15:58 +00001100
1101 To pass exception information, use the keyword argument exc_info with
1102 a true value, e.g.
1103
1104 logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1105 """
Guido van Rossum13257902007-06-07 23:15:56 +00001106 if not isinstance(level, int):
Vinay Sajip779e0c92004-07-03 11:47:26 +00001107 if raiseExceptions:
Collin Winterce36ad82007-08-30 01:19:48 +00001108 raise TypeError("level must be an integer")
Vinay Sajip779e0c92004-07-03 11:47:26 +00001109 else:
1110 return
Guido van Rossum57102f82002-11-13 16:15:58 +00001111 if self.isEnabledFor(level):
Neal Norwitzd9108552006-03-17 08:00:19 +00001112 self._log(level, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001113
1114 def findCaller(self):
1115 """
1116 Find the stack frame of the caller so that we can note the source
Vinay Sajip829dc512005-02-18 11:53:32 +00001117 file name, line number and function name.
Guido van Rossum57102f82002-11-13 16:15:58 +00001118 """
Benjamin Petersonf3d7dbe2009-10-04 14:54:52 +00001119 f = currentframe()
1120 #On some versions of IronPython, currentframe() returns None if
1121 #IronPython isn't run with -X:Frames.
1122 if f is not None:
1123 f = f.f_back
Thomas Woutersa9773292006-04-21 09:43:23 +00001124 rv = "(unknown file)", 0, "(unknown function)"
1125 while hasattr(f, "f_code"):
Jeremy Hylton250684d2003-01-23 18:29:29 +00001126 co = f.f_code
1127 filename = os.path.normcase(co.co_filename)
1128 if filename == _srcfile:
1129 f = f.f_back
1130 continue
Thomas Woutersa9773292006-04-21 09:43:23 +00001131 rv = (filename, f.f_lineno, co.co_name)
1132 break
1133 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +00001134
Vinay Sajiped1992f2006-02-09 08:48:36 +00001135 def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
Guido van Rossum57102f82002-11-13 16:15:58 +00001136 """
1137 A factory method which can be overridden in subclasses to create
1138 specialized LogRecords.
1139 """
Vinay Sajiped1992f2006-02-09 08:48:36 +00001140 rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
Christian Heimes04c420f2008-01-18 18:40:46 +00001141 if extra is not None:
Vinay Sajip260ce432006-02-09 08:34:14 +00001142 for key in extra:
1143 if (key in ["message", "asctime"]) or (key in rv.__dict__):
1144 raise KeyError("Attempt to overwrite %r in LogRecord" % key)
1145 rv.__dict__[key] = extra[key]
1146 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +00001147
Vinay Sajip260ce432006-02-09 08:34:14 +00001148 def _log(self, level, msg, args, exc_info=None, extra=None):
Guido van Rossum57102f82002-11-13 16:15:58 +00001149 """
1150 Low-level logging routine which creates a LogRecord and then calls
1151 all the handlers of this logger to handle the record.
1152 """
Jeremy Hylton250684d2003-01-23 18:29:29 +00001153 if _srcfile:
Vinay Sajipb672b6d2009-02-19 12:36:11 +00001154 #IronPython doesn't track Python frames, so findCaller throws an
Benjamin Petersonf3d7dbe2009-10-04 14:54:52 +00001155 #exception on some versions of IronPython. We trap it here so that
1156 #IronPython can use logging.
Vinay Sajipb672b6d2009-02-19 12:36:11 +00001157 try:
1158 fn, lno, func = self.findCaller()
1159 except ValueError:
1160 fn, lno, func = "(unknown file)", 0, "(unknown function)"
Guido van Rossum57102f82002-11-13 16:15:58 +00001161 else:
Vinay Sajip829dc512005-02-18 11:53:32 +00001162 fn, lno, func = "(unknown file)", 0, "(unknown function)"
Guido van Rossum57102f82002-11-13 16:15:58 +00001163 if exc_info:
Guido van Rossum13257902007-06-07 23:15:56 +00001164 if not isinstance(exc_info, tuple):
Vinay Sajiped6bb142004-02-20 13:18:36 +00001165 exc_info = sys.exc_info()
Vinay Sajiped1992f2006-02-09 08:48:36 +00001166 record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
Guido van Rossum57102f82002-11-13 16:15:58 +00001167 self.handle(record)
1168
1169 def handle(self, record):
1170 """
1171 Call the handlers for the specified record.
1172
1173 This method is used for unpickled records received from a socket, as
1174 well as those created locally. Logger-level filtering is applied.
1175 """
1176 if (not self.disabled) and self.filter(record):
1177 self.callHandlers(record)
1178
1179 def addHandler(self, hdlr):
1180 """
1181 Add the specified handler to this logger.
1182 """
1183 if not (hdlr in self.handlers):
1184 self.handlers.append(hdlr)
1185
1186 def removeHandler(self, hdlr):
1187 """
1188 Remove the specified handler from this logger.
1189 """
1190 if hdlr in self.handlers:
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001191 #hdlr.close()
Vinay Sajip116f16e2005-09-16 10:33:40 +00001192 hdlr.acquire()
1193 try:
1194 self.handlers.remove(hdlr)
1195 finally:
1196 hdlr.release()
Guido van Rossum57102f82002-11-13 16:15:58 +00001197
1198 def callHandlers(self, record):
1199 """
1200 Pass a record to all relevant handlers.
1201
1202 Loop through all handlers for this logger and its parents in the
1203 logger hierarchy. If no handler was found, output a one-off error
1204 message to sys.stderr. Stop searching up the hierarchy whenever a
1205 logger with the "propagate" attribute set to zero is found - that
1206 will be the last logger whose handlers are called.
1207 """
1208 c = self
1209 found = 0
1210 while c:
1211 for hdlr in c.handlers:
1212 found = found + 1
1213 if record.levelno >= hdlr.level:
1214 hdlr.handle(record)
1215 if not c.propagate:
1216 c = None #break out
1217 else:
1218 c = c.parent
Vinay Sajip1e86beb2005-10-23 22:32:59 +00001219 if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
Guido van Rossum57102f82002-11-13 16:15:58 +00001220 sys.stderr.write("No handlers could be found for logger"
1221 " \"%s\"\n" % self.name)
1222 self.manager.emittedNoHandlerWarning = 1
1223
1224 def getEffectiveLevel(self):
1225 """
1226 Get the effective level for this logger.
1227
1228 Loop through this logger and its parents in the logger hierarchy,
1229 looking for a non-zero logging level. Return the first one found.
1230 """
1231 logger = self
1232 while logger:
1233 if logger.level:
1234 return logger.level
1235 logger = logger.parent
1236 return NOTSET
1237
1238 def isEnabledFor(self, level):
1239 """
1240 Is this logger enabled for level 'level'?
1241 """
1242 if self.manager.disable >= level:
1243 return 0
1244 return level >= self.getEffectiveLevel()
1245
1246class RootLogger(Logger):
1247 """
1248 A root logger is not that different to any other logger, except that
1249 it must have a logging level and there is only one instance of it in
1250 the hierarchy.
1251 """
1252 def __init__(self, level):
1253 """
1254 Initialize the logger with the name "root".
1255 """
1256 Logger.__init__(self, "root", level)
1257
1258_loggerClass = Logger
1259
Christian Heimes04c420f2008-01-18 18:40:46 +00001260class LoggerAdapter:
1261 """
1262 An adapter for loggers which makes it easier to specify contextual
1263 information in logging output.
1264 """
1265
1266 def __init__(self, logger, extra):
1267 """
1268 Initialize the adapter with a logger and a dict-like object which
1269 provides contextual information. This constructor signature allows
1270 easy stacking of LoggerAdapters, if so desired.
1271
1272 You can effectively pass keyword arguments as shown in the
1273 following example:
1274
1275 adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
1276 """
1277 self.logger = logger
1278 self.extra = extra
1279
1280 def process(self, msg, kwargs):
1281 """
1282 Process the logging message and keyword arguments passed in to
1283 a logging call to insert contextual information. You can either
1284 manipulate the message itself, the keyword args or both. Return
1285 the message and kwargs modified (or not) to suit your needs.
1286
1287 Normally, you'll only need to override this one method in a
1288 LoggerAdapter subclass for your specific needs.
1289 """
1290 kwargs["extra"] = self.extra
1291 return msg, kwargs
1292
1293 def debug(self, msg, *args, **kwargs):
1294 """
1295 Delegate a debug call to the underlying logger, after adding
1296 contextual information from this adapter instance.
1297 """
1298 msg, kwargs = self.process(msg, kwargs)
1299 self.logger.debug(msg, *args, **kwargs)
1300
1301 def info(self, msg, *args, **kwargs):
1302 """
1303 Delegate an info call to the underlying logger, after adding
1304 contextual information from this adapter instance.
1305 """
1306 msg, kwargs = self.process(msg, kwargs)
1307 self.logger.info(msg, *args, **kwargs)
1308
1309 def warning(self, msg, *args, **kwargs):
1310 """
1311 Delegate a warning call to the underlying logger, after adding
1312 contextual information from this adapter instance.
1313 """
1314 msg, kwargs = self.process(msg, kwargs)
1315 self.logger.warning(msg, *args, **kwargs)
1316
1317 def error(self, msg, *args, **kwargs):
1318 """
1319 Delegate an error call to the underlying logger, after adding
1320 contextual information from this adapter instance.
1321 """
1322 msg, kwargs = self.process(msg, kwargs)
1323 self.logger.error(msg, *args, **kwargs)
1324
1325 def exception(self, msg, *args, **kwargs):
1326 """
1327 Delegate an exception call to the underlying logger, after adding
1328 contextual information from this adapter instance.
1329 """
1330 msg, kwargs = self.process(msg, kwargs)
1331 kwargs["exc_info"] = 1
1332 self.logger.error(msg, *args, **kwargs)
1333
1334 def critical(self, msg, *args, **kwargs):
1335 """
1336 Delegate a critical call to the underlying logger, after adding
1337 contextual information from this adapter instance.
1338 """
1339 msg, kwargs = self.process(msg, kwargs)
1340 self.logger.critical(msg, *args, **kwargs)
1341
1342 def log(self, level, msg, *args, **kwargs):
1343 """
1344 Delegate a log call to the underlying logger, after adding
1345 contextual information from this adapter instance.
1346 """
1347 msg, kwargs = self.process(msg, kwargs)
1348 self.logger.log(level, msg, *args, **kwargs)
1349
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001350root = RootLogger(WARNING)
Guido van Rossum57102f82002-11-13 16:15:58 +00001351Logger.root = root
1352Logger.manager = Manager(Logger.root)
1353
1354#---------------------------------------------------------------------------
1355# Configuration classes and functions
1356#---------------------------------------------------------------------------
1357
1358BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
1359
Vinay Sajip779e0c92004-07-03 11:47:26 +00001360def basicConfig(**kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001361 """
Vinay Sajip779e0c92004-07-03 11:47:26 +00001362 Do basic configuration for the logging system.
1363
1364 This function does nothing if the root logger already has handlers
1365 configured. It is a convenience method intended for use by simple scripts
1366 to do one-shot configuration of the logging package.
1367
1368 The default behaviour is to create a StreamHandler which writes to
1369 sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1370 add the handler to the root logger.
1371
1372 A number of optional keyword arguments may be specified, which can alter
1373 the default behaviour.
1374
1375 filename Specifies that a FileHandler be created, using the specified
1376 filename, rather than a StreamHandler.
1377 filemode Specifies the mode to open the file, if filename is specified
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001378 (if filemode is unspecified, it defaults to 'a').
Vinay Sajip779e0c92004-07-03 11:47:26 +00001379 format Use the specified format string for the handler.
1380 datefmt Use the specified date/time format.
1381 level Set the root logger level to the specified level.
1382 stream Use the specified stream to initialize the StreamHandler. Note
1383 that this argument is incompatible with 'filename' - if both
1384 are present, 'stream' is ignored.
1385
1386 Note that you could specify a stream created using open(filename, mode)
1387 rather than passing the filename and mode in. However, it should be
1388 remembered that StreamHandler does not close its stream (since it may be
1389 using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1390 when the handler is closed.
Guido van Rossum57102f82002-11-13 16:15:58 +00001391 """
1392 if len(root.handlers) == 0:
Vinay Sajip779e0c92004-07-03 11:47:26 +00001393 filename = kwargs.get("filename")
1394 if filename:
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001395 mode = kwargs.get("filemode", 'a')
Vinay Sajip779e0c92004-07-03 11:47:26 +00001396 hdlr = FileHandler(filename, mode)
1397 else:
1398 stream = kwargs.get("stream")
1399 hdlr = StreamHandler(stream)
1400 fs = kwargs.get("format", BASIC_FORMAT)
1401 dfs = kwargs.get("datefmt", None)
1402 fmt = Formatter(fs, dfs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001403 hdlr.setFormatter(fmt)
1404 root.addHandler(hdlr)
Vinay Sajip779e0c92004-07-03 11:47:26 +00001405 level = kwargs.get("level")
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001406 if level is not None:
Vinay Sajip0f6eac22009-06-21 17:46:49 +00001407 if str(level) == level: # If a string was passed, do more checks
1408 if level not in _levelNames:
1409 raise ValueError("Unknown level: %r" % level)
1410 level = _levelNames[level]
Tim Peters4e0e1b62004-07-07 20:54:48 +00001411 root.setLevel(level)
Guido van Rossum57102f82002-11-13 16:15:58 +00001412
1413#---------------------------------------------------------------------------
1414# Utility functions at module level.
1415# Basically delegate everything to the root logger.
1416#---------------------------------------------------------------------------
1417
1418def getLogger(name=None):
1419 """
1420 Return a logger with the specified name, creating it if necessary.
1421
1422 If no name is specified, return the root logger.
1423 """
1424 if name:
1425 return Logger.manager.getLogger(name)
1426 else:
1427 return root
1428
1429#def getRootLogger():
1430# """
1431# Return the root logger.
1432#
1433# Note that getLogger('') now does the same thing, so this function is
1434# deprecated and may disappear in the future.
1435# """
1436# return root
1437
1438def critical(msg, *args, **kwargs):
1439 """
1440 Log a message with severity 'CRITICAL' on the root logger.
1441 """
1442 if len(root.handlers) == 0:
1443 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001444 root.critical(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001445
1446fatal = critical
1447
1448def error(msg, *args, **kwargs):
1449 """
1450 Log a message with severity 'ERROR' on the root logger.
1451 """
1452 if len(root.handlers) == 0:
1453 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001454 root.error(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001455
1456def exception(msg, *args):
1457 """
1458 Log a message with severity 'ERROR' on the root logger,
1459 with exception information.
1460 """
Neal Norwitz7c307242006-03-17 08:28:24 +00001461 error(msg, exc_info=1, *args)
Guido van Rossum57102f82002-11-13 16:15:58 +00001462
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001463def warning(msg, *args, **kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001464 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001465 Log a message with severity 'WARNING' on the root logger.
Guido van Rossum57102f82002-11-13 16:15:58 +00001466 """
1467 if len(root.handlers) == 0:
1468 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001469 root.warning(msg, *args, **kwargs)
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001470
1471warn = warning
Guido van Rossum57102f82002-11-13 16:15:58 +00001472
1473def info(msg, *args, **kwargs):
1474 """
1475 Log a message with severity 'INFO' on the root logger.
1476 """
1477 if len(root.handlers) == 0:
1478 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001479 root.info(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001480
1481def debug(msg, *args, **kwargs):
1482 """
1483 Log a message with severity 'DEBUG' on the root logger.
1484 """
1485 if len(root.handlers) == 0:
1486 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001487 root.debug(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001488
Vinay Sajipb2635b22004-09-24 11:45:52 +00001489def log(level, msg, *args, **kwargs):
1490 """
1491 Log 'msg % args' with the integer severity 'level' on the root logger.
1492 """
1493 if len(root.handlers) == 0:
1494 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001495 root.log(level, msg, *args, **kwargs)
Vinay Sajipb2635b22004-09-24 11:45:52 +00001496
Guido van Rossum57102f82002-11-13 16:15:58 +00001497def disable(level):
1498 """
1499 Disable all logging calls less severe than 'level'.
1500 """
1501 root.manager.disable = level
1502
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001503def shutdown(handlerList=_handlerList):
Guido van Rossum57102f82002-11-13 16:15:58 +00001504 """
1505 Perform any cleanup actions in the logging system (e.g. flushing
1506 buffers).
1507
1508 Should be called at application exit.
1509 """
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001510 for h in handlerList[:]:
Vinay Sajipe12f7152004-07-29 09:19:30 +00001511 #errors might occur, for example, if files are locked
Vinay Sajip260ce432006-02-09 08:34:14 +00001512 #we just ignore them if raiseExceptions is not set
Vinay Sajipe12f7152004-07-29 09:19:30 +00001513 try:
1514 h.flush()
1515 h.close()
1516 except:
Vinay Sajip260ce432006-02-09 08:34:14 +00001517 if raiseExceptions:
1518 raise
1519 #else, swallow
Vinay Sajiped6bb142004-02-20 13:18:36 +00001520
1521#Let's try and shutdown automatically on application exit...
1522try:
1523 import atexit
1524 atexit.register(shutdown)
1525except ImportError: # for Python versions < 2.0
1526 def exithook(status, old_exit=sys.exit):
1527 try:
1528 shutdown()
1529 finally:
1530 old_exit(status)
1531
1532 sys.exit = exithook
Georg Brandlf9734072008-12-07 15:30:06 +00001533
1534# Null handler
1535
1536class NullHandler(Handler):
1537 """
1538 This handler does nothing. It's intended to be used to avoid the
1539 "No handlers could be found for logger XXX" one-off warning. This is
1540 important for library code, which may contain code to log events. If a user
1541 of the library does not configure logging, the one-off warning might be
1542 produced; to avoid this, the library developer simply needs to instantiate
1543 a NullHandler and add it to the top-level logger of the library module or
1544 package.
1545 """
1546 def emit(self, record):
1547 pass
1548
1549# Warnings integration
1550
1551_warnings_showwarning = None
1552
1553def _showwarning(message, category, filename, lineno, file=None, line=None):
1554 """
1555 Implementation of showwarnings which redirects to logging, which will first
1556 check to see if the file parameter is None. If a file is specified, it will
1557 delegate to the original warnings implementation of showwarning. Otherwise,
1558 it will call warnings.formatwarning and will log the resulting string to a
1559 warnings logger named "py.warnings" with level logging.WARNING.
1560 """
1561 if file is not None:
1562 if _warnings_showwarning is not None:
1563 _warnings_showwarning(message, category, filename, lineno, file, line)
1564 else:
1565 s = warnings.formatwarning(message, category, filename, lineno, line)
1566 logger = getLogger("py.warnings")
1567 if not logger.handlers:
1568 logger.addHandler(NullHandler())
1569 logger.warning("%s", s)
1570
1571def captureWarnings(capture):
1572 """
1573 If capture is true, redirect all warnings to the logging package.
1574 If capture is False, ensure that warnings are not redirected to logging
1575 but to their original destinations.
1576 """
1577 global _warnings_showwarning
1578 if capture:
1579 if _warnings_showwarning is None:
1580 _warnings_showwarning = warnings.showwarning
1581 warnings.showwarning = _showwarning
1582 else:
1583 if _warnings_showwarning is not None:
1584 warnings.showwarning = _warnings_showwarning
1585 _warnings_showwarning = None