pythonlogginghandlerdatagram

Python logging datagram handler


I am having a problem getting the example code shown in the python docs for the logging DatagramHandler, the code shown below gives EOFError exceptions on every datagram received.

import socket
import logging
import cPickle
import struct
import sys

sock = socket.socket (socket.AF_INET, socket.SOCK_DGRAM)
sock.bind (('localhost', 9000))

handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter("UDP LogViewer %(asctime)s %(message)s"))
logger = logging.getLogger("Test")
logger.addHandler(handler)

try:
    while True:
        dgram_size = sock.recv(4)
        if len(dgram_size) < 4:
            break
        slen = struct.unpack(">L", dgram_size)[0]
        data = sock.recv(slen)

        while len(data) < slen:
            data = data + sock.recv(slen - len(data))

        try:
            obj = cPickle.loads(data)
            record = logging.makeLogRecord(obj)
            logger.handle(record)
        except:
            print "exception", sys.exc_info()[0]



finally:
    sock.close()

However this code works, any ideas

data, address = sock.recvfrom(8192)
rec = logging.makeLogRecord(cPickle.loads(data[4:]))
logger.handle(rec)

Regards


Solution

  • I expect your first recv(4) call copies the first four bytes out of your datagram and then throws the rest of the packet on the floor; your second call to recv then finds nothing to read and returns EOFError. From my system's udp(7) manpage:

       All receive operations return only one packet.  When the packet
       is smaller than the passed buffer, only that much data is
       returned; when it is bigger, the packet is truncated and the
       MSG_TRUNC flag is set.  MSG_WAITALL is not supported.
    

    Try reading in the entire datagram, grabbing the length out of the first four bytes, and then working on the subset of the array that stores the entire datagram.

    Of course, if your pickles don't fit entirely within the MTU of the connection, it'll probably never work as you intend.