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

时间:2017-10-15 10:30:53

标签: python http asynchronous logging

我正在尝试实现使用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变得不可访问或开始缓慢响应时,显然会导致调用线程的锁定。所以我试图想出最好的方法让这个调用独立于调用线程。

我考虑过的事情:

  1. 包含一些会使http请求异步的非标准库
  2. 按照概述here
  3. 使用QueueHandler和QueueListener
  4. 使用asyncio
  5. 所有这些解决方案似乎过于复杂/不必要,无法实现这样简单的任务。是否有一些更好的方法,更少的开销,以使这个处理程序不阻塞?

1 个答案:

答案 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,这会导致非阻塞日志记录。