diff --git a/Doc/lib/liblogging.tex b/Doc/lib/liblogging.tex index dd65f3b6c8b..f450c078ba3 100644 --- a/Doc/lib/liblogging.tex +++ b/Doc/lib/liblogging.tex @@ -52,7 +52,7 @@ use of \dfn{handlers}, which are instances of subclasses of the \class{Handler} class. Handlers are responsible for ensuring that a logged message (in the form of a \class{LogRecord}) ends up in a particular location (or set of locations) which is useful for the target audience for -that message (e.g. end users, support desk staff, system administrators, +that message (such as end users, support desk staff, system administrators, developers). Handlers are passed \class{LogRecord} instances intended for particular destinations. Each logger can have zero, one or more handlers associated with it (via the \method{addHandler} method of \class{Logger}). @@ -204,6 +204,13 @@ with \var{lvl} is returned. Otherwise, the string "Level \%s" \% lvl is returned. \end{funcdesc} +\begin{funcdesc}{makeLogRecord}{attrdict} +Creates and returns a new \class{LogRecord} instance whose attributes are +defined by \var{attrdict}. This function is useful for taking a pickled +\class{LogRecord} attribute dictionary, sent over a socket, and reconstituting +it as a \class{LogRecord} instance at the receiving end. +\end{funcdesc} + \begin{funcdesc}{basicConfig}{} Does basic configuration for the logging system by creating a \class{StreamHandler} with a default \class{Formatter} and adding it to @@ -266,7 +273,7 @@ determined by \method{getEffectiveLevel()}. Indicates the effective level for this logger. If a value other than \constant{NOTSET} has been set using \method{setLevel()}, it is returned. Otherwise, the hierarchy is traversed towards the root until a value -other than \constant{NOTSET} is found,and that value is returned. +other than \constant{NOTSET} is found, and that value is returned. \end{methoddesc} \begin{methoddesc}{debug}{msg\optional{, *args\optional{, **kwargs}}} @@ -535,9 +542,11 @@ Closes the socket. \end{methoddesc} \begin{methoddesc}{emit}{} -Pickles the record and writes it to the socket in binary format. -If there is an error with the socket, silently drops the packet. -If the connection was previously lost, re-establishes the connection. +Pickles the record's attribute dictionary and writes it to the socket in +binary format. If there is an error with the socket, silently drops the +packet. If the connection was previously lost, re-establishes the connection. +To unpickle the record at the receiving end into a LogRecord, use the +\function{makeLogRecord} function. \end{methoddesc} \begin{methoddesc}{handleError}{} @@ -553,8 +562,8 @@ socket (\constant{socket.SOCK_STREAM}). \end{methoddesc} \begin{methoddesc}{makePickle}{record} -Pickles the record in binary format with a length prefix, and returns -it ready for transmission across the socket. +Pickles the record's attribute dictionary in binary format with a length +prefix, and returns it ready for transmission across the socket. \end{methoddesc} \begin{methoddesc}{send}{packet} @@ -574,8 +583,11 @@ and \var{port}. \end{classdesc} \begin{methoddesc}{emit}{} -Pickles the record and writes it to the socket in binary format. -If there is an error with the socket, silently drops the packet. +Pickles the record's attribute dictionary and writes it to the socket in +binary format. If there is an error with the socket, silently drops the +packet. +To unpickle the record at the receiving end into a LogRecord, use the +\function{makeLogRecord} function. \end{methoddesc} \begin{methoddesc}{makeSocket}{} @@ -584,8 +596,7 @@ a UDP socket (\constant{socket.SOCK_DGRAM}). \end{methoddesc} \begin{methoddesc}{send}{s} -Send a pickled string to a socket. This function allows for -partial sends which can happen when the network is busy. +Send a pickled string to a socket. \end{methoddesc} \subsubsection{SysLogHandler} @@ -789,8 +800,8 @@ base supplied, the default value of "\%s(message)\\n" is used. A Formatter can be initialized with a format string which makes use of -knowledge of the \class{LogRecord} attributes - e.g. the default value -mentioned above makes use of the fact that the user's message and +knowledge of the \class{LogRecord} attributes - such as the default value +mentioned above making use of the fact that the user's message and arguments are pre- formatted into a LogRecord's \var{message} attribute. Currently, the useful attributes in a LogRecord are described by: @@ -916,7 +927,11 @@ I/O. \subsubsection{Configuration functions} -The following functions allow the logging module to be configured. +The following functions allow the logging module to be configured. Before +they can be used, you must import \module{logging.config}. Their use is optional - +you can configure the logging module entirely by making calls to the main +API (defined in \module{logging} itself) and defining handlers which are declared +either in \module{logging} or \module{logging.handlers}. \begin{funcdesc}{fileConfig}{fname\optional{, defaults}} Reads the logging configuration from a ConfigParser-format file named @@ -1013,7 +1028,7 @@ entry is set to 1 to indicate that messages must propagate to handlers higher up the logger hierarchy from this logger, or 0 to indicate that messages are \strong{not} propagated to handlers up the hierarchy. The \code{qualname} entry is the hierarchical channel name of the logger, -i.e. the name used by the application to get the logger. +for example, the name used by the application to get the logger. Sections which specify handler configuration are exemplified by the following. diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index 9d6aa92ec61..3bd0c6d7e63 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -36,8 +36,8 @@ except ImportError: __author__ = "Vinay Sajip " __status__ = "beta" -__version__ = "0.4.8" -__date__ = "22 April 2003" +__version__ = "0.4.8.1" +__date__ = "26 June 2003" #--------------------------------------------------------------------------- # Miscellaneous module data @@ -233,6 +233,17 @@ class LogRecord: msg = msg % self.args return msg +def makeLogRecord(dict): + """ + Make a LogRecord whose attributes are defined by the specified dictionary, + This function is useful for converting a logging event received over + a socket connection (which is sent as a dictionary) into a LogRecord + instance. + """ + rv = LogRecord(None, None, "", 0, "", (), None) + rv.__dict__.update(dict) + return rv + #--------------------------------------------------------------------------- # Formatter classes and functions #--------------------------------------------------------------------------- diff --git a/Lib/logging/handlers.py b/Lib/logging/handlers.py index 4a597a1627f..7ed11353399 100644 --- a/Lib/logging/handlers.py +++ b/Lib/logging/handlers.py @@ -111,8 +111,12 @@ class SocketHandler(logging.Handler): A handler class which writes logging records, in pickle format, to a streaming socket. The socket is kept open across logging calls. If the peer resets it, an attempt is made to reconnect on the next call. - Note that the very simple wire protocol used means that packet sizes - are expected to be encodable within 16 bits (i.e. < 32767 bytes). + The pickle which is sent is that of the LogRecord's attribute dictionary + (__dict__), so that the receiver does not need to have the logging module + installed in order to process the logging event. + + To unpickle the record at the receiving end into a LogRecord, use the + makeLogRecord function. """ def __init__(self, host, port): @@ -208,9 +212,12 @@ class SocketHandler(logging.Handler): class DatagramHandler(SocketHandler): """ A handler class which writes logging records, in pickle format, to - a datagram socket. Note that the very simple wire protocol used means - that packet sizes are expected to be encodable within 16 bits - (i.e. < 32767 bytes). + a datagram socket. The pickle which is sent is that of the LogRecord's + attribute dictionary (__dict__), so that the receiver does not need to + have the logging module installed in order to process the logging event. + + To unpickle the record at the receiving end into a LogRecord, use the + makeLogRecord function. """ def __init__(self, host, port): @@ -236,14 +243,6 @@ class DatagramHandler(SocketHandler): when the network is busy - UDP does not guarantee delivery and can deliver packets out of sequence. """ - #old code - #sentsofar = 0 - #left = len(s) - #addr = (self.host, self.port) - #while left > 0: - # sent = self.sock.sendto(s[sentsofar:], addr) - # sentsofar = sentsofar + sent - # left = left - sent self.sock.sendto(s, (self.host, self.port)) class SysLogHandler(logging.Handler): diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 60995620bbd..ecf0e68e6de 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -70,8 +70,7 @@ class LogRecordStreamHandler(StreamRequestHandler): while len(chunk) < slen: chunk = chunk + self.connection.recv(slen - len(chunk)) obj = self.unPickle(chunk) - record = logging.LogRecord(None, None, "", 0, "", (), None) - record.__dict__.update(obj) + record = logging.makeLogRecord(obj) self.handleLogRecord(record) except: raise diff --git a/Misc/NEWS b/Misc/NEWS index c562583b4a8..ab04a407279 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -83,6 +83,9 @@ Extension modules Library ------- +- The logging module now has a new function, makeLogRecord() making + LogHandler easier to interact with DatagramHandler and SocketHandler. + - For compatibility with doctests created before 2.3, if an expected output block consists solely of "1" and the actual output block consists solely of "True", it's accepted as a match; similarly