blob: 231e8c2340dbcfa586311abdda7ac1b50231e246 [file] [log] [blame]
Christian Heimes04c420f2008-01-18 18:40:46 +00001# Copyright 2001-2008 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',
29 'FATAL', 'FileHandler', 'Filter', 'Filterer', 'Formatter', 'Handler',
30 'INFO', 'LogRecord', 'Logger', 'Manager', 'NOTSET', 'PlaceHolder',
31 'RootLogger', 'StreamHandler', 'WARN', 'WARNING']
Vinay Sajipb89e7c92005-03-13 09:54:31 +000032
33try:
34 import codecs
35except ImportError:
36 codecs = None
Guido van Rossum57102f82002-11-13 16:15:58 +000037
38try:
Georg Brandl2067bfd2008-05-25 13:05:15 +000039 import _thread as thread
Guido van Rossum57102f82002-11-13 16:15:58 +000040 import threading
41except ImportError:
42 thread = None
Guido van Rossum57102f82002-11-13 16:15:58 +000043
44__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
Thomas Wouters477c8d52006-05-27 19:21:47 +000045__status__ = "production"
Vinay Sajip6268cbc2009-01-21 00:19:28 +000046__version__ = "0.5.0.7"
47__date__ = "20 January 2009"
Guido van Rossum57102f82002-11-13 16:15:58 +000048
49#---------------------------------------------------------------------------
50# Miscellaneous module data
51#---------------------------------------------------------------------------
52
Guido van Rossum13257902007-06-07 23:15:56 +000053_unicode = 'unicode' in dir(__builtins__)
54
Guido van Rossum57102f82002-11-13 16:15:58 +000055#
Vinay Sajip829dc512005-02-18 11:53:32 +000056# _srcfile is used when walking the stack to check when we've got the first
Guido van Rossum57102f82002-11-13 16:15:58 +000057# caller stack frame.
Neal Norwitz6fa635d2003-02-18 14:20:07 +000058#
Vinay Sajipc384fc22005-09-02 11:20:33 +000059if hasattr(sys, 'frozen'): #support for py2exe
60 _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
Neal Norwitz9d72bb42007-04-17 08:48:32 +000061elif __file__[-4:].lower() in ['.pyc', '.pyo']:
Guido van Rossum455ab772002-11-13 16:18:29 +000062 _srcfile = __file__[:-4] + '.py'
Guido van Rossum57102f82002-11-13 16:15:58 +000063else:
Guido van Rossum455ab772002-11-13 16:18:29 +000064 _srcfile = __file__
65_srcfile = os.path.normcase(_srcfile)
Guido van Rossum57102f82002-11-13 16:15:58 +000066
Vinay Sajip829dc512005-02-18 11:53:32 +000067# next bit filched from 1.5.2's inspect.py
68def currentframe():
69 """Return the frame object for the caller's stack frame."""
70 try:
Neal Norwitz1e8659b2005-10-21 06:00:24 +000071 raise Exception
Vinay Sajip829dc512005-02-18 11:53:32 +000072 except:
Guido van Rossume7ba4952007-06-06 23:52:48 +000073 return sys.exc_info()[2].tb_frame.f_back
Vinay Sajip829dc512005-02-18 11:53:32 +000074
Thomas Wouterscf297e42007-02-23 15:07:44 +000075if hasattr(sys, '_getframe'): currentframe = lambda: sys._getframe(3)
Vinay Sajip829dc512005-02-18 11:53:32 +000076# done filching
77
Jeremy Hylton250684d2003-01-23 18:29:29 +000078# _srcfile is only used in conjunction with sys._getframe().
79# To provide compatibility with older versions of Python, set _srcfile
80# to None if _getframe() is not available; this value will prevent
81# findCaller() from being called.
Vinay Sajip829dc512005-02-18 11:53:32 +000082#if not hasattr(sys, "_getframe"):
83# _srcfile = None
Jeremy Hylton250684d2003-01-23 18:29:29 +000084
Guido van Rossum57102f82002-11-13 16:15:58 +000085#
86#_startTime is used as the base when calculating the relative time of events
87#
88_startTime = time.time()
89
90#
91#raiseExceptions is used to see if exceptions during handling should be
92#propagated
93#
94raiseExceptions = 1
95
Vinay Sajipd364a072006-03-13 22:05:28 +000096#
97# If you don't want threading information in the log, set this to zero
98#
99logThreads = 1
100
101#
Jesse Noller9a0fc972009-01-18 21:12:58 +0000102# If you don't want multiprocessing information in the log, set this to zero
103#
104logMultiprocessing = 1
105
106#
Vinay Sajipd364a072006-03-13 22:05:28 +0000107# If you don't want process information in the log, set this to zero
108#
109logProcesses = 1
110
Guido van Rossum57102f82002-11-13 16:15:58 +0000111#---------------------------------------------------------------------------
112# Level related stuff
113#---------------------------------------------------------------------------
114#
115# Default levels and level names, these can be replaced with any positive set
116# of values having corresponding names. There is a pseudo-level, NOTSET, which
117# is only really there as a lower limit for user-defined levels. Handlers and
118# loggers are initialized with NOTSET so that they will log all messages, even
119# at user-defined levels.
120#
Vinay Sajipb89e7c92005-03-13 09:54:31 +0000121
Guido van Rossum57102f82002-11-13 16:15:58 +0000122CRITICAL = 50
123FATAL = CRITICAL
124ERROR = 40
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000125WARNING = 30
126WARN = WARNING
Guido van Rossum57102f82002-11-13 16:15:58 +0000127INFO = 20
128DEBUG = 10
129NOTSET = 0
130
131_levelNames = {
132 CRITICAL : 'CRITICAL',
133 ERROR : 'ERROR',
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000134 WARNING : 'WARNING',
Guido van Rossum57102f82002-11-13 16:15:58 +0000135 INFO : 'INFO',
136 DEBUG : 'DEBUG',
137 NOTSET : 'NOTSET',
138 'CRITICAL' : CRITICAL,
139 'ERROR' : ERROR,
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000140 'WARN' : WARNING,
141 'WARNING' : WARNING,
Guido van Rossum57102f82002-11-13 16:15:58 +0000142 'INFO' : INFO,
143 'DEBUG' : DEBUG,
144 'NOTSET' : NOTSET,
145}
146
147def getLevelName(level):
148 """
149 Return the textual representation of logging level 'level'.
150
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000151 If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
Guido van Rossum57102f82002-11-13 16:15:58 +0000152 INFO, DEBUG) then you get the corresponding string. If you have
153 associated levels with names using addLevelName then the name you have
Vinay Sajip779e0c92004-07-03 11:47:26 +0000154 associated with 'level' is returned.
155
156 If a numeric value corresponding to one of the defined levels is passed
157 in, the corresponding string representation is returned.
158
159 Otherwise, the string "Level %s" % level is returned.
Guido van Rossum57102f82002-11-13 16:15:58 +0000160 """
161 return _levelNames.get(level, ("Level %s" % level))
162
163def addLevelName(level, levelName):
164 """
165 Associate 'levelName' with 'level'.
166
167 This is used when converting levels to text during message formatting.
168 """
169 _acquireLock()
170 try: #unlikely to cause an exception, but you never know...
171 _levelNames[level] = levelName
172 _levelNames[levelName] = level
173 finally:
174 _releaseLock()
175
176#---------------------------------------------------------------------------
177# Thread-related stuff
178#---------------------------------------------------------------------------
179
180#
181#_lock is used to serialize access to shared data structures in this module.
182#This needs to be an RLock because fileConfig() creates Handlers and so
183#might arbitrary user threads. Since Handler.__init__() updates the shared
184#dictionary _handlers, it needs to acquire the lock. But if configuring,
185#the lock would already have been acquired - so we need an RLock.
186#The same argument applies to Loggers and Manager.loggerDict.
187#
188_lock = None
189
190def _acquireLock():
191 """
192 Acquire the module-level lock for serializing access to shared data.
193
194 This should be released with _releaseLock().
195 """
196 global _lock
197 if (not _lock) and thread:
198 _lock = threading.RLock()
199 if _lock:
200 _lock.acquire()
201
202def _releaseLock():
203 """
204 Release the module-level lock acquired by calling _acquireLock().
205 """
206 if _lock:
207 _lock.release()
208
209#---------------------------------------------------------------------------
210# The logging record
211#---------------------------------------------------------------------------
212
213class LogRecord:
214 """
215 A LogRecord instance represents an event being logged.
216
217 LogRecord instances are created every time something is logged. They
218 contain all the information pertinent to the event being logged. The
219 main information passed in is in msg and args, which are combined
220 using str(msg) % args to create the message field of the record. The
221 record also includes information such as when the record was created,
222 the source line where the logging call was made, and any exception
223 information to be logged.
224 """
Vinay Sajiped1992f2006-02-09 08:48:36 +0000225 def __init__(self, name, level, pathname, lineno,
Thomas Wouters89f507f2006-12-13 04:49:30 +0000226 msg, args, exc_info, func=None):
Guido van Rossum57102f82002-11-13 16:15:58 +0000227 """
228 Initialize a logging record with interesting information.
229 """
230 ct = time.time()
231 self.name = name
232 self.msg = msg
Vinay Sajip4ed315a2004-10-20 08:39:40 +0000233 #
234 # The following statement allows passing of a dictionary as a sole
235 # argument, so that you can do something like
236 # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
237 # Suggested by Stefan Behnel.
238 # Note that without the test for args[0], we get a problem because
239 # during formatting, we test to see if the arg is present using
240 # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
241 # and if the passed arg fails 'if self.args:' then no formatting
242 # is done. For example, logger.warn('Value is %d', 0) would log
243 # 'Value is %d' instead of 'Value is 0'.
244 # For the use case of passing a dictionary, this should not be a
245 # problem.
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000246 if args and len(args) == 1 and isinstance(args[0], dict) and args[0]:
Vinay Sajip4ed315a2004-10-20 08:39:40 +0000247 args = args[0]
Guido van Rossum57102f82002-11-13 16:15:58 +0000248 self.args = args
249 self.levelname = getLevelName(level)
250 self.levelno = level
251 self.pathname = pathname
252 try:
253 self.filename = os.path.basename(pathname)
254 self.module = os.path.splitext(self.filename)[0]
Thomas Wouters902d6eb2007-01-09 23:18:33 +0000255 except (TypeError, ValueError, AttributeError):
Guido van Rossum57102f82002-11-13 16:15:58 +0000256 self.filename = pathname
257 self.module = "Unknown module"
258 self.exc_info = exc_info
Vinay Sajiped6bb142004-02-20 13:18:36 +0000259 self.exc_text = None # used to cache the traceback text
Guido van Rossum57102f82002-11-13 16:15:58 +0000260 self.lineno = lineno
Vinay Sajiped1992f2006-02-09 08:48:36 +0000261 self.funcName = func
Guido van Rossum57102f82002-11-13 16:15:58 +0000262 self.created = ct
Guido van Rossume2a383d2007-01-15 16:59:06 +0000263 self.msecs = (ct - int(ct)) * 1000
Guido van Rossum57102f82002-11-13 16:15:58 +0000264 self.relativeCreated = (self.created - _startTime) * 1000
Vinay Sajipd364a072006-03-13 22:05:28 +0000265 if logThreads and thread:
Guido van Rossum57102f82002-11-13 16:15:58 +0000266 self.thread = thread.get_ident()
Benjamin Peterson72753702008-08-18 18:09:21 +0000267 self.threadName = threading.current_thread().name
Guido van Rossum57102f82002-11-13 16:15:58 +0000268 else:
269 self.thread = None
Vinay Sajip4a704862005-03-31 20:16:55 +0000270 self.threadName = None
Jesse Noller9a0fc972009-01-18 21:12:58 +0000271 if logMultiprocessing:
272 from multiprocessing import current_process
273 self.processName = current_process().name
274 else:
275 self.processName = None
Vinay Sajipd364a072006-03-13 22:05:28 +0000276 if logProcesses and hasattr(os, 'getpid'):
Jack Jansen4c641d02003-02-21 22:29:45 +0000277 self.process = os.getpid()
278 else:
279 self.process = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000280
281 def __str__(self):
282 return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
283 self.pathname, self.lineno, self.msg)
284
285 def getMessage(self):
286 """
287 Return the message for this LogRecord.
288
289 Return the message for this LogRecord after merging any user-supplied
290 arguments with the message.
291 """
Guido van Rossum13257902007-06-07 23:15:56 +0000292 if not _unicode: #if no unicode support...
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000293 msg = str(self.msg)
294 else:
Vinay Sajip43d6e812005-10-07 08:35:36 +0000295 msg = self.msg
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000296 if not isinstance(msg, str):
Vinay Sajip43d6e812005-10-07 08:35:36 +0000297 try:
298 msg = str(self.msg)
299 except UnicodeError:
300 msg = self.msg #Defer encoding till later
Guido van Rossum57102f82002-11-13 16:15:58 +0000301 if self.args:
302 msg = msg % self.args
303 return msg
304
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +0000305def makeLogRecord(dict):
306 """
307 Make a LogRecord whose attributes are defined by the specified dictionary,
308 This function is useful for converting a logging event received over
309 a socket connection (which is sent as a dictionary) into a LogRecord
310 instance.
311 """
Vinay Sajiped1992f2006-02-09 08:48:36 +0000312 rv = LogRecord(None, None, "", 0, "", (), None, None)
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +0000313 rv.__dict__.update(dict)
314 return rv
315
Guido van Rossum57102f82002-11-13 16:15:58 +0000316#---------------------------------------------------------------------------
317# Formatter classes and functions
318#---------------------------------------------------------------------------
319
320class Formatter:
321 """
322 Formatter instances are used to convert a LogRecord to text.
323
324 Formatters need to know how a LogRecord is constructed. They are
325 responsible for converting a LogRecord to (usually) a string which can
326 be interpreted by either a human or an external system. The base Formatter
327 allows a formatting string to be specified. If none is supplied, the
328 default value of "%s(message)\\n" is used.
329
330 The Formatter can be initialized with a format string which makes use of
331 knowledge of the LogRecord attributes - e.g. the default value mentioned
332 above makes use of the fact that the user's message and arguments are pre-
333 formatted into a LogRecord's message attribute. Currently, the useful
334 attributes in a LogRecord are described by:
335
336 %(name)s Name of the logger (logging channel)
337 %(levelno)s Numeric logging level for the message (DEBUG, INFO,
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000338 WARNING, ERROR, CRITICAL)
Guido van Rossum57102f82002-11-13 16:15:58 +0000339 %(levelname)s Text logging level for the message ("DEBUG", "INFO",
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000340 "WARNING", "ERROR", "CRITICAL")
Guido van Rossum57102f82002-11-13 16:15:58 +0000341 %(pathname)s Full pathname of the source file where the logging
342 call was issued (if available)
343 %(filename)s Filename portion of pathname
344 %(module)s Module (name portion of filename)
345 %(lineno)d Source line number where the logging call was issued
346 (if available)
Vinay Sajiped1992f2006-02-09 08:48:36 +0000347 %(funcName)s Function name
Guido van Rossum57102f82002-11-13 16:15:58 +0000348 %(created)f Time when the LogRecord was created (time.time()
349 return value)
350 %(asctime)s Textual time when the LogRecord was created
351 %(msecs)d Millisecond portion of the creation time
352 %(relativeCreated)d Time in milliseconds when the LogRecord was created,
353 relative to the time the logging module was loaded
354 (typically at application startup time)
355 %(thread)d Thread ID (if available)
Vinay Sajip4a704862005-03-31 20:16:55 +0000356 %(threadName)s Thread name (if available)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000357 %(process)d Process ID (if available)
Guido van Rossum57102f82002-11-13 16:15:58 +0000358 %(message)s The result of record.getMessage(), computed just as
359 the record is emitted
360 """
361
362 converter = time.localtime
363
364 def __init__(self, fmt=None, datefmt=None):
365 """
366 Initialize the formatter with specified format strings.
367
368 Initialize the formatter either with the specified format string, or a
369 default as described above. Allow for specialized date formatting with
370 the optional datefmt argument (if omitted, you get the ISO8601 format).
371 """
372 if fmt:
373 self._fmt = fmt
374 else:
375 self._fmt = "%(message)s"
376 self.datefmt = datefmt
377
378 def formatTime(self, record, datefmt=None):
379 """
380 Return the creation time of the specified LogRecord as formatted text.
381
382 This method should be called from format() by a formatter which
383 wants to make use of a formatted time. This method can be overridden
384 in formatters to provide for any specific requirement, but the
385 basic behaviour is as follows: if datefmt (a string) is specified,
386 it is used with time.strftime() to format the creation time of the
387 record. Otherwise, the ISO8601 format is used. The resulting
388 string is returned. This function uses a user-configurable function
389 to convert the creation time to a tuple. By default, time.localtime()
390 is used; to change this for a particular formatter instance, set the
391 'converter' attribute to a function with the same signature as
392 time.localtime() or time.gmtime(). To change it for all formatters,
393 for example if you want all logging times to be shown in GMT,
394 set the 'converter' attribute in the Formatter class.
395 """
396 ct = self.converter(record.created)
397 if datefmt:
398 s = time.strftime(datefmt, ct)
399 else:
400 t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
401 s = "%s,%03d" % (t, record.msecs)
402 return s
403
404 def formatException(self, ei):
405 """
406 Format and return the specified exception information as a string.
407
408 This default implementation just uses
409 traceback.print_exception()
410 """
Guido van Rossum34d19282007-08-09 01:03:29 +0000411 sio = io.StringIO()
Guido van Rossum57102f82002-11-13 16:15:58 +0000412 traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
413 s = sio.getvalue()
414 sio.close()
Guido van Rossum486364b2007-06-30 05:01:58 +0000415 if s[-1:] == "\n":
Guido van Rossum57102f82002-11-13 16:15:58 +0000416 s = s[:-1]
417 return s
418
419 def format(self, record):
420 """
421 Format the specified record as text.
422
423 The record's attribute dictionary is used as the operand to a
424 string formatting operation which yields the returned string.
425 Before formatting the dictionary, a couple of preparatory steps
426 are carried out. The message attribute of the record is computed
427 using LogRecord.getMessage(). If the formatting string contains
428 "%(asctime)", formatTime() is called to format the event time.
429 If there is exception information, it is formatted using
430 formatException() and appended to the message.
431 """
432 record.message = record.getMessage()
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000433 if self._fmt.find("%(asctime)") >= 0:
Guido van Rossum57102f82002-11-13 16:15:58 +0000434 record.asctime = self.formatTime(record, self.datefmt)
435 s = self._fmt % record.__dict__
436 if record.exc_info:
Vinay Sajiped6bb142004-02-20 13:18:36 +0000437 # Cache the traceback text to avoid converting it multiple times
438 # (it's constant anyway)
439 if not record.exc_text:
440 record.exc_text = self.formatException(record.exc_info)
441 if record.exc_text:
Guido van Rossum486364b2007-06-30 05:01:58 +0000442 if s[-1:] != "\n":
Guido van Rossum57102f82002-11-13 16:15:58 +0000443 s = s + "\n"
Vinay Sajiped6bb142004-02-20 13:18:36 +0000444 s = s + record.exc_text
Guido van Rossum57102f82002-11-13 16:15:58 +0000445 return s
446
447#
448# The default formatter to use when no other is specified
449#
450_defaultFormatter = Formatter()
451
452class BufferingFormatter:
453 """
454 A formatter suitable for formatting a number of records.
455 """
456 def __init__(self, linefmt=None):
457 """
458 Optionally specify a formatter which will be used to format each
459 individual record.
460 """
461 if linefmt:
462 self.linefmt = linefmt
463 else:
464 self.linefmt = _defaultFormatter
465
466 def formatHeader(self, records):
467 """
468 Return the header string for the specified records.
469 """
470 return ""
471
472 def formatFooter(self, records):
473 """
474 Return the footer string for the specified records.
475 """
476 return ""
477
478 def format(self, records):
479 """
480 Format the specified records and return the result as a string.
481 """
482 rv = ""
483 if len(records) > 0:
484 rv = rv + self.formatHeader(records)
485 for record in records:
486 rv = rv + self.linefmt.format(record)
487 rv = rv + self.formatFooter(records)
488 return rv
489
490#---------------------------------------------------------------------------
491# Filter classes and functions
492#---------------------------------------------------------------------------
493
494class Filter:
495 """
496 Filter instances are used to perform arbitrary filtering of LogRecords.
497
498 Loggers and Handlers can optionally use Filter instances to filter
499 records as desired. The base filter class only allows events which are
500 below a certain point in the logger hierarchy. For example, a filter
501 initialized with "A.B" will allow events logged by loggers "A.B",
502 "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
503 initialized with the empty string, all events are passed.
504 """
505 def __init__(self, name=''):
506 """
507 Initialize a filter.
508
509 Initialize with the name of the logger which, together with its
510 children, will have its events allowed through the filter. If no
511 name is specified, allow every event.
512 """
513 self.name = name
514 self.nlen = len(name)
515
516 def filter(self, record):
517 """
518 Determine if the specified record is to be logged.
519
520 Is the specified record to be logged? Returns 0 for no, nonzero for
521 yes. If deemed appropriate, the record may be modified in-place.
522 """
523 if self.nlen == 0:
524 return 1
525 elif self.name == record.name:
526 return 1
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000527 elif record.name.find(self.name, 0, self.nlen) != 0:
Guido van Rossum57102f82002-11-13 16:15:58 +0000528 return 0
529 return (record.name[self.nlen] == ".")
530
531class Filterer:
532 """
533 A base class for loggers and handlers which allows them to share
534 common code.
535 """
536 def __init__(self):
537 """
538 Initialize the list of filters to be an empty list.
539 """
540 self.filters = []
541
542 def addFilter(self, filter):
543 """
544 Add the specified filter to this handler.
545 """
546 if not (filter in self.filters):
547 self.filters.append(filter)
548
549 def removeFilter(self, filter):
550 """
551 Remove the specified filter from this handler.
552 """
553 if filter in self.filters:
554 self.filters.remove(filter)
555
556 def filter(self, record):
557 """
558 Determine if a record is loggable by consulting all the filters.
559
560 The default is to allow the record to be logged; any filter can veto
561 this and the record is then dropped. Returns a zero value if a record
562 is to be dropped, else non-zero.
563 """
564 rv = 1
565 for f in self.filters:
566 if not f.filter(record):
567 rv = 0
568 break
569 return rv
570
571#---------------------------------------------------------------------------
572# Handler classes and functions
573#---------------------------------------------------------------------------
574
575_handlers = {} #repository of handlers (for flushing when shutdown called)
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000576_handlerList = [] # added to allow handlers to be removed in reverse of order initialized
Guido van Rossum57102f82002-11-13 16:15:58 +0000577
578class Handler(Filterer):
579 """
580 Handler instances dispatch logging events to specific destinations.
581
582 The base handler class. Acts as a placeholder which defines the Handler
583 interface. Handlers can optionally use Formatter instances to format
584 records as desired. By default, no formatter is specified; in this case,
585 the 'raw' message as determined by record.message is logged.
586 """
587 def __init__(self, level=NOTSET):
588 """
589 Initializes the instance - basically setting the formatter to None
590 and the filter list to empty.
591 """
592 Filterer.__init__(self)
593 self.level = level
594 self.formatter = None
595 #get the module data lock, as we're updating a shared structure.
596 _acquireLock()
597 try: #unlikely to raise an exception, but you never know...
598 _handlers[self] = 1
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000599 _handlerList.insert(0, self)
Guido van Rossum57102f82002-11-13 16:15:58 +0000600 finally:
601 _releaseLock()
602 self.createLock()
603
604 def createLock(self):
605 """
606 Acquire a thread lock for serializing access to the underlying I/O.
607 """
608 if thread:
Vinay Sajip4a704862005-03-31 20:16:55 +0000609 self.lock = threading.RLock()
Guido van Rossum57102f82002-11-13 16:15:58 +0000610 else:
611 self.lock = None
612
613 def acquire(self):
614 """
615 Acquire the I/O thread lock.
616 """
617 if self.lock:
618 self.lock.acquire()
619
620 def release(self):
621 """
622 Release the I/O thread lock.
623 """
624 if self.lock:
625 self.lock.release()
626
627 def setLevel(self, level):
628 """
629 Set the logging level of this handler.
630 """
631 self.level = level
632
633 def format(self, record):
634 """
635 Format the specified record.
636
637 If a formatter is set, use it. Otherwise, use the default formatter
638 for the module.
639 """
640 if self.formatter:
641 fmt = self.formatter
642 else:
643 fmt = _defaultFormatter
644 return fmt.format(record)
645
646 def emit(self, record):
647 """
648 Do whatever it takes to actually log the specified logging record.
649
650 This version is intended to be implemented by subclasses and so
651 raises a NotImplementedError.
652 """
Collin Winterce36ad82007-08-30 01:19:48 +0000653 raise NotImplementedError('emit must be implemented '
654 'by Handler subclasses')
Guido van Rossum57102f82002-11-13 16:15:58 +0000655
656 def handle(self, record):
657 """
658 Conditionally emit the specified logging record.
659
660 Emission depends on filters which may have been added to the handler.
661 Wrap the actual emission of the record with acquisition/release of
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000662 the I/O thread lock. Returns whether the filter passed the record for
663 emission.
Guido van Rossum57102f82002-11-13 16:15:58 +0000664 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000665 rv = self.filter(record)
666 if rv:
Guido van Rossum57102f82002-11-13 16:15:58 +0000667 self.acquire()
668 try:
669 self.emit(record)
670 finally:
671 self.release()
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000672 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +0000673
674 def setFormatter(self, fmt):
675 """
676 Set the formatter for this handler.
677 """
678 self.formatter = fmt
679
680 def flush(self):
681 """
682 Ensure all logging output has been flushed.
683
684 This version does nothing and is intended to be implemented by
685 subclasses.
686 """
687 pass
688
689 def close(self):
690 """
691 Tidy up any resources used by the handler.
692
Vinay Sajiped6bb142004-02-20 13:18:36 +0000693 This version does removes the handler from an internal list
694 of handlers which is closed when shutdown() is called. Subclasses
695 should ensure that this gets called from overridden close()
696 methods.
Guido van Rossum57102f82002-11-13 16:15:58 +0000697 """
Vinay Sajiped6bb142004-02-20 13:18:36 +0000698 #get the module data lock, as we're updating a shared structure.
699 _acquireLock()
700 try: #unlikely to raise an exception, but you never know...
Vinay Sajipe0f85922006-02-07 13:55:52 +0000701 del _handlers[self]
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000702 _handlerList.remove(self)
Vinay Sajiped6bb142004-02-20 13:18:36 +0000703 finally:
704 _releaseLock()
Guido van Rossum57102f82002-11-13 16:15:58 +0000705
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000706 def handleError(self, record):
Guido van Rossum57102f82002-11-13 16:15:58 +0000707 """
708 Handle errors which occur during an emit() call.
709
710 This method should be called from handlers when an exception is
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000711 encountered during an emit() call. If raiseExceptions is false,
Guido van Rossum57102f82002-11-13 16:15:58 +0000712 exceptions get silently ignored. This is what is mostly wanted
713 for a logging system - most users will not care about errors in
714 the logging system, they are more interested in application errors.
715 You could, however, replace this with a custom handler if you wish.
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000716 The record which was being processed is passed in to this method.
Guido van Rossum57102f82002-11-13 16:15:58 +0000717 """
718 if raiseExceptions:
Guido van Rossum57102f82002-11-13 16:15:58 +0000719 ei = sys.exc_info()
720 traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
721 del ei
722
723class StreamHandler(Handler):
724 """
725 A handler class which writes logging records, appropriately formatted,
726 to a stream. Note that this class does not close the stream, as
727 sys.stdout or sys.stderr may be used.
728 """
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000729
Guido van Rossum57102f82002-11-13 16:15:58 +0000730 def __init__(self, strm=None):
731 """
732 Initialize the handler.
733
734 If strm is not specified, sys.stderr is used.
735 """
736 Handler.__init__(self)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000737 if strm is None:
Guido van Rossum57102f82002-11-13 16:15:58 +0000738 strm = sys.stderr
739 self.stream = strm
Guido van Rossum57102f82002-11-13 16:15:58 +0000740
741 def flush(self):
742 """
743 Flushes the stream.
744 """
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +0000745 if self.stream and hasattr(self.stream, "flush"):
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000746 self.stream.flush()
Guido van Rossum57102f82002-11-13 16:15:58 +0000747
748 def emit(self, record):
749 """
750 Emit a record.
751
752 If a formatter is specified, it is used to format the record.
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000753 The record is then written to the stream with a trailing newline. If
754 exception information is present, it is formatted using
755 traceback.print_exception and appended to the stream. If the stream
756 has an 'encoding' attribute, it is used to encode the message before
757 output to the stream.
Guido van Rossum57102f82002-11-13 16:15:58 +0000758 """
759 try:
760 msg = self.format(record)
Benjamin Petersonf91df042009-02-13 02:50:59 +0000761 stream = self.stream
Vinay Sajipb9591172004-09-22 12:39:26 +0000762 fs = "%s\n"
Guido van Rossum13257902007-06-07 23:15:56 +0000763 if not _unicode: #if no unicode support...
Benjamin Petersonf91df042009-02-13 02:50:59 +0000764 stream.write(fs % msg)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000765 else:
766 try:
Benjamin Petersonf91df042009-02-13 02:50:59 +0000767 if (isinstance(msg, unicode) or
768 getattr(stream, 'encoding', None) is None):
769 stream.write(fs % msg)
Benjamin Peterson3e4f0552008-09-02 00:31:15 +0000770 else:
Benjamin Petersonf91df042009-02-13 02:50:59 +0000771 stream.write(fs % msg.encode(stream.encoding))
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000772 except UnicodeError:
Benjamin Petersonf91df042009-02-13 02:50:59 +0000773 stream.write(fs % msg.encode("UTF-8"))
Guido van Rossum57102f82002-11-13 16:15:58 +0000774 self.flush()
Vinay Sajip85c19092005-10-31 13:14:19 +0000775 except (KeyboardInterrupt, SystemExit):
776 raise
Guido van Rossum57102f82002-11-13 16:15:58 +0000777 except:
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000778 self.handleError(record)
Guido van Rossum57102f82002-11-13 16:15:58 +0000779
780class FileHandler(StreamHandler):
781 """
782 A handler class which writes formatted logging records to disk files.
783 """
Christian Heimese7a15bb2008-01-24 16:21:45 +0000784 def __init__(self, filename, mode='a', encoding=None, delay=0):
Guido van Rossum57102f82002-11-13 16:15:58 +0000785 """
786 Open the specified file and use it as the stream for logging.
787 """
Vinay Sajip4bbab2b2004-07-08 10:22:35 +0000788 #keep the absolute path, otherwise derived classes which use this
789 #may come a cropper when the current directory changes
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000790 if codecs is None:
791 encoding = None
Vinay Sajip4bbab2b2004-07-08 10:22:35 +0000792 self.baseFilename = os.path.abspath(filename)
Guido van Rossum57102f82002-11-13 16:15:58 +0000793 self.mode = mode
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000794 self.encoding = encoding
Christian Heimese7a15bb2008-01-24 16:21:45 +0000795 if delay:
Vinay Sajip6268cbc2009-01-21 00:19:28 +0000796 #We don't open the stream, but we still need to call the
797 #Handler constructor to set level, formatter, lock etc.
798 Handler.__init__(self)
Christian Heimese7a15bb2008-01-24 16:21:45 +0000799 self.stream = None
800 else:
Vinay Sajip6268cbc2009-01-21 00:19:28 +0000801 StreamHandler.__init__(self, self._open())
Guido van Rossum57102f82002-11-13 16:15:58 +0000802
803 def close(self):
804 """
805 Closes the stream.
806 """
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000807 if self.stream:
808 self.flush()
Amaury Forgeot d'Arc35c86582008-06-17 21:11:29 +0000809 if hasattr(self.stream, "close"):
810 self.stream.close()
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000811 StreamHandler.close(self)
812 self.stream = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000813
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000814 def _open(self):
815 """
816 Open the current base file with the (original) mode and encoding.
817 Return the resulting stream.
818 """
819 if self.encoding is None:
820 stream = open(self.baseFilename, self.mode)
821 else:
822 stream = codecs.open(self.baseFilename, self.mode, self.encoding)
823 return stream
824
Christian Heimese7a15bb2008-01-24 16:21:45 +0000825 def emit(self, record):
826 """
827 Emit a record.
828
829 If the stream was not opened because 'delay' was specified in the
830 constructor, open it before calling the superclass's emit.
831 """
832 if self.stream is None:
Vinay Sajip6268cbc2009-01-21 00:19:28 +0000833 self.stream = self._open()
Christian Heimese7a15bb2008-01-24 16:21:45 +0000834 StreamHandler.emit(self, record)
835
Guido van Rossum57102f82002-11-13 16:15:58 +0000836#---------------------------------------------------------------------------
837# Manager classes and functions
838#---------------------------------------------------------------------------
839
840class PlaceHolder:
841 """
842 PlaceHolder instances are used in the Manager logger hierarchy to take
Vinay Sajip3f742842004-02-28 16:07:46 +0000843 the place of nodes for which no loggers have been defined. This class is
844 intended for internal use only and not as part of the public API.
Guido van Rossum57102f82002-11-13 16:15:58 +0000845 """
846 def __init__(self, alogger):
847 """
848 Initialize with the specified logger being a child of this placeholder.
849 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000850 #self.loggers = [alogger]
851 self.loggerMap = { alogger : None }
Guido van Rossum57102f82002-11-13 16:15:58 +0000852
853 def append(self, alogger):
854 """
855 Add the specified logger as a child of this placeholder.
856 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000857 #if alogger not in self.loggers:
Guido van Rossum93662412006-08-19 16:09:41 +0000858 if alogger not in self.loggerMap:
Vinay Sajip239322b2005-10-14 09:36:35 +0000859 #self.loggers.append(alogger)
860 self.loggerMap[alogger] = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000861
862#
863# Determine which class to use when instantiating loggers.
864#
865_loggerClass = None
866
867def setLoggerClass(klass):
868 """
869 Set the class to be used when instantiating a logger. The class should
870 define __init__() such that only a name argument is required, and the
871 __init__() should call Logger.__init__()
872 """
873 if klass != Logger:
Guido van Rossum57102f82002-11-13 16:15:58 +0000874 if not issubclass(klass, Logger):
Collin Winterce36ad82007-08-30 01:19:48 +0000875 raise TypeError("logger not derived from logging.Logger: "
876 + klass.__name__)
Guido van Rossum57102f82002-11-13 16:15:58 +0000877 global _loggerClass
878 _loggerClass = klass
879
Vinay Sajipb9591172004-09-22 12:39:26 +0000880def getLoggerClass():
881 """
882 Return the class to be used when instantiating a logger.
883 """
884
885 return _loggerClass
886
Guido van Rossum57102f82002-11-13 16:15:58 +0000887class Manager:
888 """
889 There is [under normal circumstances] just one Manager instance, which
890 holds the hierarchy of loggers.
891 """
Neal Norwitzd1cade02002-11-15 23:31:28 +0000892 def __init__(self, rootnode):
Guido van Rossum57102f82002-11-13 16:15:58 +0000893 """
894 Initialize the manager with the root node of the logger hierarchy.
895 """
Neal Norwitzd1cade02002-11-15 23:31:28 +0000896 self.root = rootnode
Guido van Rossum57102f82002-11-13 16:15:58 +0000897 self.disable = 0
898 self.emittedNoHandlerWarning = 0
899 self.loggerDict = {}
900
901 def getLogger(self, name):
902 """
903 Get a logger with the specified name (channel name), creating it
Vinay Sajipb9591172004-09-22 12:39:26 +0000904 if it doesn't yet exist. This name is a dot-separated hierarchical
905 name, such as "a", "a.b", "a.b.c" or similar.
Guido van Rossum57102f82002-11-13 16:15:58 +0000906
907 If a PlaceHolder existed for the specified name [i.e. the logger
908 didn't exist but a child of it did], replace it with the created
909 logger and fix up the parent/child references which pointed to the
910 placeholder to now point to the logger.
911 """
912 rv = None
913 _acquireLock()
914 try:
Guido van Rossum93662412006-08-19 16:09:41 +0000915 if name in self.loggerDict:
Guido van Rossum57102f82002-11-13 16:15:58 +0000916 rv = self.loggerDict[name]
917 if isinstance(rv, PlaceHolder):
918 ph = rv
919 rv = _loggerClass(name)
920 rv.manager = self
921 self.loggerDict[name] = rv
922 self._fixupChildren(ph, rv)
923 self._fixupParents(rv)
924 else:
925 rv = _loggerClass(name)
926 rv.manager = self
927 self.loggerDict[name] = rv
928 self._fixupParents(rv)
929 finally:
930 _releaseLock()
931 return rv
932
933 def _fixupParents(self, alogger):
934 """
935 Ensure that there are either loggers or placeholders all the way
936 from the specified logger to the root of the logger hierarchy.
937 """
938 name = alogger.name
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000939 i = name.rfind(".")
Guido van Rossum57102f82002-11-13 16:15:58 +0000940 rv = None
941 while (i > 0) and not rv:
942 substr = name[:i]
Guido van Rossum93662412006-08-19 16:09:41 +0000943 if substr not in self.loggerDict:
Guido van Rossum57102f82002-11-13 16:15:58 +0000944 self.loggerDict[substr] = PlaceHolder(alogger)
945 else:
946 obj = self.loggerDict[substr]
947 if isinstance(obj, Logger):
948 rv = obj
949 else:
950 assert isinstance(obj, PlaceHolder)
951 obj.append(alogger)
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000952 i = name.rfind(".", 0, i - 1)
Guido van Rossum57102f82002-11-13 16:15:58 +0000953 if not rv:
954 rv = self.root
955 alogger.parent = rv
956
957 def _fixupChildren(self, ph, alogger):
958 """
959 Ensure that children of the placeholder ph are connected to the
960 specified logger.
961 """
Thomas Wouters89f507f2006-12-13 04:49:30 +0000962 name = alogger.name
963 namelen = len(name)
Vinay Sajip239322b2005-10-14 09:36:35 +0000964 for c in ph.loggerMap.keys():
Thomas Wouters89f507f2006-12-13 04:49:30 +0000965 #The if means ... if not c.parent.name.startswith(nm)
966 if c.parent.name[:namelen] != name:
Guido van Rossum57102f82002-11-13 16:15:58 +0000967 alogger.parent = c.parent
968 c.parent = alogger
969
970#---------------------------------------------------------------------------
971# Logger classes and functions
972#---------------------------------------------------------------------------
973
974class Logger(Filterer):
975 """
976 Instances of the Logger class represent a single logging channel. A
977 "logging channel" indicates an area of an application. Exactly how an
978 "area" is defined is up to the application developer. Since an
979 application can have any number of areas, logging channels are identified
980 by a unique string. Application areas can be nested (e.g. an area
981 of "input processing" might include sub-areas "read CSV files", "read
982 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
983 channel names are organized into a namespace hierarchy where levels are
984 separated by periods, much like the Java or Python package namespace. So
985 in the instance given above, channel names might be "input" for the upper
986 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
987 There is no arbitrary limit to the depth of nesting.
988 """
989 def __init__(self, name, level=NOTSET):
990 """
991 Initialize the logger with a name and an optional level.
992 """
993 Filterer.__init__(self)
994 self.name = name
995 self.level = level
996 self.parent = None
997 self.propagate = 1
998 self.handlers = []
999 self.disabled = 0
1000
1001 def setLevel(self, level):
1002 """
1003 Set the logging level of this logger.
1004 """
1005 self.level = level
1006
Guido van Rossum57102f82002-11-13 16:15:58 +00001007 def debug(self, msg, *args, **kwargs):
1008 """
1009 Log 'msg % args' with severity 'DEBUG'.
1010
1011 To pass exception information, use the keyword argument exc_info with
1012 a true value, e.g.
1013
1014 logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
1015 """
Guido van Rossum04110fb2007-08-24 16:32:05 +00001016 if self.isEnabledFor(DEBUG):
Neal Norwitzd9108552006-03-17 08:00:19 +00001017 self._log(DEBUG, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001018
1019 def info(self, msg, *args, **kwargs):
1020 """
1021 Log 'msg % args' with severity 'INFO'.
1022
1023 To pass exception information, use the keyword argument exc_info with
1024 a true value, e.g.
1025
1026 logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
1027 """
Guido van Rossum04110fb2007-08-24 16:32:05 +00001028 if self.isEnabledFor(INFO):
Neal Norwitzd9108552006-03-17 08:00:19 +00001029 self._log(INFO, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001030
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001031 def warning(self, msg, *args, **kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001032 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001033 Log 'msg % args' with severity 'WARNING'.
Guido van Rossum57102f82002-11-13 16:15:58 +00001034
1035 To pass exception information, use the keyword argument exc_info with
1036 a true value, e.g.
1037
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001038 logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
Guido van Rossum57102f82002-11-13 16:15:58 +00001039 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001040 if self.isEnabledFor(WARNING):
Neal Norwitzd9108552006-03-17 08:00:19 +00001041 self._log(WARNING, msg, args, **kwargs)
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001042
1043 warn = warning
Guido van Rossum57102f82002-11-13 16:15:58 +00001044
1045 def error(self, msg, *args, **kwargs):
1046 """
1047 Log 'msg % args' with severity 'ERROR'.
1048
1049 To pass exception information, use the keyword argument exc_info with
1050 a true value, e.g.
1051
1052 logger.error("Houston, we have a %s", "major problem", exc_info=1)
1053 """
Guido van Rossum57102f82002-11-13 16:15:58 +00001054 if self.isEnabledFor(ERROR):
Neal Norwitzd9108552006-03-17 08:00:19 +00001055 self._log(ERROR, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001056
1057 def exception(self, msg, *args):
1058 """
1059 Convenience method for logging an ERROR with exception information.
1060 """
Neal Norwitz7c307242006-03-17 08:28:24 +00001061 self.error(msg, exc_info=1, *args)
Guido van Rossum57102f82002-11-13 16:15:58 +00001062
1063 def critical(self, msg, *args, **kwargs):
1064 """
1065 Log 'msg % args' with severity 'CRITICAL'.
1066
1067 To pass exception information, use the keyword argument exc_info with
1068 a true value, e.g.
1069
1070 logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1071 """
Guido van Rossum04110fb2007-08-24 16:32:05 +00001072 if self.isEnabledFor(CRITICAL):
Neal Norwitzd9108552006-03-17 08:00:19 +00001073 self._log(CRITICAL, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001074
1075 fatal = critical
1076
1077 def log(self, level, msg, *args, **kwargs):
1078 """
Vinay Sajipeb477d02004-08-04 08:38:08 +00001079 Log 'msg % args' with the integer severity 'level'.
Guido van Rossum57102f82002-11-13 16:15:58 +00001080
1081 To pass exception information, use the keyword argument exc_info with
1082 a true value, e.g.
1083
1084 logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1085 """
Guido van Rossum13257902007-06-07 23:15:56 +00001086 if not isinstance(level, int):
Vinay Sajip779e0c92004-07-03 11:47:26 +00001087 if raiseExceptions:
Collin Winterce36ad82007-08-30 01:19:48 +00001088 raise TypeError("level must be an integer")
Vinay Sajip779e0c92004-07-03 11:47:26 +00001089 else:
1090 return
Guido van Rossum57102f82002-11-13 16:15:58 +00001091 if self.isEnabledFor(level):
Neal Norwitzd9108552006-03-17 08:00:19 +00001092 self._log(level, msg, args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001093
1094 def findCaller(self):
1095 """
1096 Find the stack frame of the caller so that we can note the source
Vinay Sajip829dc512005-02-18 11:53:32 +00001097 file name, line number and function name.
Guido van Rossum57102f82002-11-13 16:15:58 +00001098 """
Vinay Sajip829dc512005-02-18 11:53:32 +00001099 f = currentframe().f_back
Thomas Woutersa9773292006-04-21 09:43:23 +00001100 rv = "(unknown file)", 0, "(unknown function)"
1101 while hasattr(f, "f_code"):
Jeremy Hylton250684d2003-01-23 18:29:29 +00001102 co = f.f_code
1103 filename = os.path.normcase(co.co_filename)
1104 if filename == _srcfile:
1105 f = f.f_back
1106 continue
Thomas Woutersa9773292006-04-21 09:43:23 +00001107 rv = (filename, f.f_lineno, co.co_name)
1108 break
1109 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +00001110
Vinay Sajiped1992f2006-02-09 08:48:36 +00001111 def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
Guido van Rossum57102f82002-11-13 16:15:58 +00001112 """
1113 A factory method which can be overridden in subclasses to create
1114 specialized LogRecords.
1115 """
Vinay Sajiped1992f2006-02-09 08:48:36 +00001116 rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
Christian Heimes04c420f2008-01-18 18:40:46 +00001117 if extra is not None:
Vinay Sajip260ce432006-02-09 08:34:14 +00001118 for key in extra:
1119 if (key in ["message", "asctime"]) or (key in rv.__dict__):
1120 raise KeyError("Attempt to overwrite %r in LogRecord" % key)
1121 rv.__dict__[key] = extra[key]
1122 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +00001123
Vinay Sajip260ce432006-02-09 08:34:14 +00001124 def _log(self, level, msg, args, exc_info=None, extra=None):
Guido van Rossum57102f82002-11-13 16:15:58 +00001125 """
1126 Low-level logging routine which creates a LogRecord and then calls
1127 all the handlers of this logger to handle the record.
1128 """
Jeremy Hylton250684d2003-01-23 18:29:29 +00001129 if _srcfile:
Vinay Sajip829dc512005-02-18 11:53:32 +00001130 fn, lno, func = self.findCaller()
Guido van Rossum57102f82002-11-13 16:15:58 +00001131 else:
Vinay Sajip829dc512005-02-18 11:53:32 +00001132 fn, lno, func = "(unknown file)", 0, "(unknown function)"
Guido van Rossum57102f82002-11-13 16:15:58 +00001133 if exc_info:
Guido van Rossum13257902007-06-07 23:15:56 +00001134 if not isinstance(exc_info, tuple):
Vinay Sajiped6bb142004-02-20 13:18:36 +00001135 exc_info = sys.exc_info()
Vinay Sajiped1992f2006-02-09 08:48:36 +00001136 record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
Guido van Rossum57102f82002-11-13 16:15:58 +00001137 self.handle(record)
1138
1139 def handle(self, record):
1140 """
1141 Call the handlers for the specified record.
1142
1143 This method is used for unpickled records received from a socket, as
1144 well as those created locally. Logger-level filtering is applied.
1145 """
1146 if (not self.disabled) and self.filter(record):
1147 self.callHandlers(record)
1148
1149 def addHandler(self, hdlr):
1150 """
1151 Add the specified handler to this logger.
1152 """
1153 if not (hdlr in self.handlers):
1154 self.handlers.append(hdlr)
1155
1156 def removeHandler(self, hdlr):
1157 """
1158 Remove the specified handler from this logger.
1159 """
1160 if hdlr in self.handlers:
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001161 #hdlr.close()
Vinay Sajip116f16e2005-09-16 10:33:40 +00001162 hdlr.acquire()
1163 try:
1164 self.handlers.remove(hdlr)
1165 finally:
1166 hdlr.release()
Guido van Rossum57102f82002-11-13 16:15:58 +00001167
1168 def callHandlers(self, record):
1169 """
1170 Pass a record to all relevant handlers.
1171
1172 Loop through all handlers for this logger and its parents in the
1173 logger hierarchy. If no handler was found, output a one-off error
1174 message to sys.stderr. Stop searching up the hierarchy whenever a
1175 logger with the "propagate" attribute set to zero is found - that
1176 will be the last logger whose handlers are called.
1177 """
1178 c = self
1179 found = 0
1180 while c:
1181 for hdlr in c.handlers:
1182 found = found + 1
1183 if record.levelno >= hdlr.level:
1184 hdlr.handle(record)
1185 if not c.propagate:
1186 c = None #break out
1187 else:
1188 c = c.parent
Vinay Sajip1e86beb2005-10-23 22:32:59 +00001189 if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
Guido van Rossum57102f82002-11-13 16:15:58 +00001190 sys.stderr.write("No handlers could be found for logger"
1191 " \"%s\"\n" % self.name)
1192 self.manager.emittedNoHandlerWarning = 1
1193
1194 def getEffectiveLevel(self):
1195 """
1196 Get the effective level for this logger.
1197
1198 Loop through this logger and its parents in the logger hierarchy,
1199 looking for a non-zero logging level. Return the first one found.
1200 """
1201 logger = self
1202 while logger:
1203 if logger.level:
1204 return logger.level
1205 logger = logger.parent
1206 return NOTSET
1207
1208 def isEnabledFor(self, level):
1209 """
1210 Is this logger enabled for level 'level'?
1211 """
1212 if self.manager.disable >= level:
1213 return 0
1214 return level >= self.getEffectiveLevel()
1215
1216class RootLogger(Logger):
1217 """
1218 A root logger is not that different to any other logger, except that
1219 it must have a logging level and there is only one instance of it in
1220 the hierarchy.
1221 """
1222 def __init__(self, level):
1223 """
1224 Initialize the logger with the name "root".
1225 """
1226 Logger.__init__(self, "root", level)
1227
1228_loggerClass = Logger
1229
Christian Heimes04c420f2008-01-18 18:40:46 +00001230class LoggerAdapter:
1231 """
1232 An adapter for loggers which makes it easier to specify contextual
1233 information in logging output.
1234 """
1235
1236 def __init__(self, logger, extra):
1237 """
1238 Initialize the adapter with a logger and a dict-like object which
1239 provides contextual information. This constructor signature allows
1240 easy stacking of LoggerAdapters, if so desired.
1241
1242 You can effectively pass keyword arguments as shown in the
1243 following example:
1244
1245 adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))
1246 """
1247 self.logger = logger
1248 self.extra = extra
1249
1250 def process(self, msg, kwargs):
1251 """
1252 Process the logging message and keyword arguments passed in to
1253 a logging call to insert contextual information. You can either
1254 manipulate the message itself, the keyword args or both. Return
1255 the message and kwargs modified (or not) to suit your needs.
1256
1257 Normally, you'll only need to override this one method in a
1258 LoggerAdapter subclass for your specific needs.
1259 """
1260 kwargs["extra"] = self.extra
1261 return msg, kwargs
1262
1263 def debug(self, msg, *args, **kwargs):
1264 """
1265 Delegate a debug call to the underlying logger, after adding
1266 contextual information from this adapter instance.
1267 """
1268 msg, kwargs = self.process(msg, kwargs)
1269 self.logger.debug(msg, *args, **kwargs)
1270
1271 def info(self, msg, *args, **kwargs):
1272 """
1273 Delegate an info call to the underlying logger, after adding
1274 contextual information from this adapter instance.
1275 """
1276 msg, kwargs = self.process(msg, kwargs)
1277 self.logger.info(msg, *args, **kwargs)
1278
1279 def warning(self, msg, *args, **kwargs):
1280 """
1281 Delegate a warning call to the underlying logger, after adding
1282 contextual information from this adapter instance.
1283 """
1284 msg, kwargs = self.process(msg, kwargs)
1285 self.logger.warning(msg, *args, **kwargs)
1286
1287 def error(self, msg, *args, **kwargs):
1288 """
1289 Delegate an error call to the underlying logger, after adding
1290 contextual information from this adapter instance.
1291 """
1292 msg, kwargs = self.process(msg, kwargs)
1293 self.logger.error(msg, *args, **kwargs)
1294
1295 def exception(self, msg, *args, **kwargs):
1296 """
1297 Delegate an exception call to the underlying logger, after adding
1298 contextual information from this adapter instance.
1299 """
1300 msg, kwargs = self.process(msg, kwargs)
1301 kwargs["exc_info"] = 1
1302 self.logger.error(msg, *args, **kwargs)
1303
1304 def critical(self, msg, *args, **kwargs):
1305 """
1306 Delegate a critical 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.critical(msg, *args, **kwargs)
1311
1312 def log(self, level, msg, *args, **kwargs):
1313 """
1314 Delegate a log 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.log(level, msg, *args, **kwargs)
1319
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001320root = RootLogger(WARNING)
Guido van Rossum57102f82002-11-13 16:15:58 +00001321Logger.root = root
1322Logger.manager = Manager(Logger.root)
1323
1324#---------------------------------------------------------------------------
1325# Configuration classes and functions
1326#---------------------------------------------------------------------------
1327
1328BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
1329
Vinay Sajip779e0c92004-07-03 11:47:26 +00001330def basicConfig(**kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001331 """
Vinay Sajip779e0c92004-07-03 11:47:26 +00001332 Do basic configuration for the logging system.
1333
1334 This function does nothing if the root logger already has handlers
1335 configured. It is a convenience method intended for use by simple scripts
1336 to do one-shot configuration of the logging package.
1337
1338 The default behaviour is to create a StreamHandler which writes to
1339 sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1340 add the handler to the root logger.
1341
1342 A number of optional keyword arguments may be specified, which can alter
1343 the default behaviour.
1344
1345 filename Specifies that a FileHandler be created, using the specified
1346 filename, rather than a StreamHandler.
1347 filemode Specifies the mode to open the file, if filename is specified
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001348 (if filemode is unspecified, it defaults to 'a').
Vinay Sajip779e0c92004-07-03 11:47:26 +00001349 format Use the specified format string for the handler.
1350 datefmt Use the specified date/time format.
1351 level Set the root logger level to the specified level.
1352 stream Use the specified stream to initialize the StreamHandler. Note
1353 that this argument is incompatible with 'filename' - if both
1354 are present, 'stream' is ignored.
1355
1356 Note that you could specify a stream created using open(filename, mode)
1357 rather than passing the filename and mode in. However, it should be
1358 remembered that StreamHandler does not close its stream (since it may be
1359 using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1360 when the handler is closed.
Guido van Rossum57102f82002-11-13 16:15:58 +00001361 """
1362 if len(root.handlers) == 0:
Vinay Sajip779e0c92004-07-03 11:47:26 +00001363 filename = kwargs.get("filename")
1364 if filename:
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001365 mode = kwargs.get("filemode", 'a')
Vinay Sajip779e0c92004-07-03 11:47:26 +00001366 hdlr = FileHandler(filename, mode)
1367 else:
1368 stream = kwargs.get("stream")
1369 hdlr = StreamHandler(stream)
1370 fs = kwargs.get("format", BASIC_FORMAT)
1371 dfs = kwargs.get("datefmt", None)
1372 fmt = Formatter(fs, dfs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001373 hdlr.setFormatter(fmt)
1374 root.addHandler(hdlr)
Vinay Sajip779e0c92004-07-03 11:47:26 +00001375 level = kwargs.get("level")
Guido van Rossum8ce8a782007-11-01 19:42:39 +00001376 if level is not None:
Tim Peters4e0e1b62004-07-07 20:54:48 +00001377 root.setLevel(level)
Guido van Rossum57102f82002-11-13 16:15:58 +00001378
1379#---------------------------------------------------------------------------
1380# Utility functions at module level.
1381# Basically delegate everything to the root logger.
1382#---------------------------------------------------------------------------
1383
1384def getLogger(name=None):
1385 """
1386 Return a logger with the specified name, creating it if necessary.
1387
1388 If no name is specified, return the root logger.
1389 """
1390 if name:
1391 return Logger.manager.getLogger(name)
1392 else:
1393 return root
1394
1395#def getRootLogger():
1396# """
1397# Return the root logger.
1398#
1399# Note that getLogger('') now does the same thing, so this function is
1400# deprecated and may disappear in the future.
1401# """
1402# return root
1403
1404def critical(msg, *args, **kwargs):
1405 """
1406 Log a message with severity 'CRITICAL' on the root logger.
1407 """
1408 if len(root.handlers) == 0:
1409 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001410 root.critical(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001411
1412fatal = critical
1413
1414def error(msg, *args, **kwargs):
1415 """
1416 Log a message with severity 'ERROR' on the root logger.
1417 """
1418 if len(root.handlers) == 0:
1419 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001420 root.error(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001421
1422def exception(msg, *args):
1423 """
1424 Log a message with severity 'ERROR' on the root logger,
1425 with exception information.
1426 """
Neal Norwitz7c307242006-03-17 08:28:24 +00001427 error(msg, exc_info=1, *args)
Guido van Rossum57102f82002-11-13 16:15:58 +00001428
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001429def warning(msg, *args, **kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001430 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001431 Log a message with severity 'WARNING' on the root logger.
Guido van Rossum57102f82002-11-13 16:15:58 +00001432 """
1433 if len(root.handlers) == 0:
1434 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001435 root.warning(msg, *args, **kwargs)
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001436
1437warn = warning
Guido van Rossum57102f82002-11-13 16:15:58 +00001438
1439def info(msg, *args, **kwargs):
1440 """
1441 Log a message with severity 'INFO' on the root logger.
1442 """
1443 if len(root.handlers) == 0:
1444 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001445 root.info(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001446
1447def debug(msg, *args, **kwargs):
1448 """
1449 Log a message with severity 'DEBUG' on the root logger.
1450 """
1451 if len(root.handlers) == 0:
1452 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001453 root.debug(msg, *args, **kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001454
Vinay Sajipb2635b22004-09-24 11:45:52 +00001455def log(level, msg, *args, **kwargs):
1456 """
1457 Log 'msg % args' with the integer severity 'level' on the root logger.
1458 """
1459 if len(root.handlers) == 0:
1460 basicConfig()
Neal Norwitzd9108552006-03-17 08:00:19 +00001461 root.log(level, msg, *args, **kwargs)
Vinay Sajipb2635b22004-09-24 11:45:52 +00001462
Guido van Rossum57102f82002-11-13 16:15:58 +00001463def disable(level):
1464 """
1465 Disable all logging calls less severe than 'level'.
1466 """
1467 root.manager.disable = level
1468
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001469def shutdown(handlerList=_handlerList):
Guido van Rossum57102f82002-11-13 16:15:58 +00001470 """
1471 Perform any cleanup actions in the logging system (e.g. flushing
1472 buffers).
1473
1474 Should be called at application exit.
1475 """
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001476 for h in handlerList[:]:
Vinay Sajipe12f7152004-07-29 09:19:30 +00001477 #errors might occur, for example, if files are locked
Vinay Sajip260ce432006-02-09 08:34:14 +00001478 #we just ignore them if raiseExceptions is not set
Vinay Sajipe12f7152004-07-29 09:19:30 +00001479 try:
1480 h.flush()
1481 h.close()
1482 except:
Vinay Sajip260ce432006-02-09 08:34:14 +00001483 if raiseExceptions:
1484 raise
1485 #else, swallow
Vinay Sajiped6bb142004-02-20 13:18:36 +00001486
1487#Let's try and shutdown automatically on application exit...
1488try:
1489 import atexit
1490 atexit.register(shutdown)
1491except ImportError: # for Python versions < 2.0
1492 def exithook(status, old_exit=sys.exit):
1493 try:
1494 shutdown()
1495 finally:
1496 old_exit(status)
1497
1498 sys.exit = exithook
Georg Brandlf9734072008-12-07 15:30:06 +00001499
1500# Null handler
1501
1502class NullHandler(Handler):
1503 """
1504 This handler does nothing. It's intended to be used to avoid the
1505 "No handlers could be found for logger XXX" one-off warning. This is
1506 important for library code, which may contain code to log events. If a user
1507 of the library does not configure logging, the one-off warning might be
1508 produced; to avoid this, the library developer simply needs to instantiate
1509 a NullHandler and add it to the top-level logger of the library module or
1510 package.
1511 """
1512 def emit(self, record):
1513 pass
1514
1515# Warnings integration
1516
1517_warnings_showwarning = None
1518
1519def _showwarning(message, category, filename, lineno, file=None, line=None):
1520 """
1521 Implementation of showwarnings which redirects to logging, which will first
1522 check to see if the file parameter is None. If a file is specified, it will
1523 delegate to the original warnings implementation of showwarning. Otherwise,
1524 it will call warnings.formatwarning and will log the resulting string to a
1525 warnings logger named "py.warnings" with level logging.WARNING.
1526 """
1527 if file is not None:
1528 if _warnings_showwarning is not None:
1529 _warnings_showwarning(message, category, filename, lineno, file, line)
1530 else:
1531 s = warnings.formatwarning(message, category, filename, lineno, line)
1532 logger = getLogger("py.warnings")
1533 if not logger.handlers:
1534 logger.addHandler(NullHandler())
1535 logger.warning("%s", s)
1536
1537def captureWarnings(capture):
1538 """
1539 If capture is true, redirect all warnings to the logging package.
1540 If capture is False, ensure that warnings are not redirected to logging
1541 but to their original destinations.
1542 """
1543 global _warnings_showwarning
1544 if capture:
1545 if _warnings_showwarning is None:
1546 _warnings_showwarning = warnings.showwarning
1547 warnings.showwarning = _showwarning
1548 else:
1549 if _warnings_showwarning is not None:
1550 warnings.showwarning = _warnings_showwarning
1551 _warnings_showwarning = None