4

我正在尝试过滤来自 UDP 的 Python 日志消息,但由于某种原因,在接收端设置 loglevel 似乎不会影响传入的消息。

接收端代码如下:

import cPickle
import logging
import socket

logging.basicConfig(format='%(asctime)s %(levelname)-8s %(message)s')
logger = logging.getLogger()
logger.setLevel(logging.INFO)

s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('', 51010))

while True:
    d, _ = s.recvfrom(1024)
    log = cPickle.loads(d[4:])
    logger.handle(logging.makeLogRecord(log))

尽管我已将日志记录级别设置为 logging.INFO,但我仍然看到调试消息。如果我添加

logging.debug("Debug")
logging.info("Info")

在 while 循环之前,我看到了信息消息,但没有看到调试消息,表明 setLevel 正在本地工作,但不影响通过 UDP 套接字传递的消息。

任何想法为什么会发生这种情况?如果我手动检查接收到的dict的'levelno'字段(然后变成日志记录),它是10(调试),但过滤似乎并不关心......

谢谢!

编辑:

作为参考,生成通过 UDP 发送的数据包的代码很简单

import logging
import logging.handlers
import time

logging.basicConfig(level=logging.DEBUG,
    format='%(asctime)s %(levelname)-8s %(message)s')

logging.getLogger().addHandler(logging.handlers.DatagramHandler('', 51010))

while True:
    logging.debug("This shouldn't show up")
    logging.info("This should show up")
    time.sleep(3)
4

1 回答 1

3

Logger.handle() is a method that is meant to be called after level checking, which is why the level set on the logger is ineffective. It's generally better to do level setting at the source end (to avoid wasting network bandwidth), or else you can set a level on the handler at the receiving end (not possible using basicConfig(), which is meant for the simplest usages - and your's isn't, IMO). So you can do (on the receiving end):

handler = logging.StreamHandler()
handler.setLevel(logging.INFO)
# setting a Formatter to customise the logs is not shown, but
# you can add it here
logging.getLogger().addHandler(handler)

The above is instead of the basicConfig() call.

于 2013-10-31T21:06:27.487 回答