Python 日志记录数据报处理程序
我在获取 python 文档中显示的用于记录 DatagramHandler 的示例代码时遇到问题,下面显示的代码在收到的每个数据报上都会给出 EOFError 异常。
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()
然而这段代码可以工作,任何想法
data, address = sock.recvfrom(8192)
rec = logging.makeLogRecord(cPickle.loads(data[4:]))
logger.handle(rec)
问候
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我希望您的第一个
recv(4)
调用会复制数据报中的前四个字节,然后将数据包的其余部分扔到地板上;第二次调用recv
然后发现没有任何内容可读取并返回 EOFError。从我的系统的udp(7)
联机帮助页中:尝试读入整个数据报,获取前四个字节的长度,然后处理存储整个数据报的数组子集。
当然,如果你的pickles不完全适合连接的MTU,它会可能永远不会按您的预期工作。
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 torecv
then finds nothing to read and returns EOFError. From my system'sudp(7)
manpage: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.
完整的 MWA 看起来像这样。
请注意,我们只是丢弃前四个字节(pickle-data 的大小),这些字节的存在是因为 DatagramHandler 继承了在 TCP 模式下运行的 SocketHandler。由于我们使用的是 UDP,因此我们只能读取数据包的末尾。正如 Sarnold 指出的那样,如果数据无法装入数据包,我们需要更好的解决方案,并且由于 UDP 可能会丢失数据包,因此需要服务器端自定义。也许最简单的服务器端解决方案就是分割任何消息,这样我们一开始就不会超出限制!
改编自 https://docs.python 中的 TCP 示例。 org/3/howto/logging-cookbook.html#logging-cookbook。
A complete MWA looks something like this.
Notice we just discard the first four bytes (the size of the pickle-data), these exist because
DatagramHandler
inheritsSocketHandler
, which operates in TCP mode. Since we're on UDP we can just read to the end of the packet however. As Sarnold points out, if the data doesn't fit into a packet, we'd need a better solution and, since UDP can miss packets, that would require server side customisations. Perhaps the simplest server-side solution would just to be to split up any messages so we don't go over the limit in the first place!Adapted from the TCP example at https://docs.python.org/3/howto/logging-cookbook.html#logging-cookbook.