blob: 5072019d31b24535b0ad92e5e742f429fb948777 [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
Vinay Sajipd4fabf42009-07-13 11:28:25 +0000179def _checkLevel(level):
180 if isinstance(level, int):
181 rv = level
182 elif str(level) == level:
183 if level not in _levelNames:
184 raise ValueError("Unknown level: %r" % level)
185 rv = _levelNames[level]
186 else:
187 raise TypeError("Level not an integer or a valid string: %r" % level)
188 return rv
189
Guido van Rossum57102f82002-11-13 16:15:58 +0000190#---------------------------------------------------------------------------
191# Thread-related stuff
192#---------------------------------------------------------------------------
193
194#
195#_lock is used to serialize access to shared data structures in this module.
196#This needs to be an RLock because fileConfig() creates Handlers and so
197#might arbitrary user threads. Since Handler.__init__() updates the shared
198#dictionary _handlers, it needs to acquire the lock. But if configuring,
199#the lock would already have been acquired - so we need an RLock.
200#The same argument applies to Loggers and Manager.loggerDict.
201#
202_lock = None
203
204def _acquireLock():
205 """
206 Acquire the module-level lock for serializing access to shared data.
207
208 This should be released with _releaseLock().
209 """
210 global _lock
211 if (not _lock) and thread:
212 _lock = threading.RLock()
213 if _lock:
214 _lock.acquire()
215
216def _releaseLock():
217 """
218 Release the module-level lock acquired by calling _acquireLock().
219 """
220 if _lock:
221 _lock.release()
222
223#---------------------------------------------------------------------------
224# The logging record
225#---------------------------------------------------------------------------
226
227class LogRecord:
228 """
229 A LogRecord instance represents an event being logged.
230
231 LogRecord instances are created every time something is logged. They
232 contain all the information pertinent to the event being logged. The
233 main information passed in is in msg and args, which are combined
234 using str(msg) % args to create the message field of the record. The
235 record also includes information such as when the record was created,
236 the source line where the logging call was made, and any exception
237 information to be logged.
238 """
Vinay Sajiped1992f2006-02-09 08:48:36 +0000239 def __init__(self, name, level, pathname, lineno,
Thomas Wouters89f507f2006-12-13 04:49:30 +0000240 msg, args, exc_info, func=None):
Guido van Rossum57102f82002-11-13 16:15:58 +0000241 """
242 Initialize a logging record with interesting information.
243 """
244 ct = time.time()
245 self.name = name
246 self.msg = msg
Vinay Sajip4ed315a2004-10-20 08:39:40 +0000247 #
248 # The following statement allows passing of a dictionary as a sole
249 # argument, so that you can do something like
250 # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
251 # Suggested by Stefan Behnel.
252 # Note that without the test for args[0], we get a problem because
253 # during formatting, we test to see if the arg is present using
254 # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
255 # and if the passed arg fails 'if self.args:' then no formatting
256 # is done. For example, logger.warn('Value is %d', 0) would log
257 # 'Value is %d' instead of 'Value is 0'.
258 # For the use case of passing a dictionary, this should not be a
259 # problem.
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000260 if args and len(args) == 1 and isinstance(args[0], dict) and args[0]:
Vinay Sajip4ed315a2004-10-20 08:39:40 +0000261 args = args[0]
Guido van Rossum57102f82002-11-13 16:15:58 +0000262 self.args = args
263 self.levelname = getLevelName(level)
264 self.levelno = level
265 self.pathname = pathname
266 try:
267 self.filename = os.path.basename(pathname)
268 self.module = os.path.splitext(self.filename)[0]
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000269 except (TypeError, ValueError, AttributeError):
Guido van Rossum57102f82002-11-13 16:15:58 +0000270 self.filename = pathname
271 self.module = "Unknown module"
272 self.exc_info = exc_info
Vinay Sajiped6bb142004-02-20 13:18:36 +0000273 self.exc_text = None # used to cache the traceback text
Guido van Rossum57102f82002-11-13 16:15:58 +0000274 self.lineno = lineno
Vinay Sajiped1992f2006-02-09 08:48:36 +0000275 self.funcName = func
Guido van Rossum57102f82002-11-13 16:15:58 +0000276 self.created = ct
Guido van Rossume2a383d2007-01-15 16:59:06 +0000277 self.msecs = (ct - int(ct)) * 1000
Guido van Rossum57102f82002-11-13 16:15:58 +0000278 self.relativeCreated = (self.created - _startTime) * 1000
Vinay Sajipd364a072006-03-13 22:05:28 +0000279 if logThreads and thread:
Guido van Rossum57102f82002-11-13 16:15:58 +0000280 self.thread = thread.get_ident()
Benjamin Peterson72753702008-08-18 18:09:21 +0000281 self.threadName = threading.current_thread().name
Guido van Rossum57102f82002-11-13 16:15:58 +0000282 else:
283 self.thread = None
Vinay Sajip4a704862005-03-31 20:16:55 +0000284 self.threadName = None
Jesse Noller9a0fc972009-01-18 21:12:58 +0000285 if logMultiprocessing:
286 from multiprocessing import current_process
287 self.processName = current_process().name
288 else:
289 self.processName = None
Vinay Sajipd364a072006-03-13 22:05:28 +0000290 if logProcesses and hasattr(os, 'getpid'):
Jack Jansen4c641d02003-02-21 22:29:45 +0000291 self.process = os.getpid()
292 else:
293 self.process = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000294
295 def __str__(self):
296 return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
297 self.pathname, self.lineno, self.msg)
298
299 def getMessage(self):
300 """
301 Return the message for this LogRecord.
302
303 Return the message for this LogRecord after merging any user-supplied
304 arguments with the message.
305 """
Guido van Rossum13257902007-06-07 23:15:56 +0000306 if not _unicode: #if no unicode support...
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000307 msg = str(self.msg)
308 else:
Vinay Sajip43d6e812005-10-07 08:35:36 +0000309 msg = self.msg
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000310 if not isinstance(msg, str):
Vinay Sajip43d6e812005-10-07 08:35:36 +0000311 try:
312 msg = str(self.msg)
313 except UnicodeError:
314 msg = self.msg #Defer encoding till later
Guido van Rossum57102f82002-11-13 16:15:58 +0000315 if self.args:
316 msg = msg % self.args
317 return msg
318
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +0000319def makeLogRecord(dict):
320 """
321 Make a LogRecord whose attributes are defined by the specified dictionary,
322 This function is useful for converting a logging event received over
323 a socket connection (which is sent as a dictionary) into a LogRecord
324 instance.
325 """
Vinay Sajiped1992f2006-02-09 08:48:36 +0000326 rv = LogRecord(None, None, "", 0, "", (), None, None)
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +0000327 rv.__dict__.update(dict)
328 return rv
329
Guido van Rossum57102f82002-11-13 16:15:58 +0000330#---------------------------------------------------------------------------
331# Formatter classes and functions
332#---------------------------------------------------------------------------
333
334class Formatter:
335 """
336 Formatter instances are used to convert a LogRecord to text.
337
338 Formatters need to know how a LogRecord is constructed. They are
339 responsible for converting a LogRecord to (usually) a string which can
340 be interpreted by either a human or an external system. The base Formatter
341 allows a formatting string to be specified. If none is supplied, the
342 default value of "%s(message)\\n" is used.
343
344 The Formatter can be initialized with a format string which makes use of
345 knowledge of the LogRecord attributes - e.g. the default value mentioned
346 above makes use of the fact that the user's message and arguments are pre-
347 formatted into a LogRecord's message attribute. Currently, the useful
348 attributes in a LogRecord are described by:
349
350 %(name)s Name of the logger (logging channel)
351 %(levelno)s Numeric logging level for the message (DEBUG, INFO,
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000352 WARNING, ERROR, CRITICAL)
Guido van Rossum57102f82002-11-13 16:15:58 +0000353 %(levelname)s Text logging level for the message ("DEBUG", "INFO",
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000354 "WARNING", "ERROR", "CRITICAL")
Guido van Rossum57102f82002-11-13 16:15:58 +0000355 %(pathname)s Full pathname of the source file where the logging
356 call was issued (if available)
357 %(filename)s Filename portion of pathname
358 %(module)s Module (name portion of filename)
359 %(lineno)d Source line number where the logging call was issued
360 (if available)
Vinay Sajiped1992f2006-02-09 08:48:36 +0000361 %(funcName)s Function name
Guido van Rossum57102f82002-11-13 16:15:58 +0000362 %(created)f Time when the LogRecord was created (time.time()
363 return value)
364 %(asctime)s Textual time when the LogRecord was created
365 %(msecs)d Millisecond portion of the creation time
366 %(relativeCreated)d Time in milliseconds when the LogRecord was created,
367 relative to the time the logging module was loaded
368 (typically at application startup time)
369 %(thread)d Thread ID (if available)
Vinay Sajip4a704862005-03-31 20:16:55 +0000370 %(threadName)s Thread name (if available)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000371 %(process)d Process ID (if available)
Guido van Rossum57102f82002-11-13 16:15:58 +0000372 %(message)s The result of record.getMessage(), computed just as
373 the record is emitted
374 """
375
376 converter = time.localtime
377
378 def __init__(self, fmt=None, datefmt=None):
379 """
380 Initialize the formatter with specified format strings.
381
382 Initialize the formatter either with the specified format string, or a
383 default as described above. Allow for specialized date formatting with
384 the optional datefmt argument (if omitted, you get the ISO8601 format).
385 """
386 if fmt:
387 self._fmt = fmt
388 else:
389 self._fmt = "%(message)s"
390 self.datefmt = datefmt
391
392 def formatTime(self, record, datefmt=None):
393 """
394 Return the creation time of the specified LogRecord as formatted text.
395
396 This method should be called from format() by a formatter which
397 wants to make use of a formatted time. This method can be overridden
398 in formatters to provide for any specific requirement, but the
399 basic behaviour is as follows: if datefmt (a string) is specified,
400 it is used with time.strftime() to format the creation time of the
401 record. Otherwise, the ISO8601 format is used. The resulting
402 string is returned. This function uses a user-configurable function
403 to convert the creation time to a tuple. By default, time.localtime()
404 is used; to change this for a particular formatter instance, set the
405 'converter' attribute to a function with the same signature as
406 time.localtime() or time.gmtime(). To change it for all formatters,
407 for example if you want all logging times to be shown in GMT,
408 set the 'converter' attribute in the Formatter class.
409 """
410 ct = self.converter(record.created)
411 if datefmt:
412 s = time.strftime(datefmt, ct)
413 else:
414 t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
415 s = "%s,%03d" % (t, record.msecs)
416 return s
417
418 def formatException(self, ei):
419 """
420 Format and return the specified exception information as a string.
421
422 This default implementation just uses
423 traceback.print_exception()
424 """
Guido van Rossum34d19282007-08-09 01:03:29 +0000425 sio = io.StringIO()
Guido van Rossum57102f82002-11-13 16:15:58 +0000426 traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
427 s = sio.getvalue()
428 sio.close()
Guido van Rossum486364b2007-06-30 05:01:58 +0000429 if s[-1:] == "\n":
Guido van Rossum57102f82002-11-13 16:15:58 +0000430 s = s[:-1]
431 return s
432
433 def format(self, record):
434 """
435 Format the specified record as text.
436
437 The record's attribute dictionary is used as the operand to a
438 string formatting operation which yields the returned string.
439 Before formatting the dictionary, a couple of preparatory steps
440 are carried out. The message attribute of the record is computed
441 using LogRecord.getMessage(). If the formatting string contains
442 "%(asctime)", formatTime() is called to format the event time.
443 If there is exception information, it is formatted using
444 formatException() and appended to the message.
445 """
446 record.message = record.getMessage()
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000447 if self._fmt.find("%(asctime)") >= 0:
Guido van Rossum57102f82002-11-13 16:15:58 +0000448 record.asctime = self.formatTime(record, self.datefmt)
449 s = self._fmt % record.__dict__
450 if record.exc_info:
Vinay Sajiped6bb142004-02-20 13:18:36 +0000451 # Cache the traceback text to avoid converting it multiple times
452 # (it's constant anyway)
453 if not record.exc_text:
454 record.exc_text = self.formatException(record.exc_info)
455 if record.exc_text:
Guido van Rossum486364b2007-06-30 05:01:58 +0000456 if s[-1:] != "\n":
Guido van Rossum57102f82002-11-13 16:15:58 +0000457 s = s + "\n"
Vinay Sajiped6bb142004-02-20 13:18:36 +0000458 s = s + record.exc_text
Guido van Rossum57102f82002-11-13 16:15:58 +0000459 return s
460
461#
462# The default formatter to use when no other is specified
463#
464_defaultFormatter = Formatter()
465
466class BufferingFormatter:
467 """
468 A formatter suitable for formatting a number of records.
469 """
470 def __init__(self, linefmt=None):
471 """
472 Optionally specify a formatter which will be used to format each
473 individual record.
474 """
475 if linefmt:
476 self.linefmt = linefmt
477 else:
478 self.linefmt = _defaultFormatter
479
480 def formatHeader(self, records):
481 """
482 Return the header string for the specified records.
483 """
484 return ""
485
486 def formatFooter(self, records):
487 """
488 Return the footer string for the specified records.
489 """
490 return ""
491
492 def format(self, records):
493 """
494 Format the specified records and return the result as a string.
495 """
496 rv = ""
497 if len(records) > 0:
498 rv = rv + self.formatHeader(records)
499 for record in records:
500 rv = rv + self.linefmt.format(record)
501 rv = rv + self.formatFooter(records)
502 return rv
503
504#---------------------------------------------------------------------------
505# Filter classes and functions
506#---------------------------------------------------------------------------
507
508class Filter:
509 """
510 Filter instances are used to perform arbitrary filtering of LogRecords.
511
512 Loggers and Handlers can optionally use Filter instances to filter
513 records as desired. The base filter class only allows events which are
514 below a certain point in the logger hierarchy. For example, a filter
515 initialized with "A.B" will allow events logged by loggers "A.B",
516 "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
517 initialized with the empty string, all events are passed.
518 """
519 def __init__(self, name=''):
520 """
521 Initialize a filter.
522
523 Initialize with the name of the logger which, together with its
524 children, will have its events allowed through the filter. If no
525 name is specified, allow every event.
526 """
527 self.name = name
528 self.nlen = len(name)
529
530 def filter(self, record):
531 """
532 Determine if the specified record is to be logged.
533
534 Is the specified record to be logged? Returns 0 for no, nonzero for
535 yes. If deemed appropriate, the record may be modified in-place.
536 """
537 if self.nlen == 0:
538 return 1
539 elif self.name == record.name:
540 return 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000541 elif record.name.find(self.name, 0, self.nlen) != 0:
Guido van Rossum57102f82002-11-13 16:15:58 +0000542 return 0
543 return (record.name[self.nlen] == ".")
544
545class Filterer:
546 """
547 A base class for loggers and handlers which allows them to share
548 common code.
549 """
550 def __init__(self):
551 """
552 Initialize the list of filters to be an empty list.
553 """
554 self.filters = []
555
556 def addFilter(self, filter):
557 """
558 Add the specified filter to this handler.
559 """
560 if not (filter in self.filters):
561 self.filters.append(filter)
562
563 def removeFilter(self, filter):
564 """
565 Remove the specified filter from this handler.
566 """
567 if filter in self.filters:
568 self.filters.remove(filter)
569
570 def filter(self, record):
571 """
572 Determine if a record is loggable by consulting all the filters.
573
574 The default is to allow the record to be logged; any filter can veto
575 this and the record is then dropped. Returns a zero value if a record
576 is to be dropped, else non-zero.
577 """
578 rv = 1
579 for f in self.filters:
580 if not f.filter(record):
581 rv = 0
582 break
583 return rv
584
585#---------------------------------------------------------------------------
586# Handler classes and functions
587#---------------------------------------------------------------------------
588
589_handlers = {} #repository of handlers (for flushing when shutdown called)
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000590_handlerList = [] # added to allow handlers to be removed in reverse of order initialized
Guido van Rossum57102f82002-11-13 16:15:58 +0000591
592class Handler(Filterer):
593 """
594 Handler instances dispatch logging events to specific destinations.
595
596 The base handler class. Acts as a placeholder which defines the Handler
597 interface. Handlers can optionally use Formatter instances to format
598 records as desired. By default, no formatter is specified; in this case,
599 the 'raw' message as determined by record.message is logged.
600 """
601 def __init__(self, level=NOTSET):
602 """
603 Initializes the instance - basically setting the formatter to None
604 and the filter list to empty.
605 """
606 Filterer.__init__(self)
Vinay Sajipd4fabf42009-07-13 11:28:25 +0000607 self.level = _checkLevel(level)
Guido van Rossum57102f82002-11-13 16:15:58 +0000608 self.formatter = None
609 #get the module data lock, as we're updating a shared structure.
610 _acquireLock()
611 try: #unlikely to raise an exception, but you never know...
612 _handlers[self] = 1
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000613 _handlerList.insert(0, self)
Guido van Rossum57102f82002-11-13 16:15:58 +0000614 finally:
615 _releaseLock()
616 self.createLock()
617
618 def createLock(self):
619 """
620 Acquire a thread lock for serializing access to the underlying I/O.
621 """
622 if thread:
Vinay Sajip4a704862005-03-31 20:16:55 +0000623 self.lock = threading.RLock()
Guido van Rossum57102f82002-11-13 16:15:58 +0000624 else:
625 self.lock = None
626
627 def acquire(self):
628 """
629 Acquire the I/O thread lock.
630 """
631 if self.lock:
632 self.lock.acquire()
633
634 def release(self):
635 """
636 Release the I/O thread lock.
637 """
638 if self.lock:
639 self.lock.release()
640
641 def setLevel(self, level):
642 """
643 Set the logging level of this handler.
644 """
Vinay Sajipd4fabf42009-07-13 11:28:25 +0000645 self.level = _checkLevel(level)
Guido van Rossum57102f82002-11-13 16:15:58 +0000646
647 def format(self, record):
648 """
649 Format the specified record.
650
651 If a formatter is set, use it. Otherwise, use the default formatter
652 for the module.
653 """
654 if self.formatter:
655 fmt = self.formatter
656 else:
657 fmt = _defaultFormatter
658 return fmt.format(record)
659
660 def emit(self, record):
661 """
662 Do whatever it takes to actually log the specified logging record.
663
664 This version is intended to be implemented by subclasses and so
665 raises a NotImplementedError.
666 """
Collin Winterce36ad82007-08-30 01:19:48 +0000667 raise NotImplementedError('emit must be implemented '
668 'by Handler subclasses')
Guido van Rossum57102f82002-11-13 16:15:58 +0000669
670 def handle(self, record):
671 """
672 Conditionally emit the specified logging record.
673
674 Emission depends on filters which may have been added to the handler.
675 Wrap the actual emission of the record with acquisition/release of
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000676 the I/O thread lock. Returns whether the filter passed the record for
677 emission.
Guido van Rossum57102f82002-11-13 16:15:58 +0000678 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000679 rv = self.filter(record)
680 if rv:
Guido van Rossum57102f82002-11-13 16:15:58 +0000681 self.acquire()
682 try:
683 self.emit(record)
684 finally:
685 self.release()
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000686 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +0000687
688 def setFormatter(self, fmt):
689 """
690 Set the formatter for this handler.
691 """
692 self.formatter = fmt
693
694 def flush(self):
695 """
696 Ensure all logging output has been flushed.
697
698 This version does nothing and is intended to be implemented by
699 subclasses.
700 """
701 pass
702
703 def close(self):
704 """
705 Tidy up any resources used by the handler.
706
Vinay Sajiped6bb142004-02-20 13:18:36 +0000707 This version does removes the handler from an internal list
708 of handlers which is closed when shutdown() is called. Subclasses
709 should ensure that this gets called from overridden close()
710 methods.
Guido van Rossum57102f82002-11-13 16:15:58 +0000711 """
Vinay Sajiped6bb142004-02-20 13:18:36 +0000712 #get the module data lock, as we're updating a shared structure.
713 _acquireLock()
714 try: #unlikely to raise an exception, but you never know...
Vinay Sajipe0f85922006-02-07 13:55:52 +0000715 del _handlers[self]
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000716 _handlerList.remove(self)
Vinay Sajiped6bb142004-02-20 13:18:36 +0000717 finally:
718 _releaseLock()
Guido van Rossum57102f82002-11-13 16:15:58 +0000719
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000720 def handleError(self, record):
Guido van Rossum57102f82002-11-13 16:15:58 +0000721 """
722 Handle errors which occur during an emit() call.
723
724 This method should be called from handlers when an exception is
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000725 encountered during an emit() call. If raiseExceptions is false,
Guido van Rossum57102f82002-11-13 16:15:58 +0000726 exceptions get silently ignored. This is what is mostly wanted
727 for a logging system - most users will not care about errors in
728 the logging system, they are more interested in application errors.
729 You could, however, replace this with a custom handler if you wish.
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000730 The record which was being processed is passed in to this method.
Guido van Rossum57102f82002-11-13 16:15:58 +0000731 """
732 if raiseExceptions:
Guido van Rossum57102f82002-11-13 16:15:58 +0000733 ei = sys.exc_info()
Benjamin Petersonfa0d7032009-06-01 22:42:33 +0000734 try:
735 traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
736 except IOError:
737 pass # see issue 5971
738 finally:
739 del ei
Guido van Rossum57102f82002-11-13 16:15:58 +0000740
741class StreamHandler(Handler):
742 """
743 A handler class which writes logging records, appropriately formatted,
744 to a stream. Note that this class does not close the stream, as
745 sys.stdout or sys.stderr may be used.
746 """
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000747
Guido van Rossum57102f82002-11-13 16:15:58 +0000748 def __init__(self, strm=None):
749 """
750 Initialize the handler.
751
752 If strm is not specified, sys.stderr is used.
753 """
754 Handler.__init__(self)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000755 if strm is None:
Guido van Rossum57102f82002-11-13 16:15:58 +0000756 strm = sys.stderr
757 self.stream = strm
Guido van Rossum57102f82002-11-13 16:15:58 +0000758
759 def flush(self):
760 """
761 Flushes the stream.
762 """
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +0000763 if self.stream and hasattr(self.stream, "flush"):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000764 self.stream.flush()
Guido van Rossum57102f82002-11-13 16:15:58 +0000765
766 def emit(self, record):
767 """
768 Emit a record.
769
770 If a formatter is specified, it is used to format the record.
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000771 The record is then written to the stream with a trailing newline. If
772 exception information is present, it is formatted using
773 traceback.print_exception and appended to the stream. If the stream
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000774 has an 'encoding' attribute, it is used to determine how to do the
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000775 output to the stream.
Guido van Rossum57102f82002-11-13 16:15:58 +0000776 """
777 try:
778 msg = self.format(record)
Benjamin Petersonf91df042009-02-13 02:50:59 +0000779 stream = self.stream
Vinay Sajipb9591172004-09-22 12:39:26 +0000780 fs = "%s\n"
Guido van Rossum13257902007-06-07 23:15:56 +0000781 if not _unicode: #if no unicode support...
Benjamin Petersonf91df042009-02-13 02:50:59 +0000782 stream.write(fs % msg)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000783 else:
784 try:
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000785 if (isinstance(msg, unicode) and
786 getattr(stream, 'encoding', None)):
787 fs = fs.decode(stream.encoding)
788 try:
789 stream.write(fs % msg)
790 except UnicodeEncodeError:
791 #Printing to terminals sometimes fails. For example,
792 #with an encoding of 'cp1251', the above write will
793 #work if written to a stream opened or wrapped by
794 #the codecs module, but fail when writing to a
795 #terminal even when the codepage is set to cp1251.
796 #An extra encoding step seems to be needed.
797 stream.write((fs % msg).encode(stream.encoding))
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000798 else:
Benjamin Peterson25c95f12009-05-08 20:42:26 +0000799 stream.write(fs % msg)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000800 except UnicodeError:
Benjamin Petersonf91df042009-02-13 02:50:59 +0000801 stream.write(fs % msg.encode("UTF-8"))
Guido van Rossum57102f82002-11-13 16:15:58 +0000802 self.flush()
Vinay Sajip85c19092005-10-31 13:14:19 +0000803 except (KeyboardInterrupt, SystemExit):
804 raise
Guido van Rossum57102f82002-11-13 16:15:58 +0000805 except:
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000806 self.handleError(record)
Guido van Rossum57102f82002-11-13 16:15:58 +0000807
808class FileHandler(StreamHandler):
809 """
810 A handler class which writes formatted logging records to disk files.
811 """
Christian Heimese7a15bb2008-01-24 16:21:45 +0000812 def __init__(self, filename, mode='a', encoding=None, delay=0):
Guido van Rossum57102f82002-11-13 16:15:58 +0000813 """
814 Open the specified file and use it as the stream for logging.
815 """
Vinay Sajip4bbab2b2004-07-08 10:22:35 +0000816 #keep the absolute path, otherwise derived classes which use this
817 #may come a cropper when the current directory changes
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000818 if codecs is None:
819 encoding = None
Vinay Sajip4bbab2b2004-07-08 10:22:35 +0000820 self.baseFilename = os.path.abspath(filename)
Guido van Rossum57102f82002-11-13 16:15:58 +0000821 self.mode = mode
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000822 self.encoding = encoding
Christian Heimese7a15bb2008-01-24 16:21:45 +0000823 if delay:
Vinay Sajip6268cbc2009-01-21 00:19:28 +0000824 #We don't open the stream, but we still need to call the
825 #Handler constructor to set level, formatter, lock etc.
826 Handler.__init__(self)
Christian Heimese7a15bb2008-01-24 16:21:45 +0000827 self.stream = None
828 else:
Vinay Sajip6268cbc2009-01-21 00:19:28 +0000829 StreamHandler.__init__(self, self._open())
Guido van Rossum57102f82002-11-13 16:15:58 +0000830
831 def close(self):
832 """
833 Closes the stream.
834 """
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000835 if self.stream:
836 self.flush()
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +0000837 if hasattr(self.stream, "close"):
838 self.stream.close()
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000839 StreamHandler.close(self)
840 self.stream = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000841
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000842 def _open(self):
843 """
844 Open the current base file with the (original) mode and encoding.
845 Return the resulting stream.
846 """
847 if self.encoding is None:
848 stream = open(self.baseFilename, self.mode)
849 else:
850 stream = codecs.open(self.baseFilename, self.mode, self.encoding)
851 return stream
852
Christian Heimese7a15bb2008-01-24 16:21:45 +0000853 def emit(self, record):
854 """
855 Emit a record.
856
857 If the stream was not opened because 'delay' was specified in the
858 constructor, open it before calling the superclass's emit.
859 """
860 if self.stream is None:
Vinay Sajip6268cbc2009-01-21 00:19:28 +0000861 self.stream = self._open()
Christian Heimese7a15bb2008-01-24 16:21:45 +0000862 StreamHandler.emit(self, record)
863
Guido van Rossum57102f82002-11-13 16:15:58 +0000864#---------------------------------------------------------------------------
865# Manager classes and functions
866#---------------------------------------------------------------------------
867
868class PlaceHolder:
869 """
870 PlaceHolder instances are used in the Manager logger hierarchy to take
Vinay Sajip3f742842004-02-28 16:07:46 +0000871 the place of nodes for which no loggers have been defined. This class is
872 intended for internal use only and not as part of the public API.
Guido van Rossum57102f82002-11-13 16:15:58 +0000873 """
874 def __init__(self, alogger):
875 """
876 Initialize with the specified logger being a child of this placeholder.
877 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000878 #self.loggers = [alogger]
879 self.loggerMap = { alogger : None }
Guido van Rossum57102f82002-11-13 16:15:58 +0000880
881 def append(self, alogger):
882 """
883 Add the specified logger as a child of this placeholder.
884 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000885 #if alogger not in self.loggers:
Guido van Rossum93662412006-08-19 16:09:41 +0000886 if alogger not in self.loggerMap:
Vinay Sajip239322b2005-10-14 09:36:35 +0000887 #self.loggers.append(alogger)
888 self.loggerMap[alogger] = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000889
890#
891# Determine which class to use when instantiating loggers.
892#
893_loggerClass = None
894
895def setLoggerClass(klass):
896 """
897 Set the class to be used when instantiating a logger. The class should
898 define __init__() such that only a name argument is required, and the
899 __init__() should call Logger.__init__()
900 """
901 if klass != Logger:
Guido van Rossum57102f82002-11-13 16:15:58 +0000902 if not issubclass(klass, Logger):
Collin Winterce36ad82007-08-30 01:19:48 +0000903 raise TypeError("logger not derived from logging.Logger: "
904 + klass.__name__)
Guido van Rossum57102f82002-11-13 16:15:58 +0000905 global _loggerClass
906 _loggerClass = klass
907
Vinay Sajipb9591172004-09-22 12:39:26 +0000908def getLoggerClass():
909 """
910 Return the class to be used when instantiating a logger.
911 """
912
913 return _loggerClass
914
Guido van Rossum57102f82002-11-13 16:15:58 +0000915class Manager:
916 """
917 There is [under normal circumstances] just one Manager instance, which
918 holds the hierarchy of loggers.
919 """
Neal Norwitzd1cade02002-11-15 23:31:28 +0000920 def __init__(self, rootnode):
Guido van Rossum57102f82002-11-13 16:15:58 +0000921 """
922 Initialize the manager with the root node of the logger hierarchy.
923 """
Neal Norwitzd1cade02002-11-15 23:31:28 +0000924 self.root = rootnode
Guido van Rossum57102f82002-11-13 16:15:58 +0000925 self.disable = 0
926 self.emittedNoHandlerWarning = 0
927 self.loggerDict = {}
928
929 def getLogger(self, name):
930 """
931 Get a logger with the specified name (channel name), creating it
Vinay Sajipb9591172004-09-22 12:39:26 +0000932 if it doesn't yet exist. This name is a dot-separated hierarchical
933 name, such as "a", "a.b", "a.b.c" or similar.
Guido van Rossum57102f82002-11-13 16:15:58 +0000934
935 If a PlaceHolder existed for the specified name [i.e. the logger
936 didn't exist but a child of it did], replace it with the created
937 logger and fix up the parent/child references which pointed to the
938 placeholder to now point to the logger.
939 """
940 rv = None
941 _acquireLock()
942 try:
Guido van Rossum93662412006-08-19 16:09:41 +0000943 if name in self.loggerDict:
Guido van Rossum57102f82002-11-13 16:15:58 +0000944 rv = self.loggerDict[name]
945 if isinstance(rv, PlaceHolder):
946 ph = rv
947 rv = _loggerClass(name)
948 rv.manager = self
949 self.loggerDict[name] = rv
950 self._fixupChildren(ph, rv)
951 self._fixupParents(rv)
952 else:
953 rv = _loggerClass(name)
954 rv.manager = self
955 self.loggerDict[name] = rv
956 self._fixupParents(rv)
957 finally:
958 _releaseLock()
959 return rv
960
961 def _fixupParents(self, alogger):
962 """
963 Ensure that there are either loggers or placeholders all the way
964 from the specified logger to the root of the logger hierarchy.
965 """
966 name = alogger.name
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000967 i = name.rfind(".")
Guido van Rossum57102f82002-11-13 16:15:58 +0000968 rv = None
969 while (i > 0) and not rv:
970 substr = name[:i]
Guido van Rossum93662412006-08-19 16:09:41 +0000971 if substr not in self.loggerDict:
Guido van Rossum57102f82002-11-13 16:15:58 +0000972 self.loggerDict[substr] = PlaceHolder(alogger)
973 else:
974 obj = self.loggerDict[substr]
975 if isinstance(obj, Logger):
976 rv = obj
977 else:
978 assert isinstance(obj, PlaceHolder)
979 obj.append(alogger)
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000980 i = name.rfind(".", 0, i - 1)
Guido van Rossum57102f82002-11-13 16:15:58 +0000981 if not rv:
982 rv = self.root
983 alogger.parent = rv
984
985 def _fixupChildren(self, ph, alogger):
986 """
987 Ensure that children of the placeholder ph are connected to the
988 specified logger.
989 """
Thomas Wouters89f507f2006-12-13 04:49:30 +0000990 name = alogger.name
991 namelen = len(name)
Vinay Sajip239322b2005-10-14 09:36:35 +0000992 for c in ph.loggerMap.keys():
Thomas Wouters89f507f2006-12-13 04:49:30 +0000993 #The if means ... if not c.parent.name.startswith(nm)
994 if c.parent.name[:namelen] != name:
Guido van Rossum57102f82002-11-13 16:15:58 +0000995 alogger.parent = c.parent
996 c.parent = alogger
997
998#---------------------------------------------------------------------------
999# Logger classes and functions
1000#---------------------------------------------------------------------------
1001
1002class Logger(Filterer):
1003 """
1004 Instances of the Logger class represent a single logging channel. A
1005 "logging channel" indicates an area of an application. Exactly how an
1006 "area" is defined is up to the application developer. Since an
1007 application can have any number of areas, logging channels are identified
1008 by a unique string. Application areas can be nested (e.g. an area
1009 of "input processing" might include sub-areas "read CSV files", "read
1010 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
1011 channel names are organized into a namespace hierarchy where levels are
1012 separated by periods, much like the Java or Python package namespace. So
1013 in the instance given above, channel names might be "input" for the upper
1014 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
1015 There is no arbitrary limit to the depth of nesting.
1016 """
1017 def __init__(self, name, level=NOTSET):
1018 """
1019 Initialize the logger with a name and an optional level.
1020 """
1021 Filterer.__init__(self)
1022 self.name = name
Vinay Sajipd4fabf42009-07-13 11:28:25 +00001023 self.level = _checkLevel(level)
Guido van Rossum57102f82002-11-13 16:15:58 +00001024 self.parent = None
1025 self.propagate = 1
1026 self.handlers = []
1027 self.disabled = 0
1028
1029 def setLevel(self, level):
1030 """
1031 Set the logging level of this logger.
1032 """
Vinay Sajipd4fabf42009-07-13 11:28:25 +00001033 self.level = _checkLevel(level)
Guido van Rossum57102f82002-11-13 16:15:58 +00001034
Guido van Rossum57102f82002-11-13 16:15:58 +00001035 def debug(self, msg, *args, **kwargs):
1036 """
1037 Log 'msg % args' with severity 'DEBUG'.
1038
1039 To pass exception information, use the keyword argument exc_info with
1040 a true value, e.g.
1041
1042 logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
1043 """
Guido van Rossum04110fb2007-08-24 16:32:05 +00001044 if self.isEnabledFor(DEBUG):
Neal Norwitzd9108552006-03-17 08:00:19 +00001045 self._log(DEBUG, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001046
1047 def info(self, msg, *args, **kwargs):
1048 """
1049 Log 'msg % args' with severity 'INFO'.
1050
1051 To pass exception information, use the keyword argument exc_info with
1052 a true value, e.g.
1053
1054 logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
1055 """
Guido van Rossum04110fb2007-08-24 16:32:05 +00001056 if self.isEnabledFor(INFO):
Neal Norwitzd9108552006-03-17 08:00:19 +00001057 self._log(INFO, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001058
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001059 def warning(self, msg, *args, **kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001060 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001061 Log 'msg % args' with severity 'WARNING'.
Guido van Rossum57102f82002-11-13 16:15:58 +00001062
1063 To pass exception information, use the keyword argument exc_info with
1064 a true value, e.g.
1065
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001066 logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
Guido van Rossum57102f82002-11-13 16:15:58 +00001067 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001068 if self.isEnabledFor(WARNING):
Neal Norwitzd9108552006-03-17 08:00:19 +00001069 self._log(WARNING, msg, args, **kwargs)
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001070
1071 warn = warning
Guido van Rossum57102f82002-11-13 16:15:58 +00001072
1073 def error(self, msg, *args, **kwargs):
1074 """
1075 Log 'msg % args' with severity 'ERROR'.
1076
1077 To pass exception information, use the keyword argument exc_info with
1078 a true value, e.g.
1079
1080 logger.error("Houston, we have a %s", "major problem", exc_info=1)
1081 """
Guido van Rossum57102f82002-11-13 16:15:58 +00001082 if self.isEnabledFor(ERROR):
Neal Norwitzd9108552006-03-17 08:00:19 +00001083 self._log(ERROR, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001084
1085 def exception(self, msg, *args):
1086 """
1087 Convenience method for logging an ERROR with exception information.
1088 """
Neal Norwitz7c307242006-03-17 08:28:24 +00001089 self.error(msg, exc_info=1, *args)
Guido van Rossum57102f82002-11-13 16:15:58 +00001090
1091 def critical(self, msg, *args, **kwargs):
1092 """
1093 Log 'msg % args' with severity 'CRITICAL'.
1094
1095 To pass exception information, use the keyword argument exc_info with
1096 a true value, e.g.
1097
1098 logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1099 """
Guido van Rossum04110fb2007-08-24 16:32:05 +00001100 if self.isEnabledFor(CRITICAL):
Neal Norwitzd9108552006-03-17 08:00:19 +00001101 self._log(CRITICAL, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001102
1103 fatal = critical
1104
1105 def log(self, level, msg, *args, **kwargs):
1106 """
Vinay Sajipeb477d02004-08-04 08:38:08 +00001107 Log 'msg % args' with the integer severity 'level'.
Guido van Rossum57102f82002-11-13 16:15:58 +00001108
1109 To pass exception information, use the keyword argument exc_info with
1110 a true value, e.g.
1111
1112 logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1113 """
Guido van Rossum13257902007-06-07 23:15:56 +00001114 if not isinstance(level, int):
Vinay Sajip779e0c92004-07-03 11:47:26 +00001115 if raiseExceptions:
Collin Winterce36ad82007-08-30 01:19:48 +00001116 raise TypeError("level must be an integer")
Vinay Sajip779e0c92004-07-03 11:47:26 +00001117 else:
1118 return
Guido van Rossum57102f82002-11-13 16:15:58 +00001119 if self.isEnabledFor(level):
Neal Norwitzd9108552006-03-17 08:00:19 +00001120 self._log(level, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001121
1122 def findCaller(self):
1123 """
1124 Find the stack frame of the caller so that we can note the source
Vinay Sajip829dc512005-02-18 11:53:32 +00001125 file name, line number and function name.
Guido van Rossum57102f82002-11-13 16:15:58 +00001126 """
Vinay Sajip829dc512005-02-18 11:53:32 +00001127 f = currentframe().f_back
Thomas Woutersa9773292006-04-21 09:43:23 +00001128 rv = "(unknown file)", 0, "(unknown function)"
1129 while hasattr(f, "f_code"):
Jeremy Hylton250684d2003-01-23 18:29:29 +00001130 co = f.f_code
1131 filename = os.path.normcase(co.co_filename)
1132 if filename == _srcfile:
1133 f = f.f_back
1134 continue
Thomas Woutersa9773292006-04-21 09:43:23 +00001135 rv = (filename, f.f_lineno, co.co_name)
1136 break
1137 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +00001138
Vinay Sajiped1992f2006-02-09 08:48:36 +00001139 def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
Guido van Rossum57102f82002-11-13 16:15:58 +00001140 """
1141 A factory method which can be overridden in subclasses to create
1142 specialized LogRecords.
1143 """
Vinay Sajiped1992f2006-02-09 08:48:36 +00001144 rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
Christian Heimes04c420f2008-01-18 18:40:46 +00001145 if extra is not None:
Vinay Sajip260ce432006-02-09 08:34:14 +00001146 for key in extra:
1147 if (key in ["message", "asctime"]) or (key in rv.__dict__):
1148 raise KeyError("Attempt to overwrite %r in LogRecord" % key)
1149 rv.__dict__[key] = extra[key]
1150 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +00001151
Vinay Sajip260ce432006-02-09 08:34:14 +00001152 def _log(self, level, msg, args, exc_info=None, extra=None):
Guido van Rossum57102f82002-11-13 16:15:58 +00001153 """
1154 Low-level logging routine which creates a LogRecord and then calls
1155 all the handlers of this logger to handle the record.
1156 """
Jeremy Hylton250684d2003-01-23 18:29:29 +00001157 if _srcfile:
Vinay Sajipb672b6d2009-02-19 12:36:11 +00001158 #IronPython doesn't track Python frames, so findCaller throws an
1159 #exception. We trap it here so that IronPython can use logging.
1160 try:
1161 fn, lno, func = self.findCaller()
1162 except ValueError:
1163 fn, lno, func = "(unknown file)", 0, "(unknown function)"
Guido van Rossum57102f82002-11-13 16:15:58 +00001164 else:
Vinay Sajip829dc512005-02-18 11:53:32 +00001165 fn, lno, func = "(unknown file)", 0, "(unknown function)"
Guido van Rossum57102f82002-11-13 16:15:58 +00001166 if exc_info:
Guido van Rossum13257902007-06-07 23:15:56 +00001167 if not isinstance(exc_info, tuple):
Vinay Sajiped6bb142004-02-20 13:18:36 +00001168 exc_info = sys.exc_info()
Vinay Sajiped1992f2006-02-09 08:48:36 +00001169 record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
Guido van Rossum57102f82002-11-13 16:15:58 +00001170 self.handle(record)
1171
1172 def handle(self, record):
1173 """
1174 Call the handlers for the specified record.
1175
1176 This method is used for unpickled records received from a socket, as
1177 well as those created locally. Logger-level filtering is applied.
1178 """
1179 if (not self.disabled) and self.filter(record):
1180 self.callHandlers(record)
1181
1182 def addHandler(self, hdlr):
1183 """
1184 Add the specified handler to this logger.
1185 """
1186 if not (hdlr in self.handlers):
1187 self.handlers.append(hdlr)
1188
1189 def removeHandler(self, hdlr):
1190 """
1191 Remove the specified handler from this logger.
1192 """
1193 if hdlr in self.handlers:
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001194 #hdlr.close()
Vinay Sajip116f16e2005-09-16 10:33:40 +00001195 hdlr.acquire()
1196 try:
1197 self.handlers.remove(hdlr)
1198 finally:
1199 hdlr.release()
Guido van Rossum57102f82002-11-13 16:15:58 +00001200
1201 def callHandlers(self, record):
1202 """
1203 Pass a record to all relevant handlers.
1204
1205 Loop through all handlers for this logger and its parents in the
1206 logger hierarchy. If no handler was found, output a one-off error
1207 message to sys.stderr. Stop searching up the hierarchy whenever a
1208 logger with the "propagate" attribute set to zero is found - that
1209 will be the last logger whose handlers are called.
1210 """
1211 c = self
1212 found = 0
1213 while c:
1214 for hdlr in c.handlers:
1215 found = found + 1
1216 if record.levelno >= hdlr.level:
1217 hdlr.handle(record)
1218 if not c.propagate:
1219 c = None #break out
1220 else:
1221 c = c.parent
Vinay Sajip1e86beb2005-10-23 22:32:59 +00001222 if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
Guido van Rossum57102f82002-11-13 16:15:58 +00001223 sys.stderr.write("No handlers could be found for logger"
1224 " \"%s\"\n" % self.name)
1225 self.manager.emittedNoHandlerWarning = 1
1226
1227 def getEffectiveLevel(self):
1228 """
1229 Get the effective level for this logger.
1230
1231 Loop through this logger and its parents in the logger hierarchy,
1232 looking for a non-zero logging level. Return the first one found.
1233 """
1234 logger = self
1235 while logger:
1236 if logger.level:
1237 return logger.level
1238 logger = logger.parent
1239 return NOTSET
1240
1241 def isEnabledFor(self, level):
1242 """
1243 Is this logger enabled for level 'level'?
1244 """
1245 if self.manager.disable >= level:
1246 return 0
1247 return level >= self.getEffectiveLevel()
1248
1249class RootLogger(Logger):
1250 """
1251 A root logger is not that different to any other logger, except that
1252 it must have a logging level and there is only one instance of it in
1253 the hierarchy.
1254 """
1255 def __init__(self, level):
1256 """
1257 Initialize the logger with the name "root".
1258 """
1259 Logger.__init__(self, "root", level)
1260
1261_loggerClass = Logger
1262
Christian Heimes04c420f2008-01-18 18:40:46 +00001263class LoggerAdapter:
1264 """
1265 An adapter for loggers which makes it easier to specify contextual
1266 information in logging output.
1267 """
1268
1269 def __init__(self, logger, extra):
1270 """
1271 Initialize the adapter with a logger and a dict-like object which
1272 provides contextual information. This constructor signature allows
1273 easy stacking of LoggerAdapters, if so desired.
1274
1275 You can effectively pass keyword arguments as shown in the
1276 following example:
1277
1278 adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
1279 """
1280 self.logger = logger
1281 self.extra = extra
1282
1283 def process(self, msg, kwargs):
1284 """
1285 Process the logging message and keyword arguments passed in to
1286 a logging call to insert contextual information. You can either
1287 manipulate the message itself, the keyword args or both. Return
1288 the message and kwargs modified (or not) to suit your needs.
1289
1290 Normally, you'll only need to override this one method in a
1291 LoggerAdapter subclass for your specific needs.
1292 """
1293 kwargs["extra"] = self.extra
1294 return msg, kwargs
1295
1296 def debug(self, msg, *args, **kwargs):
1297 """
1298 Delegate a debug call to the underlying logger, after adding
1299 contextual information from this adapter instance.
1300 """
1301 msg, kwargs = self.process(msg, kwargs)
1302 self.logger.debug(msg, *args, **kwargs)
1303
1304 def info(self, msg, *args, **kwargs):
1305 """
1306 Delegate an info call to the underlying logger, after adding
1307 contextual information from this adapter instance.
1308 """
1309 msg, kwargs = self.process(msg, kwargs)
1310 self.logger.info(msg, *args, **kwargs)
1311
1312 def warning(self, msg, *args, **kwargs):
1313 """
1314 Delegate a warning call to the underlying logger, after adding
1315 contextual information from this adapter instance.
1316 """
1317 msg, kwargs = self.process(msg, kwargs)
1318 self.logger.warning(msg, *args, **kwargs)
1319
1320 def error(self, msg, *args, **kwargs):
1321 """
1322 Delegate an error call to the underlying logger, after adding
1323 contextual information from this adapter instance.
1324 """
1325 msg, kwargs = self.process(msg, kwargs)
1326 self.logger.error(msg, *args, **kwargs)
1327
1328 def exception(self, msg, *args, **kwargs):
1329 """
1330 Delegate an exception call to the underlying logger, after adding
1331 contextual information from this adapter instance.
1332 """
1333 msg, kwargs = self.process(msg, kwargs)
1334 kwargs["exc_info"] = 1
1335 self.logger.error(msg, *args, **kwargs)
1336
1337 def critical(self, msg, *args, **kwargs):
1338 """
1339 Delegate a critical call to the underlying logger, after adding
1340 contextual information from this adapter instance.
1341 """
1342 msg, kwargs = self.process(msg, kwargs)
1343 self.logger.critical(msg, *args, **kwargs)
1344
1345 def log(self, level, msg, *args, **kwargs):
1346 """
1347 Delegate a log call to the underlying logger, after adding
1348 contextual information from this adapter instance.
1349 """
1350 msg, kwargs = self.process(msg, kwargs)
1351 self.logger.log(level, msg, *args, **kwargs)
1352
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001353root = RootLogger(WARNING)
Guido van Rossum57102f82002-11-13 16:15:58 +00001354Logger.root = root
1355Logger.manager = Manager(Logger.root)
1356
1357#---------------------------------------------------------------------------
1358# Configuration classes and functions
1359#---------------------------------------------------------------------------
1360
1361BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
1362
Vinay Sajip779e0c92004-07-03 11:47:26 +00001363def basicConfig(**kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001364 """
Vinay Sajip779e0c92004-07-03 11:47:26 +00001365 Do basic configuration for the logging system.
1366
1367 This function does nothing if the root logger already has handlers
1368 configured. It is a convenience method intended for use by simple scripts
1369 to do one-shot configuration of the logging package.
1370
1371 The default behaviour is to create a StreamHandler which writes to
1372 sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1373 add the handler to the root logger.
1374
1375 A number of optional keyword arguments may be specified, which can alter
1376 the default behaviour.
1377
1378 filename Specifies that a FileHandler be created, using the specified
1379 filename, rather than a StreamHandler.
1380 filemode Specifies the mode to open the file, if filename is specified
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001381 (if filemode is unspecified, it defaults to 'a').
Vinay Sajip779e0c92004-07-03 11:47:26 +00001382 format Use the specified format string for the handler.
1383 datefmt Use the specified date/time format.
1384 level Set the root logger level to the specified level.
1385 stream Use the specified stream to initialize the StreamHandler. Note
1386 that this argument is incompatible with 'filename' - if both
1387 are present, 'stream' is ignored.
1388
1389 Note that you could specify a stream created using open(filename, mode)
1390 rather than passing the filename and mode in. However, it should be
1391 remembered that StreamHandler does not close its stream (since it may be
1392 using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1393 when the handler is closed.
Guido van Rossum57102f82002-11-13 16:15:58 +00001394 """
1395 if len(root.handlers) == 0:
Vinay Sajip779e0c92004-07-03 11:47:26 +00001396 filename = kwargs.get("filename")
1397 if filename:
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001398 mode = kwargs.get("filemode", 'a')
Vinay Sajip779e0c92004-07-03 11:47:26 +00001399 hdlr = FileHandler(filename, mode)
1400 else:
1401 stream = kwargs.get("stream")
1402 hdlr = StreamHandler(stream)
1403 fs = kwargs.get("format", BASIC_FORMAT)
1404 dfs = kwargs.get("datefmt", None)
1405 fmt = Formatter(fs, dfs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001406 hdlr.setFormatter(fmt)
1407 root.addHandler(hdlr)
Vinay Sajip779e0c92004-07-03 11:47:26 +00001408 level = kwargs.get("level")
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001409 if level is not None:
Tim Peters4e0e1b62004-07-07 20:54:48 +00001410 root.setLevel(level)
Guido van Rossum57102f82002-11-13 16:15:58 +00001411
1412#---------------------------------------------------------------------------
1413# Utility functions at module level.
1414# Basically delegate everything to the root logger.
1415#---------------------------------------------------------------------------
1416
1417def getLogger(name=None):
1418 """
1419 Return a logger with the specified name, creating it if necessary.
1420
1421 If no name is specified, return the root logger.
1422 """
1423 if name:
1424 return Logger.manager.getLogger(name)
1425 else:
1426 return root
1427
1428#def getRootLogger():
1429# """
1430# Return the root logger.
1431#
1432# Note that getLogger('') now does the same thing, so this function is
1433# deprecated and may disappear in the future.
1434# """
1435# return root
1436
1437def critical(msg, *args, **kwargs):
1438 """
1439 Log a message with severity 'CRITICAL' on the root logger.
1440 """
1441 if len(root.handlers) == 0:
1442 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001443 root.critical(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001444
1445fatal = critical
1446
1447def error(msg, *args, **kwargs):
1448 """
1449 Log a message with severity 'ERROR' on the root logger.
1450 """
1451 if len(root.handlers) == 0:
1452 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001453 root.error(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001454
1455def exception(msg, *args):
1456 """
1457 Log a message with severity 'ERROR' on the root logger,
1458 with exception information.
1459 """
Neal Norwitz7c307242006-03-17 08:28:24 +00001460 error(msg, exc_info=1, *args)
Guido van Rossum57102f82002-11-13 16:15:58 +00001461
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001462def warning(msg, *args, **kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001463 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001464 Log a message with severity 'WARNING' on the root logger.
Guido van Rossum57102f82002-11-13 16:15:58 +00001465 """
1466 if len(root.handlers) == 0:
1467 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001468 root.warning(msg, *args, **kwargs)
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001469
1470warn = warning
Guido van Rossum57102f82002-11-13 16:15:58 +00001471
1472def info(msg, *args, **kwargs):
1473 """
1474 Log a message with severity 'INFO' on the root logger.
1475 """
1476 if len(root.handlers) == 0:
1477 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001478 root.info(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001479
1480def debug(msg, *args, **kwargs):
1481 """
1482 Log a message with severity 'DEBUG' on the root logger.
1483 """
1484 if len(root.handlers) == 0:
1485 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001486 root.debug(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001487
Vinay Sajipb2635b22004-09-24 11:45:52 +00001488def log(level, msg, *args, **kwargs):
1489 """
1490 Log 'msg % args' with the integer severity 'level' on the root logger.
1491 """
1492 if len(root.handlers) == 0:
1493 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001494 root.log(level, msg, *args, **kwargs)
Vinay Sajipb2635b22004-09-24 11:45:52 +00001495
Guido van Rossum57102f82002-11-13 16:15:58 +00001496def disable(level):
1497 """
1498 Disable all logging calls less severe than 'level'.
1499 """
1500 root.manager.disable = level
1501
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001502def shutdown(handlerList=_handlerList):
Guido van Rossum57102f82002-11-13 16:15:58 +00001503 """
1504 Perform any cleanup actions in the logging system (e.g. flushing
1505 buffers).
1506
1507 Should be called at application exit.
1508 """
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001509 for h in handlerList[:]:
Vinay Sajipe12f7152004-07-29 09:19:30 +00001510 #errors might occur, for example, if files are locked
Vinay Sajip260ce432006-02-09 08:34:14 +00001511 #we just ignore them if raiseExceptions is not set
Vinay Sajipe12f7152004-07-29 09:19:30 +00001512 try:
1513 h.flush()
1514 h.close()
1515 except:
Vinay Sajip260ce432006-02-09 08:34:14 +00001516 if raiseExceptions:
1517 raise
1518 #else, swallow
Vinay Sajiped6bb142004-02-20 13:18:36 +00001519
1520#Let's try and shutdown automatically on application exit...
1521try:
1522 import atexit
1523 atexit.register(shutdown)
1524except ImportError: # for Python versions < 2.0
1525 def exithook(status, old_exit=sys.exit):
1526 try:
1527 shutdown()
1528 finally:
1529 old_exit(status)
1530
1531 sys.exit = exithook
Georg Brandlf9734072008-12-07 15:30:06 +00001532
1533# Null handler
1534
1535class NullHandler(Handler):
1536 """
1537 This handler does nothing. It's intended to be used to avoid the
1538 "No handlers could be found for logger XXX" one-off warning. This is
1539 important for library code, which may contain code to log events. If a user
1540 of the library does not configure logging, the one-off warning might be
1541 produced; to avoid this, the library developer simply needs to instantiate
1542 a NullHandler and add it to the top-level logger of the library module or
1543 package.
1544 """
1545 def emit(self, record):
1546 pass
1547
1548# Warnings integration
1549
1550_warnings_showwarning = None
1551
1552def _showwarning(message, category, filename, lineno, file=None, line=None):
1553 """
1554 Implementation of showwarnings which redirects to logging, which will first
1555 check to see if the file parameter is None. If a file is specified, it will
1556 delegate to the original warnings implementation of showwarning. Otherwise,
1557 it will call warnings.formatwarning and will log the resulting string to a
1558 warnings logger named "py.warnings" with level logging.WARNING.
1559 """
1560 if file is not None:
1561 if _warnings_showwarning is not None:
1562 _warnings_showwarning(message, category, filename, lineno, file, line)
1563 else:
1564 s = warnings.formatwarning(message, category, filename, lineno, line)
1565 logger = getLogger("py.warnings")
1566 if not logger.handlers:
1567 logger.addHandler(NullHandler())
1568 logger.warning("%s", s)
1569
1570def captureWarnings(capture):
1571 """
1572 If capture is true, redirect all warnings to the logging package.
1573 If capture is False, ensure that warnings are not redirected to logging
1574 but to their original destinations.
1575 """
1576 global _warnings_showwarning
1577 if capture:
1578 if _warnings_showwarning is None:
1579 _warnings_showwarning = warnings.showwarning
1580 warnings.showwarning = _showwarning
1581 else:
1582 if _warnings_showwarning is not None:
1583 warnings.showwarning = _warnings_showwarning
1584 _warnings_showwarning = None