aiologger icon indicating copy to clipboard operation
aiologger copied to clipboard

aiologger closes sys.stdout

Open mbrancato opened this issue 4 years ago • 3 comments

Why does aiologger close sys.stdout or any handler it doesn't open()?

import asyncio
import aiologger


async def testaiolog():
    logger = aiologger.Logger.with_default_handlers(name="my-logger")
    await logger.info("foo")


print("works")
asyncio.run(testaiolog())
print("doesn't work")

results in:

Traceback (most recent call last):
  File "/Users/mike/Documents/.../aiologgertest.py", line 12, in <module>
    print("doesn't work")
ValueError: I/O operation on closed file.
works
foo

mbrancato avatar Jul 14 '21 14:07 mbrancato

Why does aiologger close sys.stdout or any handler it doesn't open()?

import asyncio
import aiologger


async def testaiolog():
    logger = aiologger.Logger.with_default_handlers(name="my-logger")
    await logger.info("foo")


print("works")
asyncio.run(testaiolog())
print("doesn't work")

results in:

Traceback (most recent call last):
  File "/Users/mike/Documents/.../aiologgertest.py", line 12, in <module>
    print("doesn't work")
ValueError: I/O operation on closed file.
works
foo

Any chance you found a solution?

louis030195 avatar Mar 29 '22 06:03 louis030195

Any updates on this issue?

nikita-krokosh avatar Jun 15 '22 11:06 nikita-krokosh

Hello there! I think I've got a semi-reasonable workaround for anyone that's curious. Rather than directly passing sys.stdout or sys.stderr, we create a dup of either and pass that. Example below:

import os
import sys
from aiologger.handlers.streams import AsyncStreamHandler

AsyncStreamHandler(
    stream=os.fdopen(
        os.dup(sys.__stdout__.fileno())
))

Full credit to this StackOverflow answer for the idea: https://stackoverflow.com/a/40845164. Hope this helps!

Quick Edit: This workaround assumes you won't be attempting to re-use the same instance of the Hander/Logger later. I'd recommend creating a logger factory if you plan on passing the same logger between different calls to asyncio.run()/etc.

adalundhe avatar Dec 11 '22 17:12 adalundhe