blob: 853b606ebb249fff3b0a61c2e672abb72c37dea3 [file] [log] [blame]
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001# Copyright 2001-2005 by Vinay Sajip. All Rights Reserved.
Guido van Rossum57102f82002-11-13 16:15:58 +00002#
3# Permission to use, copy, modify, and distribute this software and its
4# documentation for any purpose and without fee is hereby granted,
5# provided that the above copyright notice appear in all copies and that
6# both that copyright notice and this permission notice appear in
7# supporting documentation, and that the name of Vinay Sajip
8# not be used in advertising or publicity pertaining to distribution
9# of the software without specific, written prior permission.
10# VINAY SAJIP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
11# ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
12# VINAY SAJIP BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
13# ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
14# IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum57102f82002-11-13 16:15:58 +000016
17"""
18Logging package for Python. Based on PEP 282 and comments thereto in
19comp.lang.python, and influenced by Apache's log4j system.
20
21Should work under Python versions >= 1.5.2, except that source line
Jeremy Hylton250684d2003-01-23 18:29:29 +000022information is not available unless 'sys._getframe()' is.
Guido van Rossum57102f82002-11-13 16:15:58 +000023
Vinay Sajiped6bb142004-02-20 13:18:36 +000024Copyright (C) 2001-2004 Vinay Sajip. All Rights Reserved.
Guido van Rossum57102f82002-11-13 16:15:58 +000025
26To use, simply 'import logging' and log away!
27"""
28
Vinay Sajipb89e7c92005-03-13 09:54:31 +000029import sys, os, types, time, string, cStringIO, traceback
30
31try:
32 import codecs
33except ImportError:
34 codecs = None
Guido van Rossum57102f82002-11-13 16:15:58 +000035
36try:
37 import thread
38 import threading
39except ImportError:
40 thread = None
Guido van Rossum57102f82002-11-13 16:15:58 +000041
42__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
Neal Norwitzf297bd12003-04-23 03:49:43 +000043__status__ = "beta"
Vinay Sajipe0f85922006-02-07 13:55:52 +000044__version__ = "0.4.9.9"
45__date__ = "06 February 2006"
Guido van Rossum57102f82002-11-13 16:15:58 +000046
47#---------------------------------------------------------------------------
48# Miscellaneous module data
49#---------------------------------------------------------------------------
50
51#
Vinay Sajip829dc512005-02-18 11:53:32 +000052# _srcfile is used when walking the stack to check when we've got the first
Guido van Rossum57102f82002-11-13 16:15:58 +000053# caller stack frame.
Neal Norwitz6fa635d2003-02-18 14:20:07 +000054#
Vinay Sajipc384fc22005-09-02 11:20:33 +000055if hasattr(sys, 'frozen'): #support for py2exe
56 _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:])
57elif string.lower(__file__[-4:]) in ['.pyc', '.pyo']:
Guido van Rossum455ab772002-11-13 16:18:29 +000058 _srcfile = __file__[:-4] + '.py'
Guido van Rossum57102f82002-11-13 16:15:58 +000059else:
Guido van Rossum455ab772002-11-13 16:18:29 +000060 _srcfile = __file__
61_srcfile = os.path.normcase(_srcfile)
Guido van Rossum57102f82002-11-13 16:15:58 +000062
Vinay Sajip829dc512005-02-18 11:53:32 +000063# next bit filched from 1.5.2's inspect.py
64def currentframe():
65 """Return the frame object for the caller's stack frame."""
66 try:
Neal Norwitz1e8659b2005-10-21 06:00:24 +000067 raise Exception
Vinay Sajip829dc512005-02-18 11:53:32 +000068 except:
69 return sys.exc_traceback.tb_frame.f_back
70
71if hasattr(sys, '_getframe'): currentframe = sys._getframe
72# done filching
73
Jeremy Hylton250684d2003-01-23 18:29:29 +000074# _srcfile is only used in conjunction with sys._getframe().
75# To provide compatibility with older versions of Python, set _srcfile
76# to None if _getframe() is not available; this value will prevent
77# findCaller() from being called.
Vinay Sajip829dc512005-02-18 11:53:32 +000078#if not hasattr(sys, "_getframe"):
79# _srcfile = None
Jeremy Hylton250684d2003-01-23 18:29:29 +000080
Guido van Rossum57102f82002-11-13 16:15:58 +000081#
82#_startTime is used as the base when calculating the relative time of events
83#
84_startTime = time.time()
85
86#
87#raiseExceptions is used to see if exceptions during handling should be
88#propagated
89#
90raiseExceptions = 1
91
Guido van Rossum57102f82002-11-13 16:15:58 +000092#---------------------------------------------------------------------------
93# Level related stuff
94#---------------------------------------------------------------------------
95#
96# Default levels and level names, these can be replaced with any positive set
97# of values having corresponding names. There is a pseudo-level, NOTSET, which
98# is only really there as a lower limit for user-defined levels. Handlers and
99# loggers are initialized with NOTSET so that they will log all messages, even
100# at user-defined levels.
101#
Vinay Sajipb89e7c92005-03-13 09:54:31 +0000102
Guido van Rossum57102f82002-11-13 16:15:58 +0000103CRITICAL = 50
104FATAL = CRITICAL
105ERROR = 40
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000106WARNING = 30
107WARN = WARNING
Guido van Rossum57102f82002-11-13 16:15:58 +0000108INFO = 20
109DEBUG = 10
110NOTSET = 0
111
112_levelNames = {
113 CRITICAL : 'CRITICAL',
114 ERROR : 'ERROR',
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000115 WARNING : 'WARNING',
Guido van Rossum57102f82002-11-13 16:15:58 +0000116 INFO : 'INFO',
117 DEBUG : 'DEBUG',
118 NOTSET : 'NOTSET',
119 'CRITICAL' : CRITICAL,
120 'ERROR' : ERROR,
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000121 'WARN' : WARNING,
122 'WARNING' : WARNING,
Guido van Rossum57102f82002-11-13 16:15:58 +0000123 'INFO' : INFO,
124 'DEBUG' : DEBUG,
125 'NOTSET' : NOTSET,
126}
127
128def getLevelName(level):
129 """
130 Return the textual representation of logging level 'level'.
131
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000132 If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
Guido van Rossum57102f82002-11-13 16:15:58 +0000133 INFO, DEBUG) then you get the corresponding string. If you have
134 associated levels with names using addLevelName then the name you have
Vinay Sajip779e0c92004-07-03 11:47:26 +0000135 associated with 'level' is returned.
136
137 If a numeric value corresponding to one of the defined levels is passed
138 in, the corresponding string representation is returned.
139
140 Otherwise, the string "Level %s" % level is returned.
Guido van Rossum57102f82002-11-13 16:15:58 +0000141 """
142 return _levelNames.get(level, ("Level %s" % level))
143
144def addLevelName(level, levelName):
145 """
146 Associate 'levelName' with 'level'.
147
148 This is used when converting levels to text during message formatting.
149 """
150 _acquireLock()
151 try: #unlikely to cause an exception, but you never know...
152 _levelNames[level] = levelName
153 _levelNames[levelName] = level
154 finally:
155 _releaseLock()
156
157#---------------------------------------------------------------------------
158# Thread-related stuff
159#---------------------------------------------------------------------------
160
161#
162#_lock is used to serialize access to shared data structures in this module.
163#This needs to be an RLock because fileConfig() creates Handlers and so
164#might arbitrary user threads. Since Handler.__init__() updates the shared
165#dictionary _handlers, it needs to acquire the lock. But if configuring,
166#the lock would already have been acquired - so we need an RLock.
167#The same argument applies to Loggers and Manager.loggerDict.
168#
169_lock = None
170
171def _acquireLock():
172 """
173 Acquire the module-level lock for serializing access to shared data.
174
175 This should be released with _releaseLock().
176 """
177 global _lock
178 if (not _lock) and thread:
179 _lock = threading.RLock()
180 if _lock:
181 _lock.acquire()
182
183def _releaseLock():
184 """
185 Release the module-level lock acquired by calling _acquireLock().
186 """
187 if _lock:
188 _lock.release()
189
190#---------------------------------------------------------------------------
191# The logging record
192#---------------------------------------------------------------------------
193
194class LogRecord:
195 """
196 A LogRecord instance represents an event being logged.
197
198 LogRecord instances are created every time something is logged. They
199 contain all the information pertinent to the event being logged. The
200 main information passed in is in msg and args, which are combined
201 using str(msg) % args to create the message field of the record. The
202 record also includes information such as when the record was created,
203 the source line where the logging call was made, and any exception
204 information to be logged.
205 """
Vinay Sajiped1992f2006-02-09 08:48:36 +0000206 def __init__(self, name, level, pathname, lineno,
207 msg, args, exc_info, func):
Guido van Rossum57102f82002-11-13 16:15:58 +0000208 """
209 Initialize a logging record with interesting information.
210 """
211 ct = time.time()
212 self.name = name
213 self.msg = msg
Vinay Sajip4ed315a2004-10-20 08:39:40 +0000214 #
215 # The following statement allows passing of a dictionary as a sole
216 # argument, so that you can do something like
217 # logging.debug("a %(a)d b %(b)s", {'a':1, 'b':2})
218 # Suggested by Stefan Behnel.
219 # Note that without the test for args[0], we get a problem because
220 # during formatting, we test to see if the arg is present using
221 # 'if self.args:'. If the event being logged is e.g. 'Value is %d'
222 # and if the passed arg fails 'if self.args:' then no formatting
223 # is done. For example, logger.warn('Value is %d', 0) would log
224 # 'Value is %d' instead of 'Value is 0'.
225 # For the use case of passing a dictionary, this should not be a
226 # problem.
Vinay Sajipdccd4322004-10-21 21:24:27 +0000227 if args and (len(args) == 1) and args[0] and (type(args[0]) == types.DictType):
Vinay Sajip4ed315a2004-10-20 08:39:40 +0000228 args = args[0]
Guido van Rossum57102f82002-11-13 16:15:58 +0000229 self.args = args
230 self.levelname = getLevelName(level)
231 self.levelno = level
232 self.pathname = pathname
233 try:
234 self.filename = os.path.basename(pathname)
235 self.module = os.path.splitext(self.filename)[0]
236 except:
237 self.filename = pathname
238 self.module = "Unknown module"
239 self.exc_info = exc_info
Vinay Sajiped6bb142004-02-20 13:18:36 +0000240 self.exc_text = None # used to cache the traceback text
Guido van Rossum57102f82002-11-13 16:15:58 +0000241 self.lineno = lineno
Vinay Sajiped1992f2006-02-09 08:48:36 +0000242 self.funcName = func
Guido van Rossum57102f82002-11-13 16:15:58 +0000243 self.created = ct
244 self.msecs = (ct - long(ct)) * 1000
245 self.relativeCreated = (self.created - _startTime) * 1000
246 if thread:
247 self.thread = thread.get_ident()
Vinay Sajip4a704862005-03-31 20:16:55 +0000248 self.threadName = threading.currentThread().getName()
Guido van Rossum57102f82002-11-13 16:15:58 +0000249 else:
250 self.thread = None
Vinay Sajip4a704862005-03-31 20:16:55 +0000251 self.threadName = None
Jack Jansen4c641d02003-02-21 22:29:45 +0000252 if hasattr(os, 'getpid'):
253 self.process = os.getpid()
254 else:
255 self.process = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000256
257 def __str__(self):
258 return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
259 self.pathname, self.lineno, self.msg)
260
261 def getMessage(self):
262 """
263 Return the message for this LogRecord.
264
265 Return the message for this LogRecord after merging any user-supplied
266 arguments with the message.
267 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000268 if not hasattr(types, "UnicodeType"): #if no unicode support...
269 msg = str(self.msg)
270 else:
Vinay Sajip43d6e812005-10-07 08:35:36 +0000271 msg = self.msg
272 if type(msg) not in (types.UnicodeType, types.StringType):
273 try:
274 msg = str(self.msg)
275 except UnicodeError:
276 msg = self.msg #Defer encoding till later
Guido van Rossum57102f82002-11-13 16:15:58 +0000277 if self.args:
278 msg = msg % self.args
279 return msg
280
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +0000281def makeLogRecord(dict):
282 """
283 Make a LogRecord whose attributes are defined by the specified dictionary,
284 This function is useful for converting a logging event received over
285 a socket connection (which is sent as a dictionary) into a LogRecord
286 instance.
287 """
Vinay Sajiped1992f2006-02-09 08:48:36 +0000288 rv = LogRecord(None, None, "", 0, "", (), None, None)
Raymond Hettinger6f3eaa62003-06-27 21:43:39 +0000289 rv.__dict__.update(dict)
290 return rv
291
Guido van Rossum57102f82002-11-13 16:15:58 +0000292#---------------------------------------------------------------------------
293# Formatter classes and functions
294#---------------------------------------------------------------------------
295
296class Formatter:
297 """
298 Formatter instances are used to convert a LogRecord to text.
299
300 Formatters need to know how a LogRecord is constructed. They are
301 responsible for converting a LogRecord to (usually) a string which can
302 be interpreted by either a human or an external system. The base Formatter
303 allows a formatting string to be specified. If none is supplied, the
304 default value of "%s(message)\\n" is used.
305
306 The Formatter can be initialized with a format string which makes use of
307 knowledge of the LogRecord attributes - e.g. the default value mentioned
308 above makes use of the fact that the user's message and arguments are pre-
309 formatted into a LogRecord's message attribute. Currently, the useful
310 attributes in a LogRecord are described by:
311
312 %(name)s Name of the logger (logging channel)
313 %(levelno)s Numeric logging level for the message (DEBUG, INFO,
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000314 WARNING, ERROR, CRITICAL)
Guido van Rossum57102f82002-11-13 16:15:58 +0000315 %(levelname)s Text logging level for the message ("DEBUG", "INFO",
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000316 "WARNING", "ERROR", "CRITICAL")
Guido van Rossum57102f82002-11-13 16:15:58 +0000317 %(pathname)s Full pathname of the source file where the logging
318 call was issued (if available)
319 %(filename)s Filename portion of pathname
320 %(module)s Module (name portion of filename)
321 %(lineno)d Source line number where the logging call was issued
322 (if available)
Vinay Sajiped1992f2006-02-09 08:48:36 +0000323 %(funcName)s Function name
Guido van Rossum57102f82002-11-13 16:15:58 +0000324 %(created)f Time when the LogRecord was created (time.time()
325 return value)
326 %(asctime)s Textual time when the LogRecord was created
327 %(msecs)d Millisecond portion of the creation time
328 %(relativeCreated)d Time in milliseconds when the LogRecord was created,
329 relative to the time the logging module was loaded
330 (typically at application startup time)
331 %(thread)d Thread ID (if available)
Vinay Sajip4a704862005-03-31 20:16:55 +0000332 %(threadName)s Thread name (if available)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000333 %(process)d Process ID (if available)
Guido van Rossum57102f82002-11-13 16:15:58 +0000334 %(message)s The result of record.getMessage(), computed just as
335 the record is emitted
336 """
337
338 converter = time.localtime
339
340 def __init__(self, fmt=None, datefmt=None):
341 """
342 Initialize the formatter with specified format strings.
343
344 Initialize the formatter either with the specified format string, or a
345 default as described above. Allow for specialized date formatting with
346 the optional datefmt argument (if omitted, you get the ISO8601 format).
347 """
348 if fmt:
349 self._fmt = fmt
350 else:
351 self._fmt = "%(message)s"
352 self.datefmt = datefmt
353
354 def formatTime(self, record, datefmt=None):
355 """
356 Return the creation time of the specified LogRecord as formatted text.
357
358 This method should be called from format() by a formatter which
359 wants to make use of a formatted time. This method can be overridden
360 in formatters to provide for any specific requirement, but the
361 basic behaviour is as follows: if datefmt (a string) is specified,
362 it is used with time.strftime() to format the creation time of the
363 record. Otherwise, the ISO8601 format is used. The resulting
364 string is returned. This function uses a user-configurable function
365 to convert the creation time to a tuple. By default, time.localtime()
366 is used; to change this for a particular formatter instance, set the
367 'converter' attribute to a function with the same signature as
368 time.localtime() or time.gmtime(). To change it for all formatters,
369 for example if you want all logging times to be shown in GMT,
370 set the 'converter' attribute in the Formatter class.
371 """
372 ct = self.converter(record.created)
373 if datefmt:
374 s = time.strftime(datefmt, ct)
375 else:
376 t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
377 s = "%s,%03d" % (t, record.msecs)
378 return s
379
380 def formatException(self, ei):
381 """
382 Format and return the specified exception information as a string.
383
384 This default implementation just uses
385 traceback.print_exception()
386 """
Guido van Rossum57102f82002-11-13 16:15:58 +0000387 sio = cStringIO.StringIO()
388 traceback.print_exception(ei[0], ei[1], ei[2], None, sio)
389 s = sio.getvalue()
390 sio.close()
391 if s[-1] == "\n":
392 s = s[:-1]
393 return s
394
395 def format(self, record):
396 """
397 Format the specified record as text.
398
399 The record's attribute dictionary is used as the operand to a
400 string formatting operation which yields the returned string.
401 Before formatting the dictionary, a couple of preparatory steps
402 are carried out. The message attribute of the record is computed
403 using LogRecord.getMessage(). If the formatting string contains
404 "%(asctime)", formatTime() is called to format the event time.
405 If there is exception information, it is formatted using
406 formatException() and appended to the message.
407 """
408 record.message = record.getMessage()
409 if string.find(self._fmt,"%(asctime)") >= 0:
410 record.asctime = self.formatTime(record, self.datefmt)
411 s = self._fmt % record.__dict__
412 if record.exc_info:
Vinay Sajiped6bb142004-02-20 13:18:36 +0000413 # Cache the traceback text to avoid converting it multiple times
414 # (it's constant anyway)
415 if not record.exc_text:
416 record.exc_text = self.formatException(record.exc_info)
417 if record.exc_text:
Guido van Rossum57102f82002-11-13 16:15:58 +0000418 if s[-1] != "\n":
419 s = s + "\n"
Vinay Sajiped6bb142004-02-20 13:18:36 +0000420 s = s + record.exc_text
Guido van Rossum57102f82002-11-13 16:15:58 +0000421 return s
422
423#
424# The default formatter to use when no other is specified
425#
426_defaultFormatter = Formatter()
427
428class BufferingFormatter:
429 """
430 A formatter suitable for formatting a number of records.
431 """
432 def __init__(self, linefmt=None):
433 """
434 Optionally specify a formatter which will be used to format each
435 individual record.
436 """
437 if linefmt:
438 self.linefmt = linefmt
439 else:
440 self.linefmt = _defaultFormatter
441
442 def formatHeader(self, records):
443 """
444 Return the header string for the specified records.
445 """
446 return ""
447
448 def formatFooter(self, records):
449 """
450 Return the footer string for the specified records.
451 """
452 return ""
453
454 def format(self, records):
455 """
456 Format the specified records and return the result as a string.
457 """
458 rv = ""
459 if len(records) > 0:
460 rv = rv + self.formatHeader(records)
461 for record in records:
462 rv = rv + self.linefmt.format(record)
463 rv = rv + self.formatFooter(records)
464 return rv
465
466#---------------------------------------------------------------------------
467# Filter classes and functions
468#---------------------------------------------------------------------------
469
470class Filter:
471 """
472 Filter instances are used to perform arbitrary filtering of LogRecords.
473
474 Loggers and Handlers can optionally use Filter instances to filter
475 records as desired. The base filter class only allows events which are
476 below a certain point in the logger hierarchy. For example, a filter
477 initialized with "A.B" will allow events logged by loggers "A.B",
478 "A.B.C", "A.B.C.D", "A.B.D" etc. but not "A.BB", "B.A.B" etc. If
479 initialized with the empty string, all events are passed.
480 """
481 def __init__(self, name=''):
482 """
483 Initialize a filter.
484
485 Initialize with the name of the logger which, together with its
486 children, will have its events allowed through the filter. If no
487 name is specified, allow every event.
488 """
489 self.name = name
490 self.nlen = len(name)
491
492 def filter(self, record):
493 """
494 Determine if the specified record is to be logged.
495
496 Is the specified record to be logged? Returns 0 for no, nonzero for
497 yes. If deemed appropriate, the record may be modified in-place.
498 """
499 if self.nlen == 0:
500 return 1
501 elif self.name == record.name:
502 return 1
503 elif string.find(record.name, self.name, 0, self.nlen) != 0:
504 return 0
505 return (record.name[self.nlen] == ".")
506
507class Filterer:
508 """
509 A base class for loggers and handlers which allows them to share
510 common code.
511 """
512 def __init__(self):
513 """
514 Initialize the list of filters to be an empty list.
515 """
516 self.filters = []
517
518 def addFilter(self, filter):
519 """
520 Add the specified filter to this handler.
521 """
522 if not (filter in self.filters):
523 self.filters.append(filter)
524
525 def removeFilter(self, filter):
526 """
527 Remove the specified filter from this handler.
528 """
529 if filter in self.filters:
530 self.filters.remove(filter)
531
532 def filter(self, record):
533 """
534 Determine if a record is loggable by consulting all the filters.
535
536 The default is to allow the record to be logged; any filter can veto
537 this and the record is then dropped. Returns a zero value if a record
538 is to be dropped, else non-zero.
539 """
540 rv = 1
541 for f in self.filters:
542 if not f.filter(record):
543 rv = 0
544 break
545 return rv
546
547#---------------------------------------------------------------------------
548# Handler classes and functions
549#---------------------------------------------------------------------------
550
551_handlers = {} #repository of handlers (for flushing when shutdown called)
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000552_handlerList = [] # added to allow handlers to be removed in reverse of order initialized
Guido van Rossum57102f82002-11-13 16:15:58 +0000553
554class Handler(Filterer):
555 """
556 Handler instances dispatch logging events to specific destinations.
557
558 The base handler class. Acts as a placeholder which defines the Handler
559 interface. Handlers can optionally use Formatter instances to format
560 records as desired. By default, no formatter is specified; in this case,
561 the 'raw' message as determined by record.message is logged.
562 """
563 def __init__(self, level=NOTSET):
564 """
565 Initializes the instance - basically setting the formatter to None
566 and the filter list to empty.
567 """
568 Filterer.__init__(self)
569 self.level = level
570 self.formatter = None
571 #get the module data lock, as we're updating a shared structure.
572 _acquireLock()
573 try: #unlikely to raise an exception, but you never know...
574 _handlers[self] = 1
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000575 _handlerList.insert(0, self)
Guido van Rossum57102f82002-11-13 16:15:58 +0000576 finally:
577 _releaseLock()
578 self.createLock()
579
580 def createLock(self):
581 """
582 Acquire a thread lock for serializing access to the underlying I/O.
583 """
584 if thread:
Vinay Sajip4a704862005-03-31 20:16:55 +0000585 self.lock = threading.RLock()
Guido van Rossum57102f82002-11-13 16:15:58 +0000586 else:
587 self.lock = None
588
589 def acquire(self):
590 """
591 Acquire the I/O thread lock.
592 """
593 if self.lock:
594 self.lock.acquire()
595
596 def release(self):
597 """
598 Release the I/O thread lock.
599 """
600 if self.lock:
601 self.lock.release()
602
603 def setLevel(self, level):
604 """
605 Set the logging level of this handler.
606 """
607 self.level = level
608
609 def format(self, record):
610 """
611 Format the specified record.
612
613 If a formatter is set, use it. Otherwise, use the default formatter
614 for the module.
615 """
616 if self.formatter:
617 fmt = self.formatter
618 else:
619 fmt = _defaultFormatter
620 return fmt.format(record)
621
622 def emit(self, record):
623 """
624 Do whatever it takes to actually log the specified logging record.
625
626 This version is intended to be implemented by subclasses and so
627 raises a NotImplementedError.
628 """
629 raise NotImplementedError, 'emit must be implemented '\
630 'by Handler subclasses'
631
632 def handle(self, record):
633 """
634 Conditionally emit the specified logging record.
635
636 Emission depends on filters which may have been added to the handler.
637 Wrap the actual emission of the record with acquisition/release of
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000638 the I/O thread lock. Returns whether the filter passed the record for
639 emission.
Guido van Rossum57102f82002-11-13 16:15:58 +0000640 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000641 rv = self.filter(record)
642 if rv:
Guido van Rossum57102f82002-11-13 16:15:58 +0000643 self.acquire()
644 try:
645 self.emit(record)
646 finally:
647 self.release()
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000648 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +0000649
650 def setFormatter(self, fmt):
651 """
652 Set the formatter for this handler.
653 """
654 self.formatter = fmt
655
656 def flush(self):
657 """
658 Ensure all logging output has been flushed.
659
660 This version does nothing and is intended to be implemented by
661 subclasses.
662 """
663 pass
664
665 def close(self):
666 """
667 Tidy up any resources used by the handler.
668
Vinay Sajiped6bb142004-02-20 13:18:36 +0000669 This version does removes the handler from an internal list
670 of handlers which is closed when shutdown() is called. Subclasses
671 should ensure that this gets called from overridden close()
672 methods.
Guido van Rossum57102f82002-11-13 16:15:58 +0000673 """
Vinay Sajiped6bb142004-02-20 13:18:36 +0000674 #get the module data lock, as we're updating a shared structure.
675 _acquireLock()
676 try: #unlikely to raise an exception, but you never know...
Vinay Sajipe0f85922006-02-07 13:55:52 +0000677 del _handlers[self]
Vinay Sajip0ee9ba22005-09-08 18:14:16 +0000678 _handlerList.remove(self)
Vinay Sajiped6bb142004-02-20 13:18:36 +0000679 finally:
680 _releaseLock()
Guido van Rossum57102f82002-11-13 16:15:58 +0000681
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000682 def handleError(self, record):
Guido van Rossum57102f82002-11-13 16:15:58 +0000683 """
684 Handle errors which occur during an emit() call.
685
686 This method should be called from handlers when an exception is
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000687 encountered during an emit() call. If raiseExceptions is false,
Guido van Rossum57102f82002-11-13 16:15:58 +0000688 exceptions get silently ignored. This is what is mostly wanted
689 for a logging system - most users will not care about errors in
690 the logging system, they are more interested in application errors.
691 You could, however, replace this with a custom handler if you wish.
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000692 The record which was being processed is passed in to this method.
Guido van Rossum57102f82002-11-13 16:15:58 +0000693 """
694 if raiseExceptions:
Guido van Rossum57102f82002-11-13 16:15:58 +0000695 ei = sys.exc_info()
696 traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
697 del ei
698
699class StreamHandler(Handler):
700 """
701 A handler class which writes logging records, appropriately formatted,
702 to a stream. Note that this class does not close the stream, as
703 sys.stdout or sys.stderr may be used.
704 """
705 def __init__(self, strm=None):
706 """
707 Initialize the handler.
708
709 If strm is not specified, sys.stderr is used.
710 """
711 Handler.__init__(self)
712 if not strm:
713 strm = sys.stderr
714 self.stream = strm
715 self.formatter = None
716
717 def flush(self):
718 """
719 Flushes the stream.
720 """
721 self.stream.flush()
722
723 def emit(self, record):
724 """
725 Emit a record.
726
727 If a formatter is specified, it is used to format the record.
728 The record is then written to the stream with a trailing newline
729 [N.B. this may be removed depending on feedback]. If exception
730 information is present, it is formatted using
731 traceback.print_exception and appended to the stream.
732 """
733 try:
734 msg = self.format(record)
Vinay Sajipb9591172004-09-22 12:39:26 +0000735 fs = "%s\n"
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000736 if not hasattr(types, "UnicodeType"): #if no unicode support...
Vinay Sajipb9591172004-09-22 12:39:26 +0000737 self.stream.write(fs % msg)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000738 else:
739 try:
Vinay Sajipb9591172004-09-22 12:39:26 +0000740 self.stream.write(fs % msg)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000741 except UnicodeError:
Vinay Sajipb9591172004-09-22 12:39:26 +0000742 self.stream.write(fs % msg.encode("UTF-8"))
Guido van Rossum57102f82002-11-13 16:15:58 +0000743 self.flush()
Vinay Sajip85c19092005-10-31 13:14:19 +0000744 except (KeyboardInterrupt, SystemExit):
745 raise
Guido van Rossum57102f82002-11-13 16:15:58 +0000746 except:
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000747 self.handleError(record)
Guido van Rossum57102f82002-11-13 16:15:58 +0000748
749class FileHandler(StreamHandler):
750 """
751 A handler class which writes formatted logging records to disk files.
752 """
Vinay Sajipb89e7c92005-03-13 09:54:31 +0000753 def __init__(self, filename, mode='a', encoding=None):
Guido van Rossum57102f82002-11-13 16:15:58 +0000754 """
755 Open the specified file and use it as the stream for logging.
756 """
Vinay Sajipb89e7c92005-03-13 09:54:31 +0000757 if codecs is None:
758 encoding = None
759 if encoding is None:
760 stream = open(filename, mode)
761 else:
762 stream = codecs.open(filename, mode, encoding)
763 StreamHandler.__init__(self, stream)
Vinay Sajip4bbab2b2004-07-08 10:22:35 +0000764 #keep the absolute path, otherwise derived classes which use this
765 #may come a cropper when the current directory changes
766 self.baseFilename = os.path.abspath(filename)
Guido van Rossum57102f82002-11-13 16:15:58 +0000767 self.mode = mode
768
769 def close(self):
770 """
771 Closes the stream.
772 """
Vinay Sajip3f9f84d2004-02-21 22:12:32 +0000773 self.flush()
Guido van Rossum57102f82002-11-13 16:15:58 +0000774 self.stream.close()
Vinay Sajiped6bb142004-02-20 13:18:36 +0000775 StreamHandler.close(self)
Guido van Rossum57102f82002-11-13 16:15:58 +0000776
777#---------------------------------------------------------------------------
778# Manager classes and functions
779#---------------------------------------------------------------------------
780
781class PlaceHolder:
782 """
783 PlaceHolder instances are used in the Manager logger hierarchy to take
Vinay Sajip3f742842004-02-28 16:07:46 +0000784 the place of nodes for which no loggers have been defined. This class is
785 intended for internal use only and not as part of the public API.
Guido van Rossum57102f82002-11-13 16:15:58 +0000786 """
787 def __init__(self, alogger):
788 """
789 Initialize with the specified logger being a child of this placeholder.
790 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000791 #self.loggers = [alogger]
792 self.loggerMap = { alogger : None }
Guido van Rossum57102f82002-11-13 16:15:58 +0000793
794 def append(self, alogger):
795 """
796 Add the specified logger as a child of this placeholder.
797 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000798 #if alogger not in self.loggers:
799 if not self.loggerMap.has_key(alogger):
800 #self.loggers.append(alogger)
801 self.loggerMap[alogger] = None
Guido van Rossum57102f82002-11-13 16:15:58 +0000802
803#
804# Determine which class to use when instantiating loggers.
805#
806_loggerClass = None
807
808def setLoggerClass(klass):
809 """
810 Set the class to be used when instantiating a logger. The class should
811 define __init__() such that only a name argument is required, and the
812 __init__() should call Logger.__init__()
813 """
814 if klass != Logger:
Guido van Rossum57102f82002-11-13 16:15:58 +0000815 if not issubclass(klass, Logger):
816 raise TypeError, "logger not derived from logging.Logger: " + \
817 klass.__name__
818 global _loggerClass
819 _loggerClass = klass
820
Vinay Sajipb9591172004-09-22 12:39:26 +0000821def getLoggerClass():
822 """
823 Return the class to be used when instantiating a logger.
824 """
825
826 return _loggerClass
827
Guido van Rossum57102f82002-11-13 16:15:58 +0000828class Manager:
829 """
830 There is [under normal circumstances] just one Manager instance, which
831 holds the hierarchy of loggers.
832 """
Neal Norwitzd1cade02002-11-15 23:31:28 +0000833 def __init__(self, rootnode):
Guido van Rossum57102f82002-11-13 16:15:58 +0000834 """
835 Initialize the manager with the root node of the logger hierarchy.
836 """
Neal Norwitzd1cade02002-11-15 23:31:28 +0000837 self.root = rootnode
Guido van Rossum57102f82002-11-13 16:15:58 +0000838 self.disable = 0
839 self.emittedNoHandlerWarning = 0
840 self.loggerDict = {}
841
842 def getLogger(self, name):
843 """
844 Get a logger with the specified name (channel name), creating it
Vinay Sajipb9591172004-09-22 12:39:26 +0000845 if it doesn't yet exist. This name is a dot-separated hierarchical
846 name, such as "a", "a.b", "a.b.c" or similar.
Guido van Rossum57102f82002-11-13 16:15:58 +0000847
848 If a PlaceHolder existed for the specified name [i.e. the logger
849 didn't exist but a child of it did], replace it with the created
850 logger and fix up the parent/child references which pointed to the
851 placeholder to now point to the logger.
852 """
853 rv = None
854 _acquireLock()
855 try:
856 if self.loggerDict.has_key(name):
857 rv = self.loggerDict[name]
858 if isinstance(rv, PlaceHolder):
859 ph = rv
860 rv = _loggerClass(name)
861 rv.manager = self
862 self.loggerDict[name] = rv
863 self._fixupChildren(ph, rv)
864 self._fixupParents(rv)
865 else:
866 rv = _loggerClass(name)
867 rv.manager = self
868 self.loggerDict[name] = rv
869 self._fixupParents(rv)
870 finally:
871 _releaseLock()
872 return rv
873
874 def _fixupParents(self, alogger):
875 """
876 Ensure that there are either loggers or placeholders all the way
877 from the specified logger to the root of the logger hierarchy.
878 """
879 name = alogger.name
880 i = string.rfind(name, ".")
881 rv = None
882 while (i > 0) and not rv:
883 substr = name[:i]
884 if not self.loggerDict.has_key(substr):
885 self.loggerDict[substr] = PlaceHolder(alogger)
886 else:
887 obj = self.loggerDict[substr]
888 if isinstance(obj, Logger):
889 rv = obj
890 else:
891 assert isinstance(obj, PlaceHolder)
892 obj.append(alogger)
893 i = string.rfind(name, ".", 0, i - 1)
894 if not rv:
895 rv = self.root
896 alogger.parent = rv
897
898 def _fixupChildren(self, ph, alogger):
899 """
900 Ensure that children of the placeholder ph are connected to the
901 specified logger.
902 """
Vinay Sajip239322b2005-10-14 09:36:35 +0000903 #for c in ph.loggers:
904 for c in ph.loggerMap.keys():
Guido van Rossum57102f82002-11-13 16:15:58 +0000905 if string.find(c.parent.name, alogger.name) <> 0:
906 alogger.parent = c.parent
907 c.parent = alogger
908
909#---------------------------------------------------------------------------
910# Logger classes and functions
911#---------------------------------------------------------------------------
912
913class Logger(Filterer):
914 """
915 Instances of the Logger class represent a single logging channel. A
916 "logging channel" indicates an area of an application. Exactly how an
917 "area" is defined is up to the application developer. Since an
918 application can have any number of areas, logging channels are identified
919 by a unique string. Application areas can be nested (e.g. an area
920 of "input processing" might include sub-areas "read CSV files", "read
921 XLS files" and "read Gnumeric files"). To cater for this natural nesting,
922 channel names are organized into a namespace hierarchy where levels are
923 separated by periods, much like the Java or Python package namespace. So
924 in the instance given above, channel names might be "input" for the upper
925 level, and "input.csv", "input.xls" and "input.gnu" for the sub-levels.
926 There is no arbitrary limit to the depth of nesting.
927 """
928 def __init__(self, name, level=NOTSET):
929 """
930 Initialize the logger with a name and an optional level.
931 """
932 Filterer.__init__(self)
933 self.name = name
934 self.level = level
935 self.parent = None
936 self.propagate = 1
937 self.handlers = []
938 self.disabled = 0
939
940 def setLevel(self, level):
941 """
942 Set the logging level of this logger.
943 """
944 self.level = level
945
Guido van Rossum57102f82002-11-13 16:15:58 +0000946 def debug(self, msg, *args, **kwargs):
947 """
948 Log 'msg % args' with severity 'DEBUG'.
949
950 To pass exception information, use the keyword argument exc_info with
951 a true value, e.g.
952
953 logger.debug("Houston, we have a %s", "thorny problem", exc_info=1)
954 """
955 if self.manager.disable >= DEBUG:
956 return
957 if DEBUG >= self.getEffectiveLevel():
Guido van Rossum0df64422003-03-02 20:47:29 +0000958 apply(self._log, (DEBUG, msg, args), kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +0000959
960 def info(self, msg, *args, **kwargs):
961 """
962 Log 'msg % args' with severity 'INFO'.
963
964 To pass exception information, use the keyword argument exc_info with
965 a true value, e.g.
966
967 logger.info("Houston, we have a %s", "interesting problem", exc_info=1)
968 """
969 if self.manager.disable >= INFO:
970 return
971 if INFO >= self.getEffectiveLevel():
Guido van Rossum0df64422003-03-02 20:47:29 +0000972 apply(self._log, (INFO, msg, args), kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +0000973
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000974 def warning(self, msg, *args, **kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +0000975 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000976 Log 'msg % args' with severity 'WARNING'.
Guido van Rossum57102f82002-11-13 16:15:58 +0000977
978 To pass exception information, use the keyword argument exc_info with
979 a true value, e.g.
980
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000981 logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
Guido van Rossum57102f82002-11-13 16:15:58 +0000982 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000983 if self.manager.disable >= WARNING:
Guido van Rossum57102f82002-11-13 16:15:58 +0000984 return
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000985 if self.isEnabledFor(WARNING):
Guido van Rossum0df64422003-03-02 20:47:29 +0000986 apply(self._log, (WARNING, msg, args), kwargs)
Neal Norwitz6fa635d2003-02-18 14:20:07 +0000987
988 warn = warning
Guido van Rossum57102f82002-11-13 16:15:58 +0000989
990 def error(self, msg, *args, **kwargs):
991 """
992 Log 'msg % args' with severity 'ERROR'.
993
994 To pass exception information, use the keyword argument exc_info with
995 a true value, e.g.
996
997 logger.error("Houston, we have a %s", "major problem", exc_info=1)
998 """
999 if self.manager.disable >= ERROR:
1000 return
1001 if self.isEnabledFor(ERROR):
Guido van Rossum0df64422003-03-02 20:47:29 +00001002 apply(self._log, (ERROR, msg, args), kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001003
1004 def exception(self, msg, *args):
1005 """
1006 Convenience method for logging an ERROR with exception information.
1007 """
Guido van Rossum0df64422003-03-02 20:47:29 +00001008 apply(self.error, (msg,) + args, {'exc_info': 1})
Guido van Rossum57102f82002-11-13 16:15:58 +00001009
1010 def critical(self, msg, *args, **kwargs):
1011 """
1012 Log 'msg % args' with severity 'CRITICAL'.
1013
1014 To pass exception information, use the keyword argument exc_info with
1015 a true value, e.g.
1016
1017 logger.critical("Houston, we have a %s", "major disaster", exc_info=1)
1018 """
1019 if self.manager.disable >= CRITICAL:
1020 return
1021 if CRITICAL >= self.getEffectiveLevel():
Guido van Rossum0df64422003-03-02 20:47:29 +00001022 apply(self._log, (CRITICAL, msg, args), kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001023
1024 fatal = critical
1025
1026 def log(self, level, msg, *args, **kwargs):
1027 """
Vinay Sajipeb477d02004-08-04 08:38:08 +00001028 Log 'msg % args' with the integer severity 'level'.
Guido van Rossum57102f82002-11-13 16:15:58 +00001029
1030 To pass exception information, use the keyword argument exc_info with
1031 a true value, e.g.
1032
1033 logger.log(level, "We have a %s", "mysterious problem", exc_info=1)
1034 """
Vinay Sajip779e0c92004-07-03 11:47:26 +00001035 if type(level) != types.IntType:
1036 if raiseExceptions:
1037 raise TypeError, "level must be an integer"
1038 else:
1039 return
Guido van Rossum57102f82002-11-13 16:15:58 +00001040 if self.manager.disable >= level:
1041 return
1042 if self.isEnabledFor(level):
Guido van Rossum0df64422003-03-02 20:47:29 +00001043 apply(self._log, (level, msg, args), kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001044
1045 def findCaller(self):
1046 """
1047 Find the stack frame of the caller so that we can note the source
Vinay Sajip829dc512005-02-18 11:53:32 +00001048 file name, line number and function name.
Guido van Rossum57102f82002-11-13 16:15:58 +00001049 """
Vinay Sajip829dc512005-02-18 11:53:32 +00001050 f = currentframe().f_back
Jeremy Hylton250684d2003-01-23 18:29:29 +00001051 while 1:
1052 co = f.f_code
1053 filename = os.path.normcase(co.co_filename)
1054 if filename == _srcfile:
1055 f = f.f_back
1056 continue
Vinay Sajip829dc512005-02-18 11:53:32 +00001057 return filename, f.f_lineno, co.co_name
Guido van Rossum57102f82002-11-13 16:15:58 +00001058
Vinay Sajiped1992f2006-02-09 08:48:36 +00001059 def makeRecord(self, name, level, fn, lno, msg, args, exc_info, func=None, extra=None):
Guido van Rossum57102f82002-11-13 16:15:58 +00001060 """
1061 A factory method which can be overridden in subclasses to create
1062 specialized LogRecords.
1063 """
Vinay Sajiped1992f2006-02-09 08:48:36 +00001064 rv = LogRecord(name, level, fn, lno, msg, args, exc_info, func)
Vinay Sajip260ce432006-02-09 08:34:14 +00001065 if extra:
1066 for key in extra:
1067 if (key in ["message", "asctime"]) or (key in rv.__dict__):
1068 raise KeyError("Attempt to overwrite %r in LogRecord" % key)
1069 rv.__dict__[key] = extra[key]
1070 return rv
Guido van Rossum57102f82002-11-13 16:15:58 +00001071
Vinay Sajip260ce432006-02-09 08:34:14 +00001072 def _log(self, level, msg, args, exc_info=None, extra=None):
Guido van Rossum57102f82002-11-13 16:15:58 +00001073 """
1074 Low-level logging routine which creates a LogRecord and then calls
1075 all the handlers of this logger to handle the record.
1076 """
Jeremy Hylton250684d2003-01-23 18:29:29 +00001077 if _srcfile:
Vinay Sajip829dc512005-02-18 11:53:32 +00001078 fn, lno, func = self.findCaller()
Guido van Rossum57102f82002-11-13 16:15:58 +00001079 else:
Vinay Sajip829dc512005-02-18 11:53:32 +00001080 fn, lno, func = "(unknown file)", 0, "(unknown function)"
Guido van Rossum57102f82002-11-13 16:15:58 +00001081 if exc_info:
Vinay Sajiped6bb142004-02-20 13:18:36 +00001082 if type(exc_info) != types.TupleType:
1083 exc_info = sys.exc_info()
Vinay Sajiped1992f2006-02-09 08:48:36 +00001084 record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
Guido van Rossum57102f82002-11-13 16:15:58 +00001085 self.handle(record)
1086
1087 def handle(self, record):
1088 """
1089 Call the handlers for the specified record.
1090
1091 This method is used for unpickled records received from a socket, as
1092 well as those created locally. Logger-level filtering is applied.
1093 """
1094 if (not self.disabled) and self.filter(record):
1095 self.callHandlers(record)
1096
1097 def addHandler(self, hdlr):
1098 """
1099 Add the specified handler to this logger.
1100 """
1101 if not (hdlr in self.handlers):
1102 self.handlers.append(hdlr)
1103
1104 def removeHandler(self, hdlr):
1105 """
1106 Remove the specified handler from this logger.
1107 """
1108 if hdlr in self.handlers:
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001109 #hdlr.close()
Vinay Sajip116f16e2005-09-16 10:33:40 +00001110 hdlr.acquire()
1111 try:
1112 self.handlers.remove(hdlr)
1113 finally:
1114 hdlr.release()
Guido van Rossum57102f82002-11-13 16:15:58 +00001115
1116 def callHandlers(self, record):
1117 """
1118 Pass a record to all relevant handlers.
1119
1120 Loop through all handlers for this logger and its parents in the
1121 logger hierarchy. If no handler was found, output a one-off error
1122 message to sys.stderr. Stop searching up the hierarchy whenever a
1123 logger with the "propagate" attribute set to zero is found - that
1124 will be the last logger whose handlers are called.
1125 """
1126 c = self
1127 found = 0
1128 while c:
1129 for hdlr in c.handlers:
1130 found = found + 1
1131 if record.levelno >= hdlr.level:
1132 hdlr.handle(record)
1133 if not c.propagate:
1134 c = None #break out
1135 else:
1136 c = c.parent
Vinay Sajip1e86beb2005-10-23 22:32:59 +00001137 if (found == 0) and raiseExceptions and not self.manager.emittedNoHandlerWarning:
Guido van Rossum57102f82002-11-13 16:15:58 +00001138 sys.stderr.write("No handlers could be found for logger"
1139 " \"%s\"\n" % self.name)
1140 self.manager.emittedNoHandlerWarning = 1
1141
1142 def getEffectiveLevel(self):
1143 """
1144 Get the effective level for this logger.
1145
1146 Loop through this logger and its parents in the logger hierarchy,
1147 looking for a non-zero logging level. Return the first one found.
1148 """
1149 logger = self
1150 while logger:
1151 if logger.level:
1152 return logger.level
1153 logger = logger.parent
1154 return NOTSET
1155
1156 def isEnabledFor(self, level):
1157 """
1158 Is this logger enabled for level 'level'?
1159 """
1160 if self.manager.disable >= level:
1161 return 0
1162 return level >= self.getEffectiveLevel()
1163
1164class RootLogger(Logger):
1165 """
1166 A root logger is not that different to any other logger, except that
1167 it must have a logging level and there is only one instance of it in
1168 the hierarchy.
1169 """
1170 def __init__(self, level):
1171 """
1172 Initialize the logger with the name "root".
1173 """
1174 Logger.__init__(self, "root", level)
1175
1176_loggerClass = Logger
1177
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001178root = RootLogger(WARNING)
Guido van Rossum57102f82002-11-13 16:15:58 +00001179Logger.root = root
1180Logger.manager = Manager(Logger.root)
1181
1182#---------------------------------------------------------------------------
1183# Configuration classes and functions
1184#---------------------------------------------------------------------------
1185
1186BASIC_FORMAT = "%(levelname)s:%(name)s:%(message)s"
1187
Vinay Sajip779e0c92004-07-03 11:47:26 +00001188def basicConfig(**kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001189 """
Vinay Sajip779e0c92004-07-03 11:47:26 +00001190 Do basic configuration for the logging system.
1191
1192 This function does nothing if the root logger already has handlers
1193 configured. It is a convenience method intended for use by simple scripts
1194 to do one-shot configuration of the logging package.
1195
1196 The default behaviour is to create a StreamHandler which writes to
1197 sys.stderr, set a formatter using the BASIC_FORMAT format string, and
1198 add the handler to the root logger.
1199
1200 A number of optional keyword arguments may be specified, which can alter
1201 the default behaviour.
1202
1203 filename Specifies that a FileHandler be created, using the specified
1204 filename, rather than a StreamHandler.
1205 filemode Specifies the mode to open the file, if filename is specified
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001206 (if filemode is unspecified, it defaults to 'a').
Vinay Sajip779e0c92004-07-03 11:47:26 +00001207 format Use the specified format string for the handler.
1208 datefmt Use the specified date/time format.
1209 level Set the root logger level to the specified level.
1210 stream Use the specified stream to initialize the StreamHandler. Note
1211 that this argument is incompatible with 'filename' - if both
1212 are present, 'stream' is ignored.
1213
1214 Note that you could specify a stream created using open(filename, mode)
1215 rather than passing the filename and mode in. However, it should be
1216 remembered that StreamHandler does not close its stream (since it may be
1217 using sys.stdout or sys.stderr), whereas FileHandler closes its stream
1218 when the handler is closed.
Guido van Rossum57102f82002-11-13 16:15:58 +00001219 """
1220 if len(root.handlers) == 0:
Vinay Sajip779e0c92004-07-03 11:47:26 +00001221 filename = kwargs.get("filename")
1222 if filename:
Vinay Sajipb89e7c92005-03-13 09:54:31 +00001223 mode = kwargs.get("filemode", 'a')
Vinay Sajip779e0c92004-07-03 11:47:26 +00001224 hdlr = FileHandler(filename, mode)
1225 else:
1226 stream = kwargs.get("stream")
1227 hdlr = StreamHandler(stream)
1228 fs = kwargs.get("format", BASIC_FORMAT)
1229 dfs = kwargs.get("datefmt", None)
1230 fmt = Formatter(fs, dfs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001231 hdlr.setFormatter(fmt)
1232 root.addHandler(hdlr)
Vinay Sajip779e0c92004-07-03 11:47:26 +00001233 level = kwargs.get("level")
1234 if level:
Tim Peters4e0e1b62004-07-07 20:54:48 +00001235 root.setLevel(level)
Guido van Rossum57102f82002-11-13 16:15:58 +00001236
1237#---------------------------------------------------------------------------
1238# Utility functions at module level.
1239# Basically delegate everything to the root logger.
1240#---------------------------------------------------------------------------
1241
1242def getLogger(name=None):
1243 """
1244 Return a logger with the specified name, creating it if necessary.
1245
1246 If no name is specified, return the root logger.
1247 """
1248 if name:
1249 return Logger.manager.getLogger(name)
1250 else:
1251 return root
1252
1253#def getRootLogger():
1254# """
1255# Return the root logger.
1256#
1257# Note that getLogger('') now does the same thing, so this function is
1258# deprecated and may disappear in the future.
1259# """
1260# return root
1261
1262def critical(msg, *args, **kwargs):
1263 """
1264 Log a message with severity 'CRITICAL' on the root logger.
1265 """
1266 if len(root.handlers) == 0:
1267 basicConfig()
Guido van Rossum0df64422003-03-02 20:47:29 +00001268 apply(root.critical, (msg,)+args, kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001269
1270fatal = critical
1271
1272def error(msg, *args, **kwargs):
1273 """
1274 Log a message with severity 'ERROR' on the root logger.
1275 """
1276 if len(root.handlers) == 0:
1277 basicConfig()
Guido van Rossum0df64422003-03-02 20:47:29 +00001278 apply(root.error, (msg,)+args, kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001279
1280def exception(msg, *args):
1281 """
1282 Log a message with severity 'ERROR' on the root logger,
1283 with exception information.
1284 """
Guido van Rossum0df64422003-03-02 20:47:29 +00001285 apply(error, (msg,)+args, {'exc_info': 1})
Guido van Rossum57102f82002-11-13 16:15:58 +00001286
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001287def warning(msg, *args, **kwargs):
Guido van Rossum57102f82002-11-13 16:15:58 +00001288 """
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001289 Log a message with severity 'WARNING' on the root logger.
Guido van Rossum57102f82002-11-13 16:15:58 +00001290 """
1291 if len(root.handlers) == 0:
1292 basicConfig()
Guido van Rossum0df64422003-03-02 20:47:29 +00001293 apply(root.warning, (msg,)+args, kwargs)
Neal Norwitz6fa635d2003-02-18 14:20:07 +00001294
1295warn = warning
Guido van Rossum57102f82002-11-13 16:15:58 +00001296
1297def info(msg, *args, **kwargs):
1298 """
1299 Log a message with severity 'INFO' on the root logger.
1300 """
1301 if len(root.handlers) == 0:
1302 basicConfig()
Guido van Rossum0df64422003-03-02 20:47:29 +00001303 apply(root.info, (msg,)+args, kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001304
1305def debug(msg, *args, **kwargs):
1306 """
1307 Log a message with severity 'DEBUG' on the root logger.
1308 """
1309 if len(root.handlers) == 0:
1310 basicConfig()
Guido van Rossum0df64422003-03-02 20:47:29 +00001311 apply(root.debug, (msg,)+args, kwargs)
Guido van Rossum57102f82002-11-13 16:15:58 +00001312
Vinay Sajipb2635b22004-09-24 11:45:52 +00001313def log(level, msg, *args, **kwargs):
1314 """
1315 Log 'msg % args' with the integer severity 'level' on the root logger.
1316 """
1317 if len(root.handlers) == 0:
1318 basicConfig()
1319 apply(root.log, (level, msg)+args, kwargs)
1320
Guido van Rossum57102f82002-11-13 16:15:58 +00001321def disable(level):
1322 """
1323 Disable all logging calls less severe than 'level'.
1324 """
1325 root.manager.disable = level
1326
1327def shutdown():
1328 """
1329 Perform any cleanup actions in the logging system (e.g. flushing
1330 buffers).
1331
1332 Should be called at application exit.
1333 """
Vinay Sajip0ee9ba22005-09-08 18:14:16 +00001334 for h in _handlerList[:]: # was _handlers.keys():
Vinay Sajipe12f7152004-07-29 09:19:30 +00001335 #errors might occur, for example, if files are locked
Vinay Sajip260ce432006-02-09 08:34:14 +00001336 #we just ignore them if raiseExceptions is not set
Vinay Sajipe12f7152004-07-29 09:19:30 +00001337 try:
1338 h.flush()
1339 h.close()
1340 except:
Vinay Sajip260ce432006-02-09 08:34:14 +00001341 if raiseExceptions:
1342 raise
1343 #else, swallow
Vinay Sajiped6bb142004-02-20 13:18:36 +00001344
1345#Let's try and shutdown automatically on application exit...
1346try:
1347 import atexit
1348 atexit.register(shutdown)
1349except ImportError: # for Python versions < 2.0
1350 def exithook(status, old_exit=sys.exit):
1351 try:
1352 shutdown()
1353 finally:
1354 old_exit(status)
1355
1356 sys.exit = exithook