简体   繁体   English

使用 async emit 创建一个 logging.Handler

[英]Making a logging.Handler with async emit

I have a Python log handler that writes using asyncio (it's too much work to write to this particular service any other way).我有一个 Python 日志处理程序,它使用 asyncio 写入(以任何其他方式写入此特定服务的工作量太大)。 I also want to be able to log messages from background threads, since a few bits of code do that.我还希望能够记录来自后台线程的消息,因为一些代码可以做到这一点。 So my code looks basically like this (minimal version):所以我的代码基本上是这样的(最小版本):

class AsyncEmitLogHandler(logging.Handler):
    def __init__(self):
        self.loop = asyncio.get_running_loop()
        super().__init__()

    def emit(self, record):
        self.format(record)
        asyncio.run_coroutine_threadsafe(
            coro=self._async_emit(record.message),
            loop=self.loop,
        )

    async def _async_emit(message):
        await my_async_write_function(message)

Mostly it works fine but when processes exit I get a lot some warnings like this: "coroutine 'AsyncEmitLogHandler._async_emit' was never awaited"大多数情况下它工作正常但是当进程退出时我收到很多这样的警告:“coroutine 'AsyncEmitLogHandler._async_emit' was never awaited”

Any suggestions on a cleaner way to do this?关于更清洁的方法有什么建议吗? Or some way to catch shutdown and kill pending writes?或者某种方式来捕获关闭并杀死挂起的写入? Or just suppress the warnings?或者只是抑制警告?

Note: the full code is [here][1] [1]: https://github.com/lsst-ts/ts_salobj/blob/c0c6473f7ff7c71bd3c84e8e95b4ad7c28e67721/python/lsst/ts/salobj/sal_log_handler.py注意:完整代码在[此处][1][1]:https://github.com/lsst-ts/ts_salobj/blob/c0c6473f7ff7c71bd3c84e8e95b4ad7c28e67721/python/lsst/ts/salobj/sal_log_handler.py

You could keep a reference to the coro, and override the handler's close() method to call close() on it.您可以保留对 coro 的引用,并覆盖处理程序的close()方法以在其上调用close() A general way to manage coros is to keep a list of them in the handler, and override the handler's close() method to call close() on each coro, or else create tasks from them and call cancel() on each of the tasks.管理 coros 的一般方法是在处理程序中保留它们的列表,并覆盖处理程序的close()方法以在每个 coro 上调用close() ,或者从它们创建任务并在每个任务上调用cancel() .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM