SF patch #687683, Patches to logging (updates from Vinay)

Mostly rename WARN -> WARNING
Other misc tweaks
Update tests (not in original patch)
This commit is contained in:
Neal Norwitz 2003-02-18 14:20:07 +00:00
parent d6a3f93070
commit 6fa635df7a
5 changed files with 98 additions and 63 deletions

View file

@ -36,16 +36,24 @@ except ImportError:
__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
__status__ = "alpha"
__version__ = "0.4.7"
__date__ = "27 August 2002"
__version__ = "0.4.8"
__date__ = "16 February 2003"
#---------------------------------------------------------------------------
# Miscellaneous module data
#---------------------------------------------------------------------------
#
# _verinfo is used for when behaviour needs to be adjusted to the version
# of Python
#
_verinfo = getattr(sys, "version_info", None)
#
#_srcfile is used when walking the stack to check when we've got the first
# caller stack frame.
#
if string.lower(__file__[-4:]) in ['.pyc', '.pyo']:
_srcfile = __file__[:-4] + '.py'
else:
@ -70,7 +78,6 @@ _startTime = time.time()
#
raiseExceptions = 1
#---------------------------------------------------------------------------
# Level related stuff
#---------------------------------------------------------------------------
@ -84,7 +91,8 @@ raiseExceptions = 1
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARN = 30
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
@ -92,13 +100,14 @@ NOTSET = 0
_levelNames = {
CRITICAL : 'CRITICAL',
ERROR : 'ERROR',
WARN : 'WARN',
WARNING : 'WARNING',
INFO : 'INFO',
DEBUG : 'DEBUG',
NOTSET : 'NOTSET',
'CRITICAL' : CRITICAL,
'ERROR' : ERROR,
'WARN' : WARN,
'WARN' : WARNING,
'WARNING' : WARNING,
'INFO' : INFO,
'DEBUG' : DEBUG,
'NOTSET' : NOTSET,
@ -108,7 +117,7 @@ def getLevelName(level):
"""
Return the textual representation of logging level 'level'.
If the level is one of the predefined levels (CRITICAL, ERROR, WARN,
If the level is one of the predefined levels (CRITICAL, ERROR, WARNING,
INFO, DEBUG) then you get the corresponding string. If you have
associated levels with names using addLevelName then the name you have
associated with 'level' is returned. Otherwise, the string
@ -204,6 +213,7 @@ class LogRecord:
self.thread = thread.get_ident()
else:
self.thread = None
self.process = os.getpid()
def __str__(self):
return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
@ -216,7 +226,13 @@ class LogRecord:
Return the message for this LogRecord after merging any user-supplied
arguments with the message.
"""
msg = str(self.msg)
if not hasattr(types, "UnicodeType"): #if no unicode support...
msg = str(self.msg)
else:
try:
msg = str(self.msg)
except UnicodeError:
msg = self.msg #Defer encoding till later
if self.args:
msg = msg % self.args
return msg
@ -243,9 +259,9 @@ class Formatter:
%(name)s Name of the logger (logging channel)
%(levelno)s Numeric logging level for the message (DEBUG, INFO,
WARN, ERROR, CRITICAL)
WARNING, ERROR, CRITICAL)
%(levelname)s Text logging level for the message ("DEBUG", "INFO",
"WARN", "ERROR", "CRITICAL")
"WARNING", "ERROR", "CRITICAL")
%(pathname)s Full pathname of the source file where the logging
call was issued (if available)
%(filename)s Filename portion of pathname
@ -260,6 +276,7 @@ class Formatter:
relative to the time the logging module was loaded
(typically at application startup time)
%(thread)d Thread ID (if available)
%(process)d Process ID (if available)
%(message)s The result of record.getMessage(), computed just as
the record is emitted
"""
@ -558,14 +575,17 @@ class Handler(Filterer):
Emission depends on filters which may have been added to the handler.
Wrap the actual emission of the record with acquisition/release of
the I/O thread lock.
the I/O thread lock. Returns whether the filter passed the record for
emission.
"""
if self.filter(record):
rv = self.filter(record)
if rv:
self.acquire()
try:
self.emit(record)
finally:
self.release()
return rv
def setFormatter(self, fmt):
"""
@ -591,17 +611,17 @@ class Handler(Filterer):
"""
pass
def handleError(self):
def handleError(self, record):
"""
Handle errors which occur during an emit() call.
This method should be called from handlers when an exception is
encountered during an emit() call. By default it does nothing,
because by default raiseExceptions is false, which means that
encountered during an emit() call. If raiseExceptions is false,
exceptions get silently ignored. This is what is mostly wanted
for a logging system - most users will not care about errors in
the logging system, they are more interested in application errors.
You could, however, replace this with a custom handler if you wish.
The record which was being processed is passed in to this method.
"""
if raiseExceptions:
import traceback
@ -645,10 +665,16 @@ class StreamHandler(Handler):
"""
try:
msg = self.format(record)
self.stream.write("%s\n" % msg)
if not hasattr(types, "UnicodeType"): #if no unicode support...
self.stream.write("%s\n" % msg)
else:
try:
self.stream.write("%s\n" % msg)
except UnicodeError:
self.stream.write("%s\n" % msg.encode("UTF-8"))
self.flush()
except:
self.handleError()
self.handleError(record)
class FileHandler(StreamHandler):
"""
@ -861,19 +887,21 @@ class Logger(Filterer):
if INFO >= self.getEffectiveLevel():
apply(self._log, (INFO, msg, args), kwargs)
def warn(self, msg, *args, **kwargs):
def warning(self, msg, *args, **kwargs):
"""
Log 'msg % args' with severity 'WARN'.
Log 'msg % args' with severity 'WARNING'.
To pass exception information, use the keyword argument exc_info with
a true value, e.g.
logger.warn("Houston, we have a %s", "bit of a problem", exc_info=1)
logger.warning("Houston, we have a %s", "bit of a problem", exc_info=1)
"""
if self.manager.disable >= WARN:
if self.manager.disable >= WARNING:
return
if self.isEnabledFor(WARN):
apply(self._log, (WARN, msg, args), kwargs)
if self.isEnabledFor(WARNING):
apply(self._log, (WARNING, msg, args), kwargs)
warn = warning
def error(self, msg, *args, **kwargs):
"""
@ -982,7 +1010,7 @@ class Logger(Filterer):
Remove the specified handler from this logger.
"""
if hdlr in self.handlers:
hdlr.close()
#hdlr.close()
self.handlers.remove(hdlr)
def callHandlers(self, record):
@ -1047,7 +1075,7 @@ class RootLogger(Logger):
_loggerClass = Logger
root = RootLogger(WARN)
root = RootLogger(WARNING)
Logger.root = root
Logger.manager = Manager(Logger.root)
@ -1119,13 +1147,15 @@ def exception(msg, *args):
"""
apply(error, (msg,)+args, {'exc_info': 1})
def warn(msg, *args, **kwargs):
def warning(msg, *args, **kwargs):
"""
Log a message with severity 'WARN' on the root logger.
Log a message with severity 'WARNING' on the root logger.
"""
if len(root.handlers) == 0:
basicConfig()
apply(root.warn, (msg,)+args, kwargs)
apply(root.warning, (msg,)+args, kwargs)
warn = warning
def info(msg, *args, **kwargs):
"""

View file

@ -100,7 +100,7 @@ class RotatingFileHandler(logging.FileHandler):
"""
if self.maxBytes > 0: # are we rolling over?
msg = "%s\n" % self.format(record)
#print msg
self.stream.seek(0, 2) #due to non-posix-compliant Windows feature
if self.stream.tell() + len(msg) >= self.maxBytes:
self.doRollover()
logging.FileHandler.emit(self, record)
@ -145,8 +145,8 @@ class SocketHandler(logging.Handler):
This function allows for partial sends which can happen when the
network is busy.
"""
v = sys.version_info
if v[0] >= 2 and v[1] >= 2:
v = logging._verinfo
if v and (v[0] >= 2) and (v[1] >= 2):
self.sock.sendall(s)
else:
sentsofar = 0
@ -167,7 +167,7 @@ class SocketHandler(logging.Handler):
slen = struct.pack(">L", len(s))
return slen + s
def handleError(self):
def handleError(self, record):
"""
Handle an error during logging.
@ -179,7 +179,7 @@ class SocketHandler(logging.Handler):
self.sock.close()
self.sock = None #try to reconnect next time
else:
logging.Handler.handleError(self)
logging.Handler.handleError(self, record)
def emit(self, record):
"""
@ -196,7 +196,7 @@ class SocketHandler(logging.Handler):
self.sock = self.makeSocket()
self.send(s)
except:
self.handleError()
self.handleError(record)
def close(self):
"""
@ -355,7 +355,7 @@ class SysLogHandler(logging.Handler):
except socket.error:
self.socket.close()
self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.socket.connect(address)
self.socket.connect(address)
self.unixsocket = 1
else:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
@ -411,7 +411,7 @@ class SysLogHandler(logging.Handler):
else:
self.socket.sendto(msg, self.address)
except:
self.handleError()
self.handleError(record)
class SMTPHandler(logging.Handler):
"""
@ -434,6 +434,8 @@ class SMTPHandler(logging.Handler):
self.mailhost = mailhost
self.mailport = None
self.fromaddr = fromaddr
if type(toaddrs) == types.StringType:
toaddrs = [toaddrs]
self.toaddrs = toaddrs
self.subject = subject
@ -467,7 +469,7 @@ class SMTPHandler(logging.Handler):
smtp.sendmail(self.fromaddr, self.toaddrs, msg)
smtp.quit()
except:
self.handleError()
self.handleError(record)
class NTEventLogHandler(logging.Handler):
"""
@ -496,7 +498,7 @@ class NTEventLogHandler(logging.Handler):
self.typemap = {
logging.DEBUG : win32evtlog.EVENTLOG_INFORMATION_TYPE,
logging.INFO : win32evtlog.EVENTLOG_INFORMATION_TYPE,
logging.WARN : win32evtlog.EVENTLOG_WARNING_TYPE,
logging.WARNING : win32evtlog.EVENTLOG_WARNING_TYPE,
logging.ERROR : win32evtlog.EVENTLOG_ERROR_TYPE,
logging.CRITICAL: win32evtlog.EVENTLOG_ERROR_TYPE,
}
@ -531,7 +533,7 @@ class NTEventLogHandler(logging.Handler):
Override this if you want to specify your own types. This version does
a mapping using the handler's typemap attribute, which is set up in
__init__() to a dictionary which contains mappings for DEBUG, INFO,
WARN, ERROR and CRITICAL. If you are using your own levels you will
WARNING, ERROR and CRITICAL. If you are using your own levels you will
either need to override this method or place a suitable dictionary in
the handler's typemap attribute.
"""
@ -552,7 +554,7 @@ class NTEventLogHandler(logging.Handler):
msg = self.format(record)
self._welu.ReportEvent(self.appname, id, cat, type, [msg])
except:
self.handleError()
self.handleError(record)
def close(self):
"""
@ -610,7 +612,7 @@ class HTTPHandler(logging.Handler):
h.send(data)
h.getreply() #can't do anything with the result
except:
self.handleError()
self.handleError(record)
class BufferingHandler(logging.Handler):
"""