在我的Python 3代码中,我设置了一个类似这样的日志记录器:
当我运行我的程序(接收日志消息的服务器已经启动运行),队列会很快填满。每添加20-30条消息,只有2-3条消息从队列中移除(即发送)。 我的内存逐渐填满,使程序变得越来越慢,直到我的RAM基本上被填满为止,此时程序变得非常缓慢,并尝试一次性清空整个队列(即发送所有内容)。如果由于任何原因它无法快速清空所有内容,则会继续变慢,直到程序完成。如果它成功清空队列并发送大约几GB的LogRecords,那么它将再次加速并按照我期望的方式工作,这意味着从此时起,它将在将消息添加到队列时立即发送所有消息而不影响性能。
由于这可能不是预期的行为,我认为我做错了什么。
值得一提的是,我正在使用LogRecord的'extra' argument发送列表以及我的某些LogRecords。这些日志记录调用看起来像这样:
class TmpQListener(logging.handlers.QueueListener):
def dequeue(self, block):
print('QSIZE : ' + str(self.queue.qsize())) # only change to the QueueListener
return self.queue.get(block)
log_q = queue.Queue(-1) # unlimited size
logger = logging.getLogger('TestLogger')
socket_handler = logging.handlers.SocketHandler('localhost', 1337)
q_handler = logging.handlers.QueueHandler(log_q)
q_listener = TmpQListener(log_q, socket_handler)
logger.addHandler(q_handler)
q_listener.start()
当我运行我的程序(接收日志消息的服务器已经启动运行),队列会很快填满。每添加20-30条消息,只有2-3条消息从队列中移除(即发送)。 我的内存逐渐填满,使程序变得越来越慢,直到我的RAM基本上被填满为止,此时程序变得非常缓慢,并尝试一次性清空整个队列(即发送所有内容)。如果由于任何原因它无法快速清空所有内容,则会继续变慢,直到程序完成。如果它成功清空队列并发送大约几GB的LogRecords,那么它将再次加速并按照我期望的方式工作,这意味着从此时起,它将在将消息添加到队列时立即发送所有消息而不影响性能。
由于这可能不是预期的行为,我认为我做错了什么。
值得一提的是,我正在使用LogRecord的'extra' argument发送列表以及我的某些LogRecords。这些日志记录调用看起来像这样:
logger.info("PROX_MARKER", extra={'vector': [some_list]})
其中some_list是一个包含数千个双精度值的列表,使得LogRecord非常大。我知道这并不是logging调用的本意,但是我认为如果程序成功清除了初始的消息积压,那么这并不是问题。
我查看了SocketHandler/QueueHandler/QueueListener的代码,但没有找到任何可以解释这种行为的内容。在我的原始代码中,我使用自定义的SocketHandler序列化日志记录。我已将其替换为默认的SocketHandler,但结果仍然相同。现在我想不出其他的办法了。
非常感谢任何有关如何解决此问题的提示。