Python日志记录即使在使用QueueHandler QueueListener时也会减慢代码的速度
我使用注释中显示的链接中的示例进行了以下日志设置 我正在使用Python 3.8.5 我正在记录一些具有毫秒分辨率时间戳的数据。我发现,如果启用控制台日志记录(Python日志记录即使在使用QueueHandler QueueListener时也会减慢代码的速度,python,python-logging,Python,Python Logging,我使用注释中显示的链接中的示例进行了以下日志设置 我正在使用Python 3.8.5 我正在记录一些具有毫秒分辨率时间戳的数据。我发现,如果启用控制台日志记录(LOG.addHandler(c\u queue\u handler)),我的代码时间戳会显示几毫秒的延迟(我使用Wireshark比较流量)。没有控制台StreamHandler,它与Wireshark计时非常一致 我所尝试的: 控制台和文件处理程序的独立侦听器,我认为这有点帮助 在控制台输出中使用如下所示的内存处理器,它显示几乎与根
LOG.addHandler(c\u queue\u handler)
),我的代码时间戳会显示几毫秒的延迟(我使用Wireshark比较流量)。没有控制台StreamHandler,它与Wireshark计时非常一致
我所尝试的:
- 控制台和文件处理程序的独立侦听器,我认为这有点帮助
- 在控制台输出中使用如下所示的
,它显示几乎与根本没有控制台处理器一样好,但不太好。有时,在某些日志上会出现几毫秒的错误,当它到达内存处理器
并刷新到控制台时,可能会出现几毫秒的错误容量
QueueListener
正在一个新线程中运行日志处理,那么这为什么会导致延迟呢?这是否只是记录器必须处理多个处理程序(而不是实际输出到控制台)的情况,因此,我无法进一步改进这一点
另外,如果我在内存句柄
中将容量
设置为一个较高的数字,当它试图将更多数据刷新到控制台时,会看到更大的延迟吗
import logging
import logging.handlers
import asyncio
try:
# Python 3.7 and newer, fast reentrant implementation
# without task tracking (not needed for that when logging)
from queue import SimpleQueue as Queue
except ImportError:
from queue import Queue
from typing import List
LOG = logging.getLogger('canlog')
# https://stackoverflow.com/questions/24791395/python-logging-causing-latencies
# https://www.zopatista.com/python/2019/05/11/asyncio-logging/
class LocalQueueHandler(logging.handlers.QueueHandler):
def emit(self, record: logging.LogRecord) -> None:
# Removed the call to self.prepare(), handle task cancellation
try:
self.enqueue(record)
except asyncio.CancelledError:
raise
except Exception:
self.handleError(record)
def loggingSetup():
c_que = Queue()
c_queue_handler = LocalQueueHandler(c_que)
c_hdl = logging.StreamHandler()
listener = logging.handlers.QueueListener(c_que, c_hdl)
formatter = logging.Formatter('[%(asctime)s %(filename)s:%(lineno)s - %(funcName)s]: %(message)s')
LOG.setLevel(logging.DEBUG)
f_que = Queue()
f_queue_handler = LocalQueueHandler(f_que)
f_hdl = logging.FileHandler('udsconn_log.log')
listener2 = logging.handlers.QueueListener(f_que, f_hdl)
memoryhandler = logging.handlers.MemoryHandler(
capacity=100, # Deliberately kept small to see affect of flushing
flushLevel=logging.ERROR,
target=c_hdl
)
c_queue_handler.setLevel(logging.INFO)
f_queue_handler.setLevel(logging.DEBUG)
c_hdl.setFormatter(formatter)
f_hdl.setFormatter(formatter)
LOG.addHandler(c_queue_handler) # Using this causes some delays
LOG.addHandler(f_queue_handler)
LOG.addHandler(memoryhandler)
listener.start()
listener2.start()