Delgan / loguru

Python logging made (stupidly) simple
MIT License
19.54k stars 691 forks source link

Asynchronous file sink #1049

Open luyiming opened 9 months ago

luyiming commented 9 months ago

If I understand correctly, we can use enqueue=True on file sinks so that code does not block on logger.info, there is a background thread collecting log records and sending them to file sinks. However, a background thread (with file IO operations) would still block the execution of the main thread. A better way might be to implement an asynchronous file sink using something like aiofile. Then the IO operations can be asynchronously carried out at the operating system level.

Is there any plan on implementing an asynchronous file sink?

Delgan commented 9 months ago

Hi @luyiming.

You're correct about enqueue=True.

Loguru is already compatible with aiofile though, since it supports asynchronous sinks.

from loguru import logger

import asyncio
from pathlib import Path
from tempfile import gettempdir

from aiofile import async_open

tmp_filename = Path("hello.txt")
logger.remove()

async def sink(message):
    async with async_open(tmp_filename, "a") as afp:
        await afp.write(message)
        afp.seek(0)

async def main():
    logger.remove()
    logger.add(sink)

    logger.info("A")
    logger.info("B")
    await logger.complete()

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

I would consider improving support for "asynchronous file sink" out-of-the-box if asynchronous file-IO was part of the Python standard library. Right now, I don't want to add a dependency on a third-party library like aiofile. However, creating and sharing such handler in a separate library might prove useful to others.