Kaydet (Commit) 6fa635df authored tarafından Neal Norwitz's avatar Neal Norwitz

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

Mostly rename WARN -> WARNING
Other misc tweaks
Update tests (not in original patch)
üst d6a3f930
...@@ -250,8 +250,9 @@ constructor sets this attribute to 1. ...@@ -250,8 +250,9 @@ constructor sets this attribute to 1.
\begin{methoddesc}{setLevel}{lvl} \begin{methoddesc}{setLevel}{lvl}
Sets the threshold for this logger to \var{lvl}. Logging messages Sets the threshold for this logger to \var{lvl}. Logging messages
which are less severe than \var{lvl} will be ignored. When a logger is which are less severe than \var{lvl} will be ignored. When a logger is
created, the level is set to \constant{ALL} (which causes all messages created, the level is set to \constant{NOTSET} (which causes all messages
to be processed). to be processed in the root logger, or delegation to the parent in non-root
loggers).
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{isEnabledFor}{lvl} \begin{methoddesc}{isEnabledFor}{lvl}
...@@ -263,9 +264,9 @@ determined by \method{getEffectiveLevel()}. ...@@ -263,9 +264,9 @@ determined by \method{getEffectiveLevel()}.
\begin{methoddesc}{getEffectiveLevel}{} \begin{methoddesc}{getEffectiveLevel}{}
Indicates the effective level for this logger. If a value other than Indicates the effective level for this logger. If a value other than
\constant{ALL} has been set using \method{setLevel()}, it is returned. \constant{NOTSET} has been set using \method{setLevel()}, it is returned.
Otherwise, the hierarchy is traversed towards the root until a value Otherwise, the hierarchy is traversed towards the root until a value
other than \constant{ALL} is found, and that value is returned. other than \constant{NOTSET} is found,and that value is returned.
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{debug}{msg\optional{, *args\optional{, **kwargs}}} \begin{methoddesc}{debug}{msg\optional{, *args\optional{, **kwargs}}}
...@@ -355,7 +356,7 @@ Handlers have the following attributes and methods. Note that ...@@ -355,7 +356,7 @@ Handlers have the following attributes and methods. Note that
base for more useful subclasses. However, the \method{__init__()} base for more useful subclasses. However, the \method{__init__()}
method in subclasses needs to call \method{Handler.__init__()}. method in subclasses needs to call \method{Handler.__init__()}.
\begin{methoddesc}{__init__}{level=\constant{ALL}} \begin{methoddesc}{__init__}{level=\constant{NOTSET}}
Initializes the \class{Handler} instance by setting its level, setting Initializes the \class{Handler} instance by setting its level, setting
the list of filters to the empty list and creating a lock (using the list of filters to the empty list and creating a lock (using
\method{getLock()}) for serializing access to an I/O mechanism. \method{getLock()}) for serializing access to an I/O mechanism.
...@@ -377,7 +378,7 @@ Releases the thread lock acquired with \method{acquire()}. ...@@ -377,7 +378,7 @@ Releases the thread lock acquired with \method{acquire()}.
\begin{methoddesc}{setLevel}{lvl} \begin{methoddesc}{setLevel}{lvl}
Sets the threshold for this handler to \var{lvl}. Logging messages which are Sets the threshold for this handler to \var{lvl}. Logging messages which are
less severe than \var{lvl} will be ignored. When a handler is created, the less severe than \var{lvl} will be ignored. When a handler is created, the
level is set to \constant{ALL} (which causes all messages to be processed). level is set to \constant{NOTSET} (which causes all messages to be processed).
\end{methoddesc} \end{methoddesc}
\begin{methoddesc}{setFormatter}{form} \begin{methoddesc}{setFormatter}{form}
...@@ -487,7 +488,7 @@ Outputs the record to the file. ...@@ -487,7 +488,7 @@ Outputs the record to the file.
The \class{RotatingFileHandler} class supports rotation of disk log files. The \class{RotatingFileHandler} class supports rotation of disk log files.
\begin{classdesc}{RotatingFileHandler}{filename\optional{, mode, maxBytes, \begin{classdesc}{RotatingFileHandler}{filename\optional{, mode, maxBytes,
backupCount}} backupCount}}
Returns a new instance of the \class{RotatingFileHandler} class. The Returns a new instance of the \class{RotatingFileHandler} class. The
specified file is opened and used as the stream for logging. If specified file is opened and used as the stream for logging. If
\var{mode} is not specified, \code{'a'} is used. By default, the \var{mode} is not specified, \code{'a'} is used. By default, the
...@@ -736,7 +737,7 @@ overridden to implement custom flushing strategies. ...@@ -736,7 +737,7 @@ overridden to implement custom flushing strategies.
\end{methoddesc} \end{methoddesc}
\begin{classdesc}{MemoryHandler}{capacity\optional{, flushLevel \begin{classdesc}{MemoryHandler}{capacity\optional{, flushLevel
\optional{, target}}} \optional{, target}}}
Returns a new instance of the \class{MemoryHandler} class. The Returns a new instance of the \class{MemoryHandler} class. The
instance is initialized with a buffer size of \var{capacity}. If instance is initialized with a buffer size of \var{capacity}. If
\var{flushLevel} is not specified, \constant{ERROR} is used. If no \var{flushLevel} is not specified, \constant{ERROR} is used. If no
...@@ -813,10 +814,10 @@ described by: ...@@ -813,10 +814,10 @@ described by:
relative to the time the logging module was loaded relative to the time the logging module was loaded
(typically at application startup time) (typically at application startup time)
\%(thread)d Thread ID (if available) \%(thread)d Thread ID (if available)
\%(process)d Process ID (if available)
\%(message)s The result of msg \% args, computed just as the \%(message)s The result of msg \% args, computed just as the
record is emitted record is emitted
\begin{classdesc}{Formatter}{\optional{fmt\optional{, datefmt}}} \begin{classdesc}{Formatter}{\optional{fmt\optional{, datefmt}}}
Returns a new instance of the \class{Formatter} class. The Returns a new instance of the \class{Formatter} class. The
instance is initialized with a format string for the message as a whole, instance is initialized with a format string for the message as a whole,
...@@ -889,7 +890,7 @@ logging event. The only reason it's a class rather than a dictionary is to ...@@ -889,7 +890,7 @@ logging event. The only reason it's a class rather than a dictionary is to
facilitate extension. facilitate extension.
\begin{classdesc}{LogRecord}{name, lvl, pathname, lineno, msg, args, \begin{classdesc}{LogRecord}{name, lvl, pathname, lineno, msg, args,
exc_info} exc_info}
Returns an instance of \class{LogRecord} initialized with interesting Returns an instance of \class{LogRecord} initialized with interesting
information. The \var{name} is the logger name; \var{lvl} is the information. The \var{name} is the logger name; \var{lvl} is the
numeric level; \var{pathname} is the absolute pathname of the source numeric level; \var{pathname} is the absolute pathname of the source
......
...@@ -36,16 +36,24 @@ except ImportError: ...@@ -36,16 +36,24 @@ except ImportError:
__author__ = "Vinay Sajip <vinay_sajip@red-dove.com>" __author__ = "Vinay Sajip <vinay_sajip@red-dove.com>"
__status__ = "alpha" __status__ = "alpha"
__version__ = "0.4.7" __version__ = "0.4.8"
__date__ = "27 August 2002" __date__ = "16 February 2003"
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Miscellaneous module data # 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 #_srcfile is used when walking the stack to check when we've got the first
# caller stack frame. # caller stack frame.
#
if string.lower(__file__[-4:]) in ['.pyc', '.pyo']: if string.lower(__file__[-4:]) in ['.pyc', '.pyo']:
_srcfile = __file__[:-4] + '.py' _srcfile = __file__[:-4] + '.py'
else: else:
...@@ -70,7 +78,6 @@ _startTime = time.time() ...@@ -70,7 +78,6 @@ _startTime = time.time()
# #
raiseExceptions = 1 raiseExceptions = 1
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Level related stuff # Level related stuff
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
...@@ -84,7 +91,8 @@ raiseExceptions = 1 ...@@ -84,7 +91,8 @@ raiseExceptions = 1
CRITICAL = 50 CRITICAL = 50
FATAL = CRITICAL FATAL = CRITICAL
ERROR = 40 ERROR = 40
WARN = 30 WARNING = 30
WARN = WARNING
INFO = 20 INFO = 20
DEBUG = 10 DEBUG = 10
NOTSET = 0 NOTSET = 0
...@@ -92,13 +100,14 @@ NOTSET = 0 ...@@ -92,13 +100,14 @@ NOTSET = 0
_levelNames = { _levelNames = {
CRITICAL : 'CRITICAL', CRITICAL : 'CRITICAL',
ERROR : 'ERROR', ERROR : 'ERROR',
WARN : 'WARN', WARNING : 'WARNING',
INFO : 'INFO', INFO : 'INFO',
DEBUG : 'DEBUG', DEBUG : 'DEBUG',
NOTSET : 'NOTSET', NOTSET : 'NOTSET',
'CRITICAL' : CRITICAL, 'CRITICAL' : CRITICAL,
'ERROR' : ERROR, 'ERROR' : ERROR,
'WARN' : WARN, 'WARN' : WARNING,
'WARNING' : WARNING,
'INFO' : INFO, 'INFO' : INFO,
'DEBUG' : DEBUG, 'DEBUG' : DEBUG,
'NOTSET' : NOTSET, 'NOTSET' : NOTSET,
...@@ -108,7 +117,7 @@ def getLevelName(level): ...@@ -108,7 +117,7 @@ def getLevelName(level):
""" """
Return the textual representation of logging level '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 INFO, DEBUG) then you get the corresponding string. If you have
associated levels with names using addLevelName then the name you have associated levels with names using addLevelName then the name you have
associated with 'level' is returned. Otherwise, the string associated with 'level' is returned. Otherwise, the string
...@@ -204,6 +213,7 @@ class LogRecord: ...@@ -204,6 +213,7 @@ class LogRecord:
self.thread = thread.get_ident() self.thread = thread.get_ident()
else: else:
self.thread = None self.thread = None
self.process = os.getpid()
def __str__(self): def __str__(self):
return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno, return '<LogRecord: %s, %s, %s, %s, "%s">'%(self.name, self.levelno,
...@@ -216,7 +226,13 @@ class LogRecord: ...@@ -216,7 +226,13 @@ class LogRecord:
Return the message for this LogRecord after merging any user-supplied Return the message for this LogRecord after merging any user-supplied
arguments with the message. 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: if self.args:
msg = msg % self.args msg = msg % self.args
return msg return msg
...@@ -243,9 +259,9 @@ class Formatter: ...@@ -243,9 +259,9 @@ class Formatter:
%(name)s Name of the logger (logging channel) %(name)s Name of the logger (logging channel)
%(levelno)s Numeric logging level for the message (DEBUG, INFO, %(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", %(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 %(pathname)s Full pathname of the source file where the logging
call was issued (if available) call was issued (if available)
%(filename)s Filename portion of pathname %(filename)s Filename portion of pathname
...@@ -260,6 +276,7 @@ class Formatter: ...@@ -260,6 +276,7 @@ class Formatter:
relative to the time the logging module was loaded relative to the time the logging module was loaded
(typically at application startup time) (typically at application startup time)
%(thread)d Thread ID (if available) %(thread)d Thread ID (if available)
%(process)d Process ID (if available)
%(message)s The result of record.getMessage(), computed just as %(message)s The result of record.getMessage(), computed just as
the record is emitted the record is emitted
""" """
...@@ -558,14 +575,17 @@ class Handler(Filterer): ...@@ -558,14 +575,17 @@ class Handler(Filterer):
Emission depends on filters which may have been added to the handler. Emission depends on filters which may have been added to the handler.
Wrap the actual emission of the record with acquisition/release of 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() self.acquire()
try: try:
self.emit(record) self.emit(record)
finally: finally:
self.release() self.release()
return rv
def setFormatter(self, fmt): def setFormatter(self, fmt):
""" """
...@@ -591,17 +611,17 @@ class Handler(Filterer): ...@@ -591,17 +611,17 @@ class Handler(Filterer):
""" """
pass pass
def handleError(self): def handleError(self, record):
""" """
Handle errors which occur during an emit() call. Handle errors which occur during an emit() call.
This method should be called from handlers when an exception is This method should be called from handlers when an exception is
encountered during an emit() call. By default it does nothing, encountered during an emit() call. If raiseExceptions is false,
because by default raiseExceptions is false, which means that
exceptions get silently ignored. This is what is mostly wanted exceptions get silently ignored. This is what is mostly wanted
for a logging system - most users will not care about errors in for a logging system - most users will not care about errors in
the logging system, they are more interested in application errors. the logging system, they are more interested in application errors.
You could, however, replace this with a custom handler if you wish. 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: if raiseExceptions:
import traceback import traceback
...@@ -645,10 +665,16 @@ class StreamHandler(Handler): ...@@ -645,10 +665,16 @@ class StreamHandler(Handler):
""" """
try: try:
msg = self.format(record) 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() self.flush()
except: except:
self.handleError() self.handleError(record)
class FileHandler(StreamHandler): class FileHandler(StreamHandler):
""" """
...@@ -861,19 +887,21 @@ class Logger(Filterer): ...@@ -861,19 +887,21 @@ class Logger(Filterer):
if INFO >= self.getEffectiveLevel(): if INFO >= self.getEffectiveLevel():
apply(self._log, (INFO, msg, args), kwargs) 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 To pass exception information, use the keyword argument exc_info with
a true value, e.g. 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 return
if self.isEnabledFor(WARN): if self.isEnabledFor(WARNING):
apply(self._log, (WARN, msg, args), kwargs) apply(self._log, (WARNING, msg, args), kwargs)
warn = warning
def error(self, msg, *args, **kwargs): def error(self, msg, *args, **kwargs):
""" """
...@@ -982,7 +1010,7 @@ class Logger(Filterer): ...@@ -982,7 +1010,7 @@ class Logger(Filterer):
Remove the specified handler from this logger. Remove the specified handler from this logger.
""" """
if hdlr in self.handlers: if hdlr in self.handlers:
hdlr.close() #hdlr.close()
self.handlers.remove(hdlr) self.handlers.remove(hdlr)
def callHandlers(self, record): def callHandlers(self, record):
...@@ -1047,7 +1075,7 @@ class RootLogger(Logger): ...@@ -1047,7 +1075,7 @@ class RootLogger(Logger):
_loggerClass = Logger _loggerClass = Logger
root = RootLogger(WARN) root = RootLogger(WARNING)
Logger.root = root Logger.root = root
Logger.manager = Manager(Logger.root) Logger.manager = Manager(Logger.root)
...@@ -1119,13 +1147,15 @@ def exception(msg, *args): ...@@ -1119,13 +1147,15 @@ def exception(msg, *args):
""" """
apply(error, (msg,)+args, {'exc_info': 1}) 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: if len(root.handlers) == 0:
basicConfig() basicConfig()
apply(root.warn, (msg,)+args, kwargs) apply(root.warning, (msg,)+args, kwargs)
warn = warning
def info(msg, *args, **kwargs): def info(msg, *args, **kwargs):
""" """
......
...@@ -100,7 +100,7 @@ class RotatingFileHandler(logging.FileHandler): ...@@ -100,7 +100,7 @@ class RotatingFileHandler(logging.FileHandler):
""" """
if self.maxBytes > 0: # are we rolling over? if self.maxBytes > 0: # are we rolling over?
msg = "%s\n" % self.format(record) 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: if self.stream.tell() + len(msg) >= self.maxBytes:
self.doRollover() self.doRollover()
logging.FileHandler.emit(self, record) logging.FileHandler.emit(self, record)
...@@ -145,8 +145,8 @@ class SocketHandler(logging.Handler): ...@@ -145,8 +145,8 @@ class SocketHandler(logging.Handler):
This function allows for partial sends which can happen when the This function allows for partial sends which can happen when the
network is busy. network is busy.
""" """
v = sys.version_info v = logging._verinfo
if v[0] >= 2 and v[1] >= 2: if v and (v[0] >= 2) and (v[1] >= 2):
self.sock.sendall(s) self.sock.sendall(s)
else: else:
sentsofar = 0 sentsofar = 0
...@@ -167,7 +167,7 @@ class SocketHandler(logging.Handler): ...@@ -167,7 +167,7 @@ class SocketHandler(logging.Handler):
slen = struct.pack(">L", len(s)) slen = struct.pack(">L", len(s))
return slen + s return slen + s
def handleError(self): def handleError(self, record):
""" """
Handle an error during logging. Handle an error during logging.
...@@ -179,7 +179,7 @@ class SocketHandler(logging.Handler): ...@@ -179,7 +179,7 @@ class SocketHandler(logging.Handler):
self.sock.close() self.sock.close()
self.sock = None #try to reconnect next time self.sock = None #try to reconnect next time
else: else:
logging.Handler.handleError(self) logging.Handler.handleError(self, record)
def emit(self, record): def emit(self, record):
""" """
...@@ -196,7 +196,7 @@ class SocketHandler(logging.Handler): ...@@ -196,7 +196,7 @@ class SocketHandler(logging.Handler):
self.sock = self.makeSocket() self.sock = self.makeSocket()
self.send(s) self.send(s)
except: except:
self.handleError() self.handleError(record)
def close(self): def close(self):
""" """
...@@ -355,7 +355,7 @@ class SysLogHandler(logging.Handler): ...@@ -355,7 +355,7 @@ class SysLogHandler(logging.Handler):
except socket.error: except socket.error:
self.socket.close() self.socket.close()
self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.socket.connect(address) self.socket.connect(address)
self.unixsocket = 1 self.unixsocket = 1
else: else:
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
...@@ -411,7 +411,7 @@ class SysLogHandler(logging.Handler): ...@@ -411,7 +411,7 @@ class SysLogHandler(logging.Handler):
else: else:
self.socket.sendto(msg, self.address) self.socket.sendto(msg, self.address)
except: except:
self.handleError() self.handleError(record)
class SMTPHandler(logging.Handler): class SMTPHandler(logging.Handler):
""" """
...@@ -434,6 +434,8 @@ class SMTPHandler(logging.Handler): ...@@ -434,6 +434,8 @@ class SMTPHandler(logging.Handler):
self.mailhost = mailhost self.mailhost = mailhost
self.mailport = None self.mailport = None
self.fromaddr = fromaddr self.fromaddr = fromaddr
if type(toaddrs) == types.StringType:
toaddrs = [toaddrs]
self.toaddrs = toaddrs self.toaddrs = toaddrs
self.subject = subject self.subject = subject
...@@ -467,7 +469,7 @@ class SMTPHandler(logging.Handler): ...@@ -467,7 +469,7 @@ class SMTPHandler(logging.Handler):
smtp.sendmail(self.fromaddr, self.toaddrs, msg) smtp.sendmail(self.fromaddr, self.toaddrs, msg)
smtp.quit() smtp.quit()
except: except:
self.handleError() self.handleError(record)
class NTEventLogHandler(logging.Handler): class NTEventLogHandler(logging.Handler):
""" """
...@@ -496,7 +498,7 @@ class NTEventLogHandler(logging.Handler): ...@@ -496,7 +498,7 @@ class NTEventLogHandler(logging.Handler):
self.typemap = { self.typemap = {
logging.DEBUG : win32evtlog.EVENTLOG_INFORMATION_TYPE, logging.DEBUG : win32evtlog.EVENTLOG_INFORMATION_TYPE,
logging.INFO : 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.ERROR : win32evtlog.EVENTLOG_ERROR_TYPE,
logging.CRITICAL: win32evtlog.EVENTLOG_ERROR_TYPE, logging.CRITICAL: win32evtlog.EVENTLOG_ERROR_TYPE,
} }
...@@ -531,7 +533,7 @@ class NTEventLogHandler(logging.Handler): ...@@ -531,7 +533,7 @@ class NTEventLogHandler(logging.Handler):
Override this if you want to specify your own types. This version does 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 a mapping using the handler's typemap attribute, which is set up in
__init__() to a dictionary which contains mappings for DEBUG, INFO, __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 either need to override this method or place a suitable dictionary in
the handler's typemap attribute. the handler's typemap attribute.
""" """
...@@ -552,7 +554,7 @@ class NTEventLogHandler(logging.Handler): ...@@ -552,7 +554,7 @@ class NTEventLogHandler(logging.Handler):
msg = self.format(record) msg = self.format(record)
self._welu.ReportEvent(self.appname, id, cat, type, [msg]) self._welu.ReportEvent(self.appname, id, cat, type, [msg])
except: except:
self.handleError() self.handleError(record)
def close(self): def close(self):
""" """
...@@ -610,7 +612,7 @@ class HTTPHandler(logging.Handler): ...@@ -610,7 +612,7 @@ class HTTPHandler(logging.Handler):
h.send(data) h.send(data)
h.getreply() #can't do anything with the result h.getreply() #can't do anything with the result
except: except:
self.handleError() self.handleError(record)
class BufferingHandler(logging.Handler): class BufferingHandler(logging.Handler):
""" """
......
...@@ -4,11 +4,11 @@ CRITICAL:ERR:Message 0 ...@@ -4,11 +4,11 @@ CRITICAL:ERR:Message 0
ERROR:ERR:Message 1 ERROR:ERR:Message 1
CRITICAL:INF:Message 2 CRITICAL:INF:Message 2
ERROR:INF:Message 3 ERROR:INF:Message 3
WARN:INF:Message 4 WARNING:INF:Message 4
INFO:INF:Message 5 INFO:INF:Message 5
CRITICAL:INF.UNDEF:Message 6 CRITICAL:INF.UNDEF:Message 6
ERROR:INF.UNDEF:Message 7 ERROR:INF.UNDEF:Message 7
WARN:INF.UNDEF:Message 8 WARNING:INF.UNDEF:Message 8
INFO:INF.UNDEF:Message 9 INFO:INF.UNDEF:Message 9
CRITICAL:INF.ERR:Message 10 CRITICAL:INF.ERR:Message 10
ERROR:INF.ERR:Message 11 ERROR:INF.ERR:Message 11
...@@ -16,12 +16,12 @@ CRITICAL:INF.ERR.UNDEF:Message 12 ...@@ -16,12 +16,12 @@ CRITICAL:INF.ERR.UNDEF:Message 12
ERROR:INF.ERR.UNDEF:Message 13 ERROR:INF.ERR.UNDEF:Message 13
CRITICAL:DEB:Message 14 CRITICAL:DEB:Message 14
ERROR:DEB:Message 15 ERROR:DEB:Message 15
WARN:DEB:Message 16 WARNING:DEB:Message 16
INFO:DEB:Message 17 INFO:DEB:Message 17
DEBUG:DEB:Message 18 DEBUG:DEB:Message 18
CRITICAL:UNDEF:Message 19 CRITICAL:UNDEF:Message 19
ERROR:UNDEF:Message 20 ERROR:UNDEF:Message 20
WARN:UNDEF:Message 21 WARNING:UNDEF:Message 21
INFO:UNDEF:Message 22 INFO:UNDEF:Message 22
CRITICAL:INF.BADPARENT.UNDEF:Message 23 CRITICAL:INF.BADPARENT.UNDEF:Message 23
CRITICAL:INF.BADPARENT:Message 24 CRITICAL:INF.BADPARENT:Message 24
...@@ -259,10 +259,10 @@ Silent:root:This should only be seen at the 'Silent' logging level (or lower) ...@@ -259,10 +259,10 @@ Silent:root:This should only be seen at the 'Silent' logging level (or lower)
-- log_test2 begin --------------------------------------------------- -- log_test2 begin ---------------------------------------------------
-- logging at DEBUG, nothing should be seen yet -- -- logging at DEBUG, nothing should be seen yet --
-- logging at INFO, nothing should be seen yet -- -- logging at INFO, nothing should be seen yet --
-- logging at WARN, 3 messages should be seen -- -- logging at WARNING, 3 messages should be seen --
DEBUG:root:Debug message DEBUG:root:Debug message
INFO:root:Info message INFO:root:Info message
WARN:root:Warn message WARNING:root:Warn message
-- logging 0 at INFO, messages should be seen every 10 events -- -- logging 0 at INFO, messages should be seen every 10 events --
-- logging 1 at INFO, messages should be seen every 10 events -- -- logging 1 at INFO, messages should be seen every 10 events --
-- logging 2 at INFO, messages should be seen every 10 events -- -- logging 2 at INFO, messages should be seen every 10 events --
...@@ -490,11 +490,11 @@ ERR -> CRITICAL: Message 0 (via logrecv.tcp.ERR) ...@@ -490,11 +490,11 @@ ERR -> CRITICAL: Message 0 (via logrecv.tcp.ERR)
ERR -> ERROR: Message 1 (via logrecv.tcp.ERR) ERR -> ERROR: Message 1 (via logrecv.tcp.ERR)
INF -> CRITICAL: Message 2 (via logrecv.tcp.INF) INF -> CRITICAL: Message 2 (via logrecv.tcp.INF)
INF -> ERROR: Message 3 (via logrecv.tcp.INF) INF -> ERROR: Message 3 (via logrecv.tcp.INF)
INF -> WARN: Message 4 (via logrecv.tcp.INF) INF -> WARNING: Message 4 (via logrecv.tcp.INF)
INF -> INFO: Message 5 (via logrecv.tcp.INF) INF -> INFO: Message 5 (via logrecv.tcp.INF)
INF.UNDEF -> CRITICAL: Message 6 (via logrecv.tcp.INF.UNDEF) INF.UNDEF -> CRITICAL: Message 6 (via logrecv.tcp.INF.UNDEF)
INF.UNDEF -> ERROR: Message 7 (via logrecv.tcp.INF.UNDEF) INF.UNDEF -> ERROR: Message 7 (via logrecv.tcp.INF.UNDEF)
INF.UNDEF -> WARN: Message 8 (via logrecv.tcp.INF.UNDEF) INF.UNDEF -> WARNING: Message 8 (via logrecv.tcp.INF.UNDEF)
INF.UNDEF -> INFO: Message 9 (via logrecv.tcp.INF.UNDEF) INF.UNDEF -> INFO: Message 9 (via logrecv.tcp.INF.UNDEF)
INF.ERR -> CRITICAL: Message 10 (via logrecv.tcp.INF.ERR) INF.ERR -> CRITICAL: Message 10 (via logrecv.tcp.INF.ERR)
INF.ERR -> ERROR: Message 11 (via logrecv.tcp.INF.ERR) INF.ERR -> ERROR: Message 11 (via logrecv.tcp.INF.ERR)
...@@ -502,12 +502,12 @@ INF.ERR.UNDEF -> CRITICAL: Message 12 (via logrecv.tcp.INF.ERR.UNDEF) ...@@ -502,12 +502,12 @@ INF.ERR.UNDEF -> CRITICAL: Message 12 (via logrecv.tcp.INF.ERR.UNDEF)
INF.ERR.UNDEF -> ERROR: Message 13 (via logrecv.tcp.INF.ERR.UNDEF) INF.ERR.UNDEF -> ERROR: Message 13 (via logrecv.tcp.INF.ERR.UNDEF)
DEB -> CRITICAL: Message 14 (via logrecv.tcp.DEB) DEB -> CRITICAL: Message 14 (via logrecv.tcp.DEB)
DEB -> ERROR: Message 15 (via logrecv.tcp.DEB) DEB -> ERROR: Message 15 (via logrecv.tcp.DEB)
DEB -> WARN: Message 16 (via logrecv.tcp.DEB) DEB -> WARNING: Message 16 (via logrecv.tcp.DEB)
DEB -> INFO: Message 17 (via logrecv.tcp.DEB) DEB -> INFO: Message 17 (via logrecv.tcp.DEB)
DEB -> DEBUG: Message 18 (via logrecv.tcp.DEB) DEB -> DEBUG: Message 18 (via logrecv.tcp.DEB)
UNDEF -> CRITICAL: Message 19 (via logrecv.tcp.UNDEF) UNDEF -> CRITICAL: Message 19 (via logrecv.tcp.UNDEF)
UNDEF -> ERROR: Message 20 (via logrecv.tcp.UNDEF) UNDEF -> ERROR: Message 20 (via logrecv.tcp.UNDEF)
UNDEF -> WARN: Message 21 (via logrecv.tcp.UNDEF) UNDEF -> WARNING: Message 21 (via logrecv.tcp.UNDEF)
UNDEF -> INFO: Message 22 (via logrecv.tcp.UNDEF) UNDEF -> INFO: Message 22 (via logrecv.tcp.UNDEF)
INF.BADPARENT.UNDEF -> CRITICAL: Message 23 (via logrecv.tcp.INF.BADPARENT.UNDEF) INF.BADPARENT.UNDEF -> CRITICAL: Message 23 (via logrecv.tcp.INF.BADPARENT.UNDEF)
INF.BADPARENT -> CRITICAL: Message 24 (via logrecv.tcp.INF.BADPARENT) INF.BADPARENT -> CRITICAL: Message 24 (via logrecv.tcp.INF.BADPARENT)
......
...@@ -342,15 +342,16 @@ MSG = "-- logging %d at INFO, messages should be seen every 10 events --" ...@@ -342,15 +342,16 @@ MSG = "-- logging %d at INFO, messages should be seen every 10 events --"
def test2(): def test2():
logger = logging.getLogger("") logger = logging.getLogger("")
sh = logger.handlers[0] sh = logger.handlers[0]
sh.close()
logger.removeHandler(sh) logger.removeHandler(sh)
mh = logging.handlers.MemoryHandler(10,logging.WARN, sh) mh = logging.handlers.MemoryHandler(10,logging.WARNING, sh)
logger.setLevel(logging.DEBUG) logger.setLevel(logging.DEBUG)
logger.addHandler(mh) logger.addHandler(mh)
message("-- logging at DEBUG, nothing should be seen yet --") message("-- logging at DEBUG, nothing should be seen yet --")
logger.debug("Debug message") logger.debug("Debug message")
message("-- logging at INFO, nothing should be seen yet --") message("-- logging at INFO, nothing should be seen yet --")
logger.info("Info message") logger.info("Info message")
message("-- logging at WARN, 3 messages should be seen --") message("-- logging at WARNING, 3 messages should be seen --")
logger.warn("Warn message") logger.warn("Warn message")
for i in xrange(102): for i in xrange(102):
message(MSG % i) message(MSG % i)
...@@ -436,6 +437,7 @@ def test_main(): ...@@ -436,6 +437,7 @@ def test_main():
rootLogger.addHandler(hdlr) rootLogger.addHandler(hdlr)
test0() test0()
hdlr.close()
rootLogger.removeHandler(hdlr) rootLogger.removeHandler(hdlr)
banner("log_test0", "end") banner("log_test0", "end")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment