Movatterモバイル変換


[0]ホーム

URL:


Up one LevelPython Library ReferenceContentsModule IndexIndex


14.5.4 Sending and receiving logging events across a network

Let's say you want to send logging events across a network, and handle themat the receiving end. A simple way of doing this is attaching aSocketHandler instance to the root logger at the sending end:

import logging, logging.handlersrootLogger = logging.getLogger('')rootLogger.setLevel(logging.DEBUG)socketHandler = logging.handlers.SocketHandler('localhost',                    logging.handlers.DEFAULT_TCP_LOGGING_PORT)# don't bother with a formatter, since a socket handler sends the event as# an unformatted picklerootLogger.addHandler(socketHandler)# Now, we can log to the root logger, or any other logger. First the root...logging.info('Jackdaws love my big sphinx of quartz.')# Now, define a couple of other loggers which might represent areas in your# application:logger1 = logging.getLogger('myapp.area1')logger2 = logging.getLogger('myapp.area2')logger1.debug('Quick zephyrs blow, vexing daft Jim.')logger1.info('How quickly daft jumping zebras vex.')logger2.warning('Jail zesty vixen who grabbed pay from quack.')logger2.error('The five boxing wizards jump quickly.')

At the receiving end, you can set up a receiver using theSocketServer module. Here is a basic working example:

import cPickleimport loggingimport logging.handlersimport SocketServerimport structclass LogRecordStreamHandler(SocketServer.StreamRequestHandler):    """Handler for a streaming logging request.    This basically logs the record using whatever logging policy is    configured locally.    """    def handle(self):        """        Handle multiple requests - each expected to be a 4-byte length,        followed by the LogRecord in pickle format. Logs the record        according to whatever policy is configured locally.        """        while 1:            chunk = self.connection.recv(4)            if len(chunk) < 4:                break            slen = struct.unpack(">L", chunk)[0]            chunk = self.connection.recv(slen)            while len(chunk) < slen:                chunk = chunk + self.connection.recv(slen - len(chunk))            obj = self.unPickle(chunk)            record = logging.makeLogRecord(obj)            self.handleLogRecord(record)    def unPickle(self, data):        return cPickle.loads(data)    def handleLogRecord(self, record):        # if a name is specified, we use the named logger rather than the one        # implied by the record.        if self.server.logname is not None:            name = self.server.logname        else:            name = record.name        logger = logging.getLogger(name)        # N.B. EVERY record gets logged. This is because Logger.handle        # is normally called AFTER logger-level filtering. If you want        # to do filtering, do it at the client end to save wasting        # cycles and network bandwidth!        logger.handle(record)class LogRecordSocketReceiver(SocketServer.ThreadingTCPServer):    """simple TCP socket-based logging receiver suitable for testing.    """    allow_reuse_address = 1    def __init__(self, host='localhost',                 port=logging.handlers.DEFAULT_TCP_LOGGING_PORT,                 handler=LogRecordStreamHandler):        SocketServer.ThreadingTCPServer.__init__(self, (host, port), handler)        self.abort = 0        self.timeout = 1        self.logname = None    def serve_until_stopped(self):        import select        abort = 0        while not abort:            rd, wr, ex = select.select([self.socket.fileno()],                                       [], [],                                       self.timeout)            if rd:                self.handle_request()            abort = self.abortdef main():    logging.basicConfig(        format="%(relativeCreated)5d %(name)-15s %(levelname)-8s %(message)s")    tcpserver = LogRecordSocketReceiver()    print "About to start TCP server..."    tcpserver.serve_until_stopped()if __name__ == "__main__":    main()

First run the server, and then the client. On the client side, nothing isprinted on the console; on the server side, you should see something like:

About to start TCP server...   59 root            INFO     Jackdaws love my big sphinx of quartz.   59 myapp.area1     DEBUG    Quick zephyrs blow, vexing daft Jim.   69 myapp.area1     INFO     How quickly daft jumping zebras vex.   69 myapp.area2     WARNING  Jail zesty vixen who grabbed pay from quack.   69 myapp.area2     ERROR    The five boxing wizards jump quickly.


Up one LevelPython Library ReferenceContentsModule IndexIndex

Release 2.5.2, documentation updated on 21st February, 2008.
SeeAbout this document... for information on suggesting changes.
[8]ページ先頭

©2009-2025 Movatter.jp