实现非阻塞远程日志处理程序

tvm*_*tvm 4 python logging asynchronous http

我正在尝试实现简单的日志处理程序,它使用 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)
Run Code Online (Sandbox Code Playgroud)

这按预期工作,但当 remote_url 变得不可访问或开始响应缓慢时,显然会导致调用线程锁定。所以我试图找出使这个调用独立于调用线程的最佳方法。

我考虑过的:

  1. 包括一些会使 http 请求异步的非标准库
  2. 使用此处概述的 QueueHandler 和 QueueListener
  3. 使用异步

所有这些解决方案对于实现如此简单的任务似乎都过于复杂/不必要。是否有一些更好的方法以更少的开销来使这个处理程序非阻塞?

tvm*_*tvm 5

对于任何人谁都会面临这样的解决方案横空出世的描述是简单的在这里

import queue
from logging.handlers 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()
Run Code Online (Sandbox Code Playgroud)

QueueListener 在它自己的线程中运行并侦听由 QueueHandlers 发送的 LogRecords,这会导致非阻塞日志记录。