我正在尝试实现使用Python的标准logging
库将事件记录到远程服务器的简单日志处理程序。所以我创建了一个继承自logging.Handler
的自定义类,名为RemoteLogHandler
,接受LogRecord
并将其发送到远程服务器。处理程序以标准addHandler()
方式附加到根记录器。
from urllib import requests
class RemoteLogHandler(logging.Handler):
def emit(self, record):
remote_url = "http://foo.bar.baz"
req = request.Request(remote_url, data=record.msg)
request.urlopen(req, timeout=1)
这可以按预期工作,但是当remote_url变得不可访问或开始缓慢响应时,显然会导致调用线程的锁定。所以我试图想出最好的方法让这个调用独立于调用线程。
我考虑过的事情:
所有这些解决方案似乎过于复杂/不必要,无法实现这样简单的任务。是否有一些更好的方法,更少的开销,以使这个处理程序不阻塞?
答案 0 :(得分:1)
对于任何会遇到此问题的人来说,解决方案结果很简单,如here所述。
import queue
from logging import QueueHandler, QueueListener
# instantiate queue & attach it to handler
log_queue = queue.Queue(-1)
queue_handler = QueueHandler(log_queue)
# instantiate our custom log handler (see question)
remote_handler = RemoteLogHandler()
# instantiate listener
remote_listener = QueueListener(log_queue, remote_handler)
# attach custom handler to root logger
logging.getLogger().addHandler(queue_handler)
# start the listener
remote_listener.start()
QueueListener在自己的线程中运行,并侦听QueueHandlers发送的LogRecords,这会导致非阻塞日志记录。