blob: 517a7a94f09ae2c75025379583bc269b3e18f4e7 [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
Jesse Noller9a0fc972009-01-18 21:12:58 +0000274 if logMultiprocessing:
275 from multiprocessing import current_process
276 self.processName = current_process().name
277 else:
278 self.processName = None
Vinay Sajipd364a072006-03-13 22:05:28 +0000279 if logProcesses and hasattr(os, 'getpid'):
Jack Jansen4c641d02003-02-21 22:29:45 +0000280 self.process = os.getpid()
281 else:
282 self.process = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000283
284 def __str__(self):
285 return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
286 self.pathname, self.lineno, self.msg)
287
288 def getMessage(self):
289 """
290 Return the message for this LogRecord.
291
292 Return the message for this LogRecord after merging any user-supplied
293 arguments with the message.
294 """
Guido van Rossum13257902007-06-07 23:15:56 +0000295 if not _unicode: #if no unicode support...
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000296 msg = str(self.msg)
297 else:
Vinay Sajip43d6e812005-10-07 08:35:36 +0000298 msg = self.msg
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000299 if not isinstance(msg, str):
Vinay Sajip43d6e812005-10-07 08:35:36 +0000300 try:
301 msg = str(self.msg)
302 except UnicodeError:
303 msg = self.msg #Defer encoding till later
Guido van Rossum57102f82002-11-13 16:15:58 +0000304 if self.args:
305 msg = msg % self.args
306 return msg
307
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +0000308def makeLogRecord(dict):
309 """
310 Make a LogRecord whose attributes are defined by the specified dictionary,
311 This function is useful for converting a logging event received over
312 a socket connection (which is sent as a dictionary) into a LogRecord
313 instance.
314 """
Vinay Sajiped1992f2006-02-09 08:48:36 +0000315 rv = LogRecord(None, None, "", 0, "", (), None, None)
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +0000316 rv.__dict__.update(dict)
317 return rv
318
Guido van Rossum57102f82002-11-13 16:15:58 +0000319#---------------------------------------------------------------------------
320# Formatter classes and functions
321#---------------------------------------------------------------------------
322
323class Formatter:
324 """
325 Formatter instances are used to convert a LogRecord to text.
326
327 Formatters need to know how a LogRecord is constructed. They are
328 responsible for converting a LogRecord to (usually) a string which can
329 be interpreted by either a human or an external system. The base Formatter
330 allows a formatting string to be specified. If none is supplied, the
331 default value of "%s(message)\\n" is used.
332
333 The Formatter can be initialized with a format string which makes use of
334 knowledge of the LogRecord attributes - e.g. the default value mentioned
335 above makes use of the fact that the user's message and arguments are pre-
336 formatted into a LogRecord's message attribute. Currently, the useful
337 attributes in a LogRecord are described by:
338
339 %(name)s Name of the logger (logging channel)
340 %(levelno)s Numeric logging level for the message (DEBUG, INFO,
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000341 WARNING, ERROR, CRITICAL)
Guido van Rossum57102f82002-11-13 16:15:58 +0000342 %(levelname)s Text logging level for the message ("DEBUG", "INFO",
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000343 "WARNING", "ERROR", "CRITICAL")
Guido van Rossum57102f82002-11-13 16:15:58 +0000344 %(pathname)s Full pathname of the source file where the logging
345 call was issued (if available)
346 %(filename)s Filename portion of pathname
347 %(module)s Module (name portion of filename)
348 %(lineno)d Source line number where the logging call was issued
349 (if available)
Vinay Sajiped1992f2006-02-09 08:48:36 +0000350 %(funcName)s Function name
Guido van Rossum57102f82002-11-13 16:15:58 +0000351 %(created)f Time when the LogRecord was created (time.time()
352 return value)
353 %(asctime)s Textual time when the LogRecord was created
354 %(msecs)d Millisecond portion of the creation time
355 %(relativeCreated)d Time in milliseconds when the LogRecord was created,
356 relative to the time the logging module was loaded
357 (typically at application startup time)
358 %(thread)d Thread ID (if available)
Vinay Sajip4a704862005-03-31 20:16:55 +0000359 %(threadName)s Thread name (if available)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000360 %(process)d Process ID (if available)
Guido van Rossum57102f82002-11-13 16:15:58 +0000361 %(message)s The result of record.getMessage(), computed just as
362 the record is emitted
363 """
364
365 converter = time.localtime
366
367 def __init__(self, fmt=None, datefmt=None):
368 """
369 Initialize the formatter with specified format strings.
370
371 Initialize the formatter either with the specified format string, or a
372 default as described above. Allow for specialized date formatting with
373 the optional datefmt argument (if omitted, you get the ISO8601 format).
374 """
375 if fmt:
376 self._fmt = fmt
377 else:
378 self._fmt = "%(message)s"
379 self.datefmt = datefmt
380
381 def formatTime(self, record, datefmt=None):
382 """
383 Return the creation time of the specified LogRecord as formatted text.
384
385 This method should be called from format() by a formatter which
386 wants to make use of a formatted time. This method can be overridden
387 in formatters to provide for any specific requirement, but the
388 basic behaviour is as follows: if datefmt (a string) is specified,
389 it is used with time.strftime() to format the creation time of the
390 record. Otherwise, the ISO8601 format is used. The resulting
391 string is returned. This function uses a user-configurable function
392 to convert the creation time to a tuple. By default, time.localtime()
393 is used; to change this for a particular formatter instance, set the
394 'converter' attribute to a function with the same signature as
395 time.localtime() or time.gmtime(). To change it for all formatters,
396 for example if you want all logging times to be shown in GMT,
397 set the 'converter' attribute in the Formatter class.
398 """
399 ct = self.converter(record.created)
400 if datefmt:
401 s = time.strftime(datefmt, ct)
402 else:
403 t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
404 s = "%s,%03d" % (t, record.msecs)
405 return s
406
407 def formatException(self, ei):
408 """
409 Format and return the specified exception information as a string.
410
411 This default implementation just uses
412 traceback.print_exception()
413 """
Guido van Rossum34d19282007-08-09 01:03:29 +0000414 sio = io.StringIO()
Guido van Rossum57102f82002-11-13 16:15:58 +0000415 traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
416 s = sio.getvalue()
417 sio.close()
Guido van Rossum486364b2007-06-30 05:01:58 +0000418 if s[-1:] == "\n":
Guido van Rossum57102f82002-11-13 16:15:58 +0000419 s = s[:-1]
420 return s
421
422 def format(self, record):
423 """
424 Format the specified record as text.
425
426 The record's attribute dictionary is used as the operand to a
427 string formatting operation which yields the returned string.
428 Before formatting the dictionary, a couple of preparatory steps
429 are carried out. The message attribute of the record is computed
430 using LogRecord.getMessage(). If the formatting string contains
431 "%(asctime)", formatTime() is called to format the event time.
432 If there is exception information, it is formatted using
433 formatException() and appended to the message.
434 """
435 record.message = record.getMessage()
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000436 if self._fmt.find("%(asctime)") >= 0:
Guido van Rossum57102f82002-11-13 16:15:58 +0000437 record.asctime = self.formatTime(record, self.datefmt)
438 s = self._fmt % record.__dict__
439 if record.exc_info:
Vinay Sajiped6bb142004-02-20 13:18:36 +0000440 # Cache the traceback text to avoid converting it multiple times
441 # (it's constant anyway)
442 if not record.exc_text:
443 record.exc_text = self.formatException(record.exc_info)
444 if record.exc_text:
Guido van Rossum486364b2007-06-30 05:01:58 +0000445 if s[-1:] != "\n":
Guido van Rossum57102f82002-11-13 16:15:58 +0000446 s = s + "\n"
Vinay Sajiped6bb142004-02-20 13:18:36 +0000447 s = s + record.exc_text
Guido van Rossum57102f82002-11-13 16:15:58 +0000448 return s
449
450#
451# The default formatter to use when no other is specified
452#
453_defaultFormatter = Formatter()
454
455class BufferingFormatter:
456 """
457 A formatter suitable for formatting a number of records.
458 """
459 def __init__(self, linefmt=None):
460 """
461 Optionally specify a formatter which will be used to format each
462 individual record.
463 """
464 if linefmt:
465 self.linefmt = linefmt
466 else:
467 self.linefmt = _defaultFormatter
468
469 def formatHeader(self, records):
470 """
471 Return the header string for the specified records.
472 """
473 return ""
474
475 def formatFooter(self, records):
476 """
477 Return the footer string for the specified records.
478 """
479 return ""
480
481 def format(self, records):
482 """
483 Format the specified records and return the result as a string.
484 """
485 rv = ""
486 if len(records) > 0:
487 rv = rv + self.formatHeader(records)
488 for record in records:
489 rv = rv + self.linefmt.format(record)
490 rv = rv + self.formatFooter(records)
491 return rv
492
493#---------------------------------------------------------------------------
494# Filter classes and functions
495#---------------------------------------------------------------------------
496
497class Filter:
498 """
499 Filter instances are used to perform arbitrary filtering of LogRecords.
500
501 Loggers and Handlers can optionally use Filter instances to filter
502 records as desired. The base filter class only allows events which are
503 below a certain point in the logger hierarchy. For example, a filter
504 initialized with "A.B" will allow events logged by loggers "A.B",
505 "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
506 initialized with the empty string, all events are passed.
507 """
508 def __init__(self, name=''):
509 """
510 Initialize a filter.
511
512 Initialize with the name of the logger which, together with its
513 children, will have its events allowed through the filter. If no
514 name is specified, allow every event.
515 """
516 self.name = name
517 self.nlen = len(name)
518
519 def filter(self, record):
520 """
521 Determine if the specified record is to be logged.
522
523 Is the specified record to be logged? Returns 0 for no, nonzero for
524 yes. If deemed appropriate, the record may be modified in-place.
525 """
526 if self.nlen == 0:
527 return 1
528 elif self.name == record.name:
529 return 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000530 elif record.name.find(self.name, 0, self.nlen) != 0:
Guido van Rossum57102f82002-11-13 16:15:58 +0000531 return 0
532 return (record.name[self.nlen] == ".")
533
534class Filterer:
535 """
536 A base class for loggers and handlers which allows them to share
537 common code.
538 """
539 def __init__(self):
540 """
541 Initialize the list of filters to be an empty list.
542 """
543 self.filters = []
544
545 def addFilter(self, filter):
546 """
547 Add the specified filter to this handler.
548 """
549 if not (filter in self.filters):
550 self.filters.append(filter)
551
552 def removeFilter(self, filter):
553 """
554 Remove the specified filter from this handler.
555 """
556 if filter in self.filters:
557 self.filters.remove(filter)
558
559 def filter(self, record):
560 """
561 Determine if a record is loggable by consulting all the filters.
562
563 The default is to allow the record to be logged; any filter can veto
564 this and the record is then dropped. Returns a zero value if a record
565 is to be dropped, else non-zero.
566 """
567 rv = 1
568 for f in self.filters:
569 if not f.filter(record):
570 rv = 0
571 break
572 return rv
573
574#---------------------------------------------------------------------------
575# Handler classes and functions
576#---------------------------------------------------------------------------
577
578_handlers = {} #repository of handlers (for flushing when shutdown called)
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000579_handlerList = [] # added to allow handlers to be removed in reverse of order initialized
Guido van Rossum57102f82002-11-13 16:15:58 +0000580
581class Handler(Filterer):
582 """
583 Handler instances dispatch logging events to specific destinations.
584
585 The base handler class. Acts as a placeholder which defines the Handler
586 interface. Handlers can optionally use Formatter instances to format
587 records as desired. By default, no formatter is specified; in this case,
588 the 'raw' message as determined by record.message is logged.
589 """
590 def __init__(self, level=NOTSET):
591 """
592 Initializes the instance - basically setting the formatter to None
593 and the filter list to empty.
594 """
595 Filterer.__init__(self)
596 self.level = level
597 self.formatter = None
598 #get the module data lock, as we're updating a shared structure.
599 _acquireLock()
600 try: #unlikely to raise an exception, but you never know...
601 _handlers[self] = 1
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000602 _handlerList.insert(0, self)
Guido van Rossum57102f82002-11-13 16:15:58 +0000603 finally:
604 _releaseLock()
605 self.createLock()
606
607 def createLock(self):
608 """
609 Acquire a thread lock for serializing access to the underlying I/O.
610 """
611 if thread:
Vinay Sajip4a704862005-03-31 20:16:55 +0000612 self.lock = threading.RLock()
Guido van Rossum57102f82002-11-13 16:15:58 +0000613 else:
614 self.lock = None
615
616 def acquire(self):
617 """
618 Acquire the I/O thread lock.
619 """
620 if self.lock:
621 self.lock.acquire()
622
623 def release(self):
624 """
625 Release the I/O thread lock.
626 """
627 if self.lock:
628 self.lock.release()
629
630 def setLevel(self, level):
631 """
632 Set the logging level of this handler.
633 """
634 self.level = level
635
636 def format(self, record):
637 """
638 Format the specified record.
639
640 If a formatter is set, use it. Otherwise, use the default formatter
641 for the module.
642 """
643 if self.formatter:
644 fmt = self.formatter
645 else:
646 fmt = _defaultFormatter
647 return fmt.format(record)
648
649 def emit(self, record):
650 """
651 Do whatever it takes to actually log the specified logging record.
652
653 This version is intended to be implemented by subclasses and so
654 raises a NotImplementedError.
655 """
Collin Winterce36ad82007-08-30 01:19:48 +0000656 raise NotImplementedError('emit must be implemented '
657 'by Handler subclasses')
Guido van Rossum57102f82002-11-13 16:15:58 +0000658
659 def handle(self, record):
660 """
661 Conditionally emit the specified logging record.
662
663 Emission depends on filters which may have been added to the handler.
664 Wrap the actual emission of the record with acquisition/release of
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000665 the I/O thread lock. Returns whether the filter passed the record for
666 emission.
Guido van Rossum57102f82002-11-13 16:15:58 +0000667 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000668 rv = self.filter(record)
669 if rv:
Guido van Rossum57102f82002-11-13 16:15:58 +0000670 self.acquire()
671 try:
672 self.emit(record)
673 finally:
674 self.release()
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000675 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +0000676
677 def setFormatter(self, fmt):
678 """
679 Set the formatter for this handler.
680 """
681 self.formatter = fmt
682
683 def flush(self):
684 """
685 Ensure all logging output has been flushed.
686
687 This version does nothing and is intended to be implemented by
688 subclasses.
689 """
690 pass
691
692 def close(self):
693 """
694 Tidy up any resources used by the handler.
695
Vinay Sajiped6bb142004-02-20 13:18:36 +0000696 This version does removes the handler from an internal list
697 of handlers which is closed when shutdown() is called. Subclasses
698 should ensure that this gets called from overridden close()
699 methods.
Guido van Rossum57102f82002-11-13 16:15:58 +0000700 """
Vinay Sajiped6bb142004-02-20 13:18:36 +0000701 #get the module data lock, as we're updating a shared structure.
702 _acquireLock()
703 try: #unlikely to raise an exception, but you never know...
Vinay Sajipe0f85922006-02-07 13:55:52 +0000704 del _handlers[self]
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000705 _handlerList.remove(self)
Vinay Sajiped6bb142004-02-20 13:18:36 +0000706 finally:
707 _releaseLock()
Guido van Rossum57102f82002-11-13 16:15:58 +0000708
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000709 def handleError(self, record):
Guido van Rossum57102f82002-11-13 16:15:58 +0000710 """
711 Handle errors which occur during an emit() call.
712
713 This method should be called from handlers when an exception is
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000714 encountered during an emit() call. If raiseExceptions is false,
Guido van Rossum57102f82002-11-13 16:15:58 +0000715 exceptions get silently ignored. This is what is mostly wanted
716 for a logging system - most users will not care about errors in
717 the logging system, they are more interested in application errors.
718 You could, however, replace this with a custom handler if you wish.
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000719 The record which was being processed is passed in to this method.
Guido van Rossum57102f82002-11-13 16:15:58 +0000720 """
721 if raiseExceptions:
Guido van Rossum57102f82002-11-13 16:15:58 +0000722 ei = sys.exc_info()
723 traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
724 del ei
725
726class StreamHandler(Handler):
727 """
728 A handler class which writes logging records, appropriately formatted,
729 to a stream. Note that this class does not close the stream, as
730 sys.stdout or sys.stderr may be used.
731 """
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000732
Guido van Rossum57102f82002-11-13 16:15:58 +0000733 def __init__(self, strm=None):
734 """
735 Initialize the handler.
736
737 If strm is not specified, sys.stderr is used.
738 """
739 Handler.__init__(self)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000740 if strm is None:
Guido van Rossum57102f82002-11-13 16:15:58 +0000741 strm = sys.stderr
742 self.stream = strm
Guido van Rossum57102f82002-11-13 16:15:58 +0000743
744 def flush(self):
745 """
746 Flushes the stream.
747 """
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +0000748 if self.stream and hasattr(self.stream, "flush"):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000749 self.stream.flush()
Guido van Rossum57102f82002-11-13 16:15:58 +0000750
751 def emit(self, record):
752 """
753 Emit a record.
754
755 If a formatter is specified, it is used to format the record.
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000756 The record is then written to the stream with a trailing newline. If
757 exception information is present, it is formatted using
758 traceback.print_exception and appended to the stream. If the stream
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000759 has an 'encoding' attribute, it is used to determine how to do the
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000760 output to the stream.
Guido van Rossum57102f82002-11-13 16:15:58 +0000761 """
762 try:
763 msg = self.format(record)
Benjamin Petersonf91df042009-02-13 02:50:59 +0000764 stream = self.stream
Vinay Sajipb9591172004-09-22 12:39:26 +0000765 fs = "%s\n"
Guido van Rossum13257902007-06-07 23:15:56 +0000766 if not _unicode: #if no unicode support...
Benjamin Petersonf91df042009-02-13 02:50:59 +0000767 stream.write(fs % msg)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000768 else:
769 try:
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000770 if (isinstance(msg, unicode) and
771 getattr(stream, 'encoding', None)):
772 fs = fs.decode(stream.encoding)
773 try:
774 stream.write(fs % msg)
775 except UnicodeEncodeError:
776 #Printing to terminals sometimes fails. For example,
777 #with an encoding of 'cp1251', the above write will
778 #work if written to a stream opened or wrapped by
779 #the codecs module, but fail when writing to a
780 #terminal even when the codepage is set to cp1251.
781 #An extra encoding step seems to be needed.
782 stream.write((fs % msg).encode(stream.encoding))
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000783 else:
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000784 stream.write(fs % msg)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000785 except UnicodeError:
Benjamin Petersonf91df042009-02-13 02:50:59 +0000786 stream.write(fs % msg.encode("UTF-8"))
Guido van Rossum57102f82002-11-13 16:15:58 +0000787 self.flush()
Vinay Sajip85c19092005-10-31 13:14:19 +0000788 except (KeyboardInterrupt, SystemExit):
789 raise
Guido van Rossum57102f82002-11-13 16:15:58 +0000790 except:
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000791 self.handleError(record)
Guido van Rossum57102f82002-11-13 16:15:58 +0000792
793class FileHandler(StreamHandler):
794 """
795 A handler class which writes formatted logging records to disk files.
796 """
Christian Heimese7a15bb2008-01-24 16:21:45 +0000797 def __init__(self, filename, mode='a', encoding=None, delay=0):
Guido van Rossum57102f82002-11-13 16:15:58 +0000798 """
799 Open the specified file and use it as the stream for logging.
800 """
Vinay Sajip4bbab2b2004-07-08 10:22:35 +0000801 #keep the absolute path, otherwise derived classes which use this
802 #may come a cropper when the current directory changes
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000803 if codecs is None:
804 encoding = None
Vinay Sajip4bbab2b2004-07-08 10:22:35 +0000805 self.baseFilename = os.path.abspath(filename)
Guido van Rossum57102f82002-11-13 16:15:58 +0000806 self.mode = mode
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000807 self.encoding = encoding
Christian Heimese7a15bb2008-01-24 16:21:45 +0000808 if delay:
Vinay Sajip6268cbc2009-01-21 00:19:28 +0000809 #We don't open the stream, but we still need to call the
810 #Handler constructor to set level, formatter, lock etc.
811 Handler.__init__(self)
Christian Heimese7a15bb2008-01-24 16:21:45 +0000812 self.stream = None
813 else:
Vinay Sajip6268cbc2009-01-21 00:19:28 +0000814 StreamHandler.__init__(self, self._open())
Guido van Rossum57102f82002-11-13 16:15:58 +0000815
816 def close(self):
817 """
818 Closes the stream.
819 """
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000820 if self.stream:
821 self.flush()
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +0000822 if hasattr(self.stream, "close"):
823 self.stream.close()
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000824 StreamHandler.close(self)
825 self.stream = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000826
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000827 def _open(self):
828 """
829 Open the current base file with the (original) mode and encoding.
830 Return the resulting stream.
831 """
832 if self.encoding is None:
833 stream = open(self.baseFilename, self.mode)
834 else:
835 stream = codecs.open(self.baseFilename, self.mode, self.encoding)
836 return stream
837
Christian Heimese7a15bb2008-01-24 16:21:45 +0000838 def emit(self, record):
839 """
840 Emit a record.
841
842 If the stream was not opened because 'delay' was specified in the
843 constructor, open it before calling the superclass's emit.
844 """
845 if self.stream is None:
Vinay Sajip6268cbc2009-01-21 00:19:28 +0000846 self.stream = self._open()
Christian Heimese7a15bb2008-01-24 16:21:45 +0000847 StreamHandler.emit(self, record)
848
Guido van Rossum57102f82002-11-13 16:15:58 +0000849#---------------------------------------------------------------------------
850# Manager classes and functions
851#---------------------------------------------------------------------------
852
853class PlaceHolder:
854 """
855 PlaceHolder instances are used in the Manager logger hierarchy to take
Vinay Sajip3f742842004-02-28 16:07:46 +0000856 the place of nodes for which no loggers have been defined. This class is
857 intended for internal use only and not as part of the public API.
Guido van Rossum57102f82002-11-13 16:15:58 +0000858 """
859 def __init__(self, alogger):
860 """
861 Initialize with the specified logger being a child of this placeholder.
862 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000863 #self.loggers = [alogger]
864 self.loggerMap = { alogger : None }
Guido van Rossum57102f82002-11-13 16:15:58 +0000865
866 def append(self, alogger):
867 """
868 Add the specified logger as a child of this placeholder.
869 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000870 #if alogger not in self.loggers:
Guido van Rossum93662412006-08-19 16:09:41 +0000871 if alogger not in self.loggerMap:
Vinay Sajip239322b2005-10-14 09:36:35 +0000872 #self.loggers.append(alogger)
873 self.loggerMap[alogger] = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000874
875#
876# Determine which class to use when instantiating loggers.
877#
878_loggerClass = None
879
880def setLoggerClass(klass):
881 """
882 Set the class to be used when instantiating a logger. The class should
883 define __init__() such that only a name argument is required, and the
884 __init__() should call Logger.__init__()
885 """
886 if klass != Logger:
Guido van Rossum57102f82002-11-13 16:15:58 +0000887 if not issubclass(klass, Logger):
Collin Winterce36ad82007-08-30 01:19:48 +0000888 raise TypeError("logger not derived from logging.Logger: "
889 + klass.__name__)
Guido van Rossum57102f82002-11-13 16:15:58 +0000890 global _loggerClass
891 _loggerClass = klass
892
Vinay Sajipb9591172004-09-22 12:39:26 +0000893def getLoggerClass():
894 """
895 Return the class to be used when instantiating a logger.
896 """
897
898 return _loggerClass
899
Guido van Rossum57102f82002-11-13 16:15:58 +0000900class Manager:
901 """
902 There is [under normal circumstances] just one Manager instance, which
903 holds the hierarchy of loggers.
904 """
Neal Norwitzd1cade02002-11-15 23:31:28 +0000905 def __init__(self, rootnode):
Guido van Rossum57102f82002-11-13 16:15:58 +0000906 """
907 Initialize the manager with the root node of the logger hierarchy.
908 """
Neal Norwitzd1cade02002-11-15 23:31:28 +0000909 self.root = rootnode
Guido van Rossum57102f82002-11-13 16:15:58 +0000910 self.disable = 0
911 self.emittedNoHandlerWarning = 0
912 self.loggerDict = {}
913
914 def getLogger(self, name):
915 """
916 Get a logger with the specified name (channel name), creating it
Vinay Sajipb9591172004-09-22 12:39:26 +0000917 if it doesn't yet exist. This name is a dot-separated hierarchical
918 name, such as "a", "a.b", "a.b.c" or similar.
Guido van Rossum57102f82002-11-13 16:15:58 +0000919
920 If a PlaceHolder existed for the specified name [i.e. the logger
921 didn't exist but a child of it did], replace it with the created
922 logger and fix up the parent/child references which pointed to the
923 placeholder to now point to the logger.
924 """
925 rv = None
926 _acquireLock()
927 try:
Guido van Rossum93662412006-08-19 16:09:41 +0000928 if name in self.loggerDict:
Guido van Rossum57102f82002-11-13 16:15:58 +0000929 rv = self.loggerDict[name]
930 if isinstance(rv, PlaceHolder):
931 ph = rv
932 rv = _loggerClass(name)
933 rv.manager = self
934 self.loggerDict[name] = rv
935 self._fixupChildren(ph, rv)
936 self._fixupParents(rv)
937 else:
938 rv = _loggerClass(name)
939 rv.manager = self
940 self.loggerDict[name] = rv
941 self._fixupParents(rv)
942 finally:
943 _releaseLock()
944 return rv
945
946 def _fixupParents(self, alogger):
947 """
948 Ensure that there are either loggers or placeholders all the way
949 from the specified logger to the root of the logger hierarchy.
950 """
951 name = alogger.name
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000952 i = name.rfind(".")
Guido van Rossum57102f82002-11-13 16:15:58 +0000953 rv = None
954 while (i > 0) and not rv:
955 substr = name[:i]
Guido van Rossum93662412006-08-19 16:09:41 +0000956 if substr not in self.loggerDict:
Guido van Rossum57102f82002-11-13 16:15:58 +0000957 self.loggerDict[substr] = PlaceHolder(alogger)
958 else:
959 obj = self.loggerDict[substr]
960 if isinstance(obj, Logger):
961 rv = obj
962 else:
963 assert isinstance(obj, PlaceHolder)
964 obj.append(alogger)
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000965 i = name.rfind(".", 0, i - 1)
Guido van Rossum57102f82002-11-13 16:15:58 +0000966 if not rv:
967 rv = self.root
968 alogger.parent = rv
969
970 def _fixupChildren(self, ph, alogger):
971 """
972 Ensure that children of the placeholder ph are connected to the
973 specified logger.
974 """
Thomas Wouters89f507f2006-12-13 04:49:30 +0000975 name = alogger.name
976 namelen = len(name)
Vinay Sajip239322b2005-10-14 09:36:35 +0000977 for c in ph.loggerMap.keys():
Thomas Wouters89f507f2006-12-13 04:49:30 +0000978 #The if means ... if not c.parent.name.startswith(nm)
979 if c.parent.name[:namelen] != name:
Guido van Rossum57102f82002-11-13 16:15:58 +0000980 alogger.parent = c.parent
981 c.parent = alogger
982
983#---------------------------------------------------------------------------
984# Logger classes and functions
985#---------------------------------------------------------------------------
986
987class Logger(Filterer):
988 """
989 Instances of the Logger class represent a single logging channel. A
990 "logging channel" indicates an area of an application. Exactly how an
991 "area" is defined is up to the application developer. Since an
992 application can have any number of areas, logging channels are identified
993 by a unique string. Application areas can be nested (e.g. an area
994 of "input processing" might include sub-areas "read CSV files", "read
995 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
996 channel names are organized into a namespace hierarchy where levels are
997 separated by periods, much like the Java or Python package namespace. So
998 in the instance given above, channel names might be "input" for the upper
999 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
1000 There is no arbitrary limit to the depth of nesting.
1001 """
1002 def __init__(self, name, level=NOTSET):
1003 """
1004 Initialize the logger with a name and an optional level.
1005 """
1006 Filterer.__init__(self)
1007 self.name = name
1008 self.level = level
1009 self.parent = None
1010 self.propagate = 1
1011 self.handlers = []
1012 self.disabled = 0
1013
1014 def setLevel(self, level):
1015 """
1016 Set the logging level of this logger.
1017 """
1018 self.level = level
1019
Guido van Rossum57102f82002-11-13 16:15:58 +00001020 def debug(self, msg, *args, **kwargs):
1021 """
1022 Log 'msg % args' with severity 'DEBUG'.
1023
1024 To pass exception information, use the keyword argument exc_info with
1025 a true value, e.g.
1026
1027 logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
1028 """
Guido van Rossum04110fb2007-08-24 16:32:05 +00001029 if self.isEnabledFor(DEBUG):
Neal Norwitzd9108552006-03-17 08:00:19 +00001030 self._log(DEBUG, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001031
1032 def info(self, msg, *args, **kwargs):
1033 """
1034 Log 'msg % args' with severity 'INFO'.
1035
1036 To pass exception information, use the keyword argument exc_info with
1037 a true value, e.g.
1038
1039 logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
1040 """
Guido van Rossum04110fb2007-08-24 16:32:05 +00001041 if self.isEnabledFor(INFO):
Neal Norwitzd9108552006-03-17 08:00:19 +00001042 self._log(INFO, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001043
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001044 def warning(self, msg, *args, **kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001045 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001046 Log 'msg % args' with severity 'WARNING'.
Guido van Rossum57102f82002-11-13 16:15:58 +00001047
1048 To pass exception information, use the keyword argument exc_info with
1049 a true value, e.g.
1050
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001051 logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
Guido van Rossum57102f82002-11-13 16:15:58 +00001052 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001053 if self.isEnabledFor(WARNING):
Neal Norwitzd9108552006-03-17 08:00:19 +00001054 self._log(WARNING, msg, args, **kwargs)
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001055
1056 warn = warning
Guido van Rossum57102f82002-11-13 16:15:58 +00001057
1058 def error(self, msg, *args, **kwargs):
1059 """
1060 Log 'msg % args' with severity 'ERROR'.
1061
1062 To pass exception information, use the keyword argument exc_info with
1063 a true value, e.g.
1064
1065 logger.error("Houston, we have a %s", "major problem", exc_info=1)
1066 """
Guido van Rossum57102f82002-11-13 16:15:58 +00001067 if self.isEnabledFor(ERROR):
Neal Norwitzd9108552006-03-17 08:00:19 +00001068 self._log(ERROR, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001069
1070 def exception(self, msg, *args):
1071 """
1072 Convenience method for logging an ERROR with exception information.
1073 """
Neal Norwitz7c307242006-03-17 08:28:24 +00001074 self.error(msg, exc_info=1, *args)
Guido van Rossum57102f82002-11-13 16:15:58 +00001075
1076 def critical(self, msg, *args, **kwargs):
1077 """
1078 Log 'msg % args' with severity 'CRITICAL'.
1079
1080 To pass exception information, use the keyword argument exc_info with
1081 a true value, e.g.
1082
1083 logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1084 """
Guido van Rossum04110fb2007-08-24 16:32:05 +00001085 if self.isEnabledFor(CRITICAL):
Neal Norwitzd9108552006-03-17 08:00:19 +00001086 self._log(CRITICAL, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001087
1088 fatal = critical
1089
1090 def log(self, level, msg, *args, **kwargs):
1091 """
Vinay Sajipeb477d02004-08-04 08:38:08 +00001092 Log 'msg % args' with the integer severity 'level'.
Guido van Rossum57102f82002-11-13 16:15:58 +00001093
1094 To pass exception information, use the keyword argument exc_info with
1095 a true value, e.g.
1096
1097 logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1098 """
Guido van Rossum13257902007-06-07 23:15:56 +00001099 if not isinstance(level, int):
Vinay Sajip779e0c92004-07-03 11:47:26 +00001100 if raiseExceptions:
Collin Winterce36ad82007-08-30 01:19:48 +00001101 raise TypeError("level must be an integer")
Vinay Sajip779e0c92004-07-03 11:47:26 +00001102 else:
1103 return
Guido van Rossum57102f82002-11-13 16:15:58 +00001104 if self.isEnabledFor(level):
Neal Norwitzd9108552006-03-17 08:00:19 +00001105 self._log(level, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001106
1107 def findCaller(self):
1108 """
1109 Find the stack frame of the caller so that we can note the source
Vinay Sajip829dc512005-02-18 11:53:32 +00001110 file name, line number and function name.
Guido van Rossum57102f82002-11-13 16:15:58 +00001111 """
Vinay Sajip829dc512005-02-18 11:53:32 +00001112 f = currentframe().f_back
Thomas Woutersa9773292006-04-21 09:43:23 +00001113 rv = "(unknown file)", 0, "(unknown function)"
1114 while hasattr(f, "f_code"):
Jeremy Hylton250684d2003-01-23 18:29:29 +00001115 co = f.f_code
1116 filename = os.path.normcase(co.co_filename)
1117 if filename == _srcfile:
1118 f = f.f_back
1119 continue
Thomas Woutersa9773292006-04-21 09:43:23 +00001120 rv = (filename, f.f_lineno, co.co_name)
1121 break
1122 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +00001123
Vinay Sajiped1992f2006-02-09 08:48:36 +00001124 def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
Guido van Rossum57102f82002-11-13 16:15:58 +00001125 """
1126 A factory method which can be overridden in subclasses to create
1127 specialized LogRecords.
1128 """
Vinay Sajiped1992f2006-02-09 08:48:36 +00001129 rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
Christian Heimes04c420f2008-01-18 18:40:46 +00001130 if extra is not None:
Vinay Sajip260ce432006-02-09 08:34:14 +00001131 for key in extra:
1132 if (key in ["message", "asctime"]) or (key in rv.__dict__):
1133 raise KeyError("Attempt to overwrite %r in LogRecord" % key)
1134 rv.__dict__[key] = extra[key]
1135 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +00001136
Vinay Sajip260ce432006-02-09 08:34:14 +00001137 def _log(self, level, msg, args, exc_info=None, extra=None):
Guido van Rossum57102f82002-11-13 16:15:58 +00001138 """
1139 Low-level logging routine which creates a LogRecord and then calls
1140 all the handlers of this logger to handle the record.
1141 """
Jeremy Hylton250684d2003-01-23 18:29:29 +00001142 if _srcfile:
Vinay Sajipb672b6d2009-02-19 12:36:11 +00001143 #IronPython doesn't track Python frames, so findCaller throws an
1144 #exception. We trap it here so that IronPython can use logging.
1145 try:
1146 fn, lno, func = self.findCaller()
1147 except ValueError:
1148 fn, lno, func = "(unknown file)", 0, "(unknown function)"
Guido van Rossum57102f82002-11-13 16:15:58 +00001149 else:
Vinay Sajip829dc512005-02-18 11:53:32 +00001150 fn, lno, func = "(unknown file)", 0, "(unknown function)"
Guido van Rossum57102f82002-11-13 16:15:58 +00001151 if exc_info:
Guido van Rossum13257902007-06-07 23:15:56 +00001152 if not isinstance(exc_info, tuple):
Vinay Sajiped6bb142004-02-20 13:18:36 +00001153 exc_info = sys.exc_info()
Vinay Sajiped1992f2006-02-09 08:48:36 +00001154 record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
Guido van Rossum57102f82002-11-13 16:15:58 +00001155 self.handle(record)
1156
1157 def handle(self, record):
1158 """
1159 Call the handlers for the specified record.
1160
1161 This method is used for unpickled records received from a socket, as
1162 well as those created locally. Logger-level filtering is applied.
1163 """
1164 if (not self.disabled) and self.filter(record):
1165 self.callHandlers(record)
1166
1167 def addHandler(self, hdlr):
1168 """
1169 Add the specified handler to this logger.
1170 """
1171 if not (hdlr in self.handlers):
1172 self.handlers.append(hdlr)
1173
1174 def removeHandler(self, hdlr):
1175 """
1176 Remove the specified handler from this logger.
1177 """
1178 if hdlr in self.handlers:
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001179 #hdlr.close()
Vinay Sajip116f16e2005-09-16 10:33:40 +00001180 hdlr.acquire()
1181 try:
1182 self.handlers.remove(hdlr)
1183 finally:
1184 hdlr.release()
Guido van Rossum57102f82002-11-13 16:15:58 +00001185
1186 def callHandlers(self, record):
1187 """
1188 Pass a record to all relevant handlers.
1189
1190 Loop through all handlers for this logger and its parents in the
1191 logger hierarchy. If no handler was found, output a one-off error
1192 message to sys.stderr. Stop searching up the hierarchy whenever a
1193 logger with the "propagate" attribute set to zero is found - that
1194 will be the last logger whose handlers are called.
1195 """
1196 c = self
1197 found = 0
1198 while c:
1199 for hdlr in c.handlers:
1200 found = found + 1
1201 if record.levelno >= hdlr.level:
1202 hdlr.handle(record)
1203 if not c.propagate:
1204 c = None #break out
1205 else:
1206 c = c.parent
Vinay Sajip1e86beb2005-10-23 22:32:59 +00001207 if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
Guido van Rossum57102f82002-11-13 16:15:58 +00001208 sys.stderr.write("No handlers could be found for logger"
1209 " \"%s\"\n" % self.name)
1210 self.manager.emittedNoHandlerWarning = 1
1211
1212 def getEffectiveLevel(self):
1213 """
1214 Get the effective level for this logger.
1215
1216 Loop through this logger and its parents in the logger hierarchy,
1217 looking for a non-zero logging level. Return the first one found.
1218 """
1219 logger = self
1220 while logger:
1221 if logger.level:
1222 return logger.level
1223 logger = logger.parent
1224 return NOTSET
1225
1226 def isEnabledFor(self, level):
1227 """
1228 Is this logger enabled for level 'level'?
1229 """
1230 if self.manager.disable >= level:
1231 return 0
1232 return level >= self.getEffectiveLevel()
1233
1234class RootLogger(Logger):
1235 """
1236 A root logger is not that different to any other logger, except that
1237 it must have a logging level and there is only one instance of it in
1238 the hierarchy.
1239 """
1240 def __init__(self, level):
1241 """
1242 Initialize the logger with the name "root".
1243 """
1244 Logger.__init__(self, "root", level)
1245
1246_loggerClass = Logger
1247
Christian Heimes04c420f2008-01-18 18:40:46 +00001248class LoggerAdapter:
1249 """
1250 An adapter for loggers which makes it easier to specify contextual
1251 information in logging output.
1252 """
1253
1254 def __init__(self, logger, extra):
1255 """
1256 Initialize the adapter with a logger and a dict-like object which
1257 provides contextual information. This constructor signature allows
1258 easy stacking of LoggerAdapters, if so desired.
1259
1260 You can effectively pass keyword arguments as shown in the
1261 following example:
1262
1263 adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
1264 """
1265 self.logger = logger
1266 self.extra = extra
1267
1268 def process(self, msg, kwargs):
1269 """
1270 Process the logging message and keyword arguments passed in to
1271 a logging call to insert contextual information. You can either
1272 manipulate the message itself, the keyword args or both. Return
1273 the message and kwargs modified (or not) to suit your needs.
1274
1275 Normally, you'll only need to override this one method in a
1276 LoggerAdapter subclass for your specific needs.
1277 """
1278 kwargs["extra"] = self.extra
1279 return msg, kwargs
1280
1281 def debug(self, msg, *args, **kwargs):
1282 """
1283 Delegate a debug call to the underlying logger, after adding
1284 contextual information from this adapter instance.
1285 """
1286 msg, kwargs = self.process(msg, kwargs)
1287 self.logger.debug(msg, *args, **kwargs)
1288
1289 def info(self, msg, *args, **kwargs):
1290 """
1291 Delegate an info call to the underlying logger, after adding
1292 contextual information from this adapter instance.
1293 """
1294 msg, kwargs = self.process(msg, kwargs)
1295 self.logger.info(msg, *args, **kwargs)
1296
1297 def warning(self, msg, *args, **kwargs):
1298 """
1299 Delegate a warning call to the underlying logger, after adding
1300 contextual information from this adapter instance.
1301 """
1302 msg, kwargs = self.process(msg, kwargs)
1303 self.logger.warning(msg, *args, **kwargs)
1304
1305 def error(self, msg, *args, **kwargs):
1306 """
1307 Delegate an error call to the underlying logger, after adding
1308 contextual information from this adapter instance.
1309 """
1310 msg, kwargs = self.process(msg, kwargs)
1311 self.logger.error(msg, *args, **kwargs)
1312
1313 def exception(self, msg, *args, **kwargs):
1314 """
1315 Delegate an exception call to the underlying logger, after adding
1316 contextual information from this adapter instance.
1317 """
1318 msg, kwargs = self.process(msg, kwargs)
1319 kwargs["exc_info"] = 1
1320 self.logger.error(msg, *args, **kwargs)
1321
1322 def critical(self, msg, *args, **kwargs):
1323 """
1324 Delegate a critical call to the underlying logger, after adding
1325 contextual information from this adapter instance.
1326 """
1327 msg, kwargs = self.process(msg, kwargs)
1328 self.logger.critical(msg, *args, **kwargs)
1329
1330 def log(self, level, msg, *args, **kwargs):
1331 """
1332 Delegate a log call to the underlying logger, after adding
1333 contextual information from this adapter instance.
1334 """
1335 msg, kwargs = self.process(msg, kwargs)
1336 self.logger.log(level, msg, *args, **kwargs)
1337
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001338root = RootLogger(WARNING)
Guido van Rossum57102f82002-11-13 16:15:58 +00001339Logger.root = root
1340Logger.manager = Manager(Logger.root)
1341
1342#---------------------------------------------------------------------------
1343# Configuration classes and functions
1344#---------------------------------------------------------------------------
1345
1346BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
1347
Vinay Sajip779e0c92004-07-03 11:47:26 +00001348def basicConfig(**kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001349 """
Vinay Sajip779e0c92004-07-03 11:47:26 +00001350 Do basic configuration for the logging system.
1351
1352 This function does nothing if the root logger already has handlers
1353 configured. It is a convenience method intended for use by simple scripts
1354 to do one-shot configuration of the logging package.
1355
1356 The default behaviour is to create a StreamHandler which writes to
1357 sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1358 add the handler to the root logger.
1359
1360 A number of optional keyword arguments may be specified, which can alter
1361 the default behaviour.
1362
1363 filename Specifies that a FileHandler be created, using the specified
1364 filename, rather than a StreamHandler.
1365 filemode Specifies the mode to open the file, if filename is specified
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001366 (if filemode is unspecified, it defaults to 'a').
Vinay Sajip779e0c92004-07-03 11:47:26 +00001367 format Use the specified format string for the handler.
1368 datefmt Use the specified date/time format.
1369 level Set the root logger level to the specified level.
1370 stream Use the specified stream to initialize the StreamHandler. Note
1371 that this argument is incompatible with 'filename' - if both
1372 are present, 'stream' is ignored.
1373
1374 Note that you could specify a stream created using open(filename, mode)
1375 rather than passing the filename and mode in. However, it should be
1376 remembered that StreamHandler does not close its stream (since it may be
1377 using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1378 when the handler is closed.
Guido van Rossum57102f82002-11-13 16:15:58 +00001379 """
1380 if len(root.handlers) == 0:
Vinay Sajip779e0c92004-07-03 11:47:26 +00001381 filename = kwargs.get("filename")
1382 if filename:
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001383 mode = kwargs.get("filemode", 'a')
Vinay Sajip779e0c92004-07-03 11:47:26 +00001384 hdlr = FileHandler(filename, mode)
1385 else:
1386 stream = kwargs.get("stream")
1387 hdlr = StreamHandler(stream)
1388 fs = kwargs.get("format", BASIC_FORMAT)
1389 dfs = kwargs.get("datefmt", None)
1390 fmt = Formatter(fs, dfs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001391 hdlr.setFormatter(fmt)
1392 root.addHandler(hdlr)
Vinay Sajip779e0c92004-07-03 11:47:26 +00001393 level = kwargs.get("level")
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001394 if level is not None:
Tim Peters4e0e1b62004-07-07 20:54:48 +00001395 root.setLevel(level)
Guido van Rossum57102f82002-11-13 16:15:58 +00001396
1397#---------------------------------------------------------------------------
1398# Utility functions at module level.
1399# Basically delegate everything to the root logger.
1400#---------------------------------------------------------------------------
1401
1402def getLogger(name=None):
1403 """
1404 Return a logger with the specified name, creating it if necessary.
1405
1406 If no name is specified, return the root logger.
1407 """
1408 if name:
1409 return Logger.manager.getLogger(name)
1410 else:
1411 return root
1412
1413#def getRootLogger():
1414# """
1415# Return the root logger.
1416#
1417# Note that getLogger('') now does the same thing, so this function is
1418# deprecated and may disappear in the future.
1419# """
1420# return root
1421
1422def critical(msg, *args, **kwargs):
1423 """
1424 Log a message with severity 'CRITICAL' on the root logger.
1425 """
1426 if len(root.handlers) == 0:
1427 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001428 root.critical(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001429
1430fatal = critical
1431
1432def error(msg, *args, **kwargs):
1433 """
1434 Log a message with severity 'ERROR' on the root logger.
1435 """
1436 if len(root.handlers) == 0:
1437 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001438 root.error(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001439
1440def exception(msg, *args):
1441 """
1442 Log a message with severity 'ERROR' on the root logger,
1443 with exception information.
1444 """
Neal Norwitz7c307242006-03-17 08:28:24 +00001445 error(msg, exc_info=1, *args)
Guido van Rossum57102f82002-11-13 16:15:58 +00001446
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001447def warning(msg, *args, **kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001448 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001449 Log a message with severity 'WARNING' on the root logger.
Guido van Rossum57102f82002-11-13 16:15:58 +00001450 """
1451 if len(root.handlers) == 0:
1452 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001453 root.warning(msg, *args, **kwargs)
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001454
1455warn = warning
Guido van Rossum57102f82002-11-13 16:15:58 +00001456
1457def info(msg, *args, **kwargs):
1458 """
1459 Log a message with severity 'INFO' on the root logger.
1460 """
1461 if len(root.handlers) == 0:
1462 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001463 root.info(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001464
1465def debug(msg, *args, **kwargs):
1466 """
1467 Log a message with severity 'DEBUG' on the root logger.
1468 """
1469 if len(root.handlers) == 0:
1470 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001471 root.debug(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001472
Vinay Sajipb2635b22004-09-24 11:45:52 +00001473def log(level, msg, *args, **kwargs):
1474 """
1475 Log 'msg % args' with the integer severity 'level' on the root logger.
1476 """
1477 if len(root.handlers) == 0:
1478 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001479 root.log(level, msg, *args, **kwargs)
Vinay Sajipb2635b22004-09-24 11:45:52 +00001480
Guido van Rossum57102f82002-11-13 16:15:58 +00001481def disable(level):
1482 """
1483 Disable all logging calls less severe than 'level'.
1484 """
1485 root.manager.disable = level
1486
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001487def shutdown(handlerList=_handlerList):
Guido van Rossum57102f82002-11-13 16:15:58 +00001488 """
1489 Perform any cleanup actions in the logging system (e.g. flushing
1490 buffers).
1491
1492 Should be called at application exit.
1493 """
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001494 for h in handlerList[:]:
Vinay Sajipe12f7152004-07-29 09:19:30 +00001495 #errors might occur, for example, if files are locked
Vinay Sajip260ce432006-02-09 08:34:14 +00001496 #we just ignore them if raiseExceptions is not set
Vinay Sajipe12f7152004-07-29 09:19:30 +00001497 try:
1498 h.flush()
1499 h.close()
1500 except:
Vinay Sajip260ce432006-02-09 08:34:14 +00001501 if raiseExceptions:
1502 raise
1503 #else, swallow
Vinay Sajiped6bb142004-02-20 13:18:36 +00001504
1505#Let's try and shutdown automatically on application exit...
1506try:
1507 import atexit
1508 atexit.register(shutdown)
1509except ImportError: # for Python versions < 2.0
1510 def exithook(status, old_exit=sys.exit):
1511 try:
1512 shutdown()
1513 finally:
1514 old_exit(status)
1515
1516 sys.exit = exithook
Georg Brandlf9734072008-12-07 15:30:06 +00001517
1518# Null handler
1519
1520class NullHandler(Handler):
1521 """
1522 This handler does nothing. It's intended to be used to avoid the
1523 "No handlers could be found for logger XXX" one-off warning. This is
1524 important for library code, which may contain code to log events. If a user
1525 of the library does not configure logging, the one-off warning might be
1526 produced; to avoid this, the library developer simply needs to instantiate
1527 a NullHandler and add it to the top-level logger of the library module or
1528 package.
1529 """
1530 def emit(self, record):
1531 pass
1532
1533# Warnings integration
1534
1535_warnings_showwarning = None
1536
1537def _showwarning(message, category, filename, lineno, file=None, line=None):
1538 """
1539 Implementation of showwarnings which redirects to logging, which will first
1540 check to see if the file parameter is None. If a file is specified, it will
1541 delegate to the original warnings implementation of showwarning. Otherwise,
1542 it will call warnings.formatwarning and will log the resulting string to a
1543 warnings logger named "py.warnings" with level logging.WARNING.
1544 """
1545 if file is not None:
1546 if _warnings_showwarning is not None:
1547 _warnings_showwarning(message, category, filename, lineno, file, line)
1548 else:
1549 s = warnings.formatwarning(message, category, filename, lineno, line)
1550 logger = getLogger("py.warnings")
1551 if not logger.handlers:
1552 logger.addHandler(NullHandler())
1553 logger.warning("%s", s)
1554
1555def captureWarnings(capture):
1556 """
1557 If capture is true, redirect all warnings to the logging package.
1558 If capture is False, ensure that warnings are not redirected to logging
1559 but to their original destinations.
1560 """
1561 global _warnings_showwarning
1562 if capture:
1563 if _warnings_showwarning is None:
1564 _warnings_showwarning = warnings.showwarning
1565 warnings.showwarning = _showwarning
1566 else:
1567 if _warnings_showwarning is not None:
1568 warnings.showwarning = _warnings_showwarning
1569 _warnings_showwarning = None