Open goseind opened 1 month ago
Hi @goseind.
As you guessed, this error occurs because the logger is trying to write to a stream object that has been closed, which is invalid (see IOBase.close()
).
When removing a file handler, Loguru will automatically close the corresponding stream object that was opened. However, when dealing with non-file streams like sys.stderr
or sys.stdout
, then Loguru will not close them. This would be very inconvenient and incorrect (as the stream is global, it must remain usable after the sink has been removed).
The error you're facing seems to come from the handler that uses sys.stdout
(according to the configuration you shared). Since Loguru does not close such stream by itself, this means something else closed the stream while it was still in use by the logger
.
At this point, it's unfortunately difficult for me to identify what in your environment or your libraries is causing this effect.
Some tools take the liberty of replacing sys.stdout
with their own stream-like object. In this way, they can capture what is printed on the standard output. This is the case of some libraries, IDEs and Cloud platforms.
The problem is that the logger
will use this wrapped stream as well. But if the third-party tool happens to clean up and close the stream, then the logger
is left with an unusable sink.
Here is a simplified example to illustrate the issue:
from contextlib import contextmanager
import sys
import io
from loguru import logger
@contextmanager
def redirect_stdout(new_target):
old_target, sys.stdout = sys.stdout, new_target
try:
yield new_target
finally:
sys.stdout = old_target
new_target.close()
if __name__ == "__main__":
logger.remove()
f = io.StringIO()
with redirect_stdout(f):
logger.add(sys.stdout)
logger.info("Hello")
print("Captured output:")
print(f.getvalue())
# ValueError: I/O operation on closed file.
logger.info("World")
Here's what you can possibly do in your situation:
sys.stdout
,logger
is always fully re-initialized whenever your environment is susceptible to cleanup the wrapped sys.stdout
;logger
with logger.add(lambda m: sys.stdout.write(m))
instead of logger.add(sys.stdout)
, so that the stream is dynamically retrieved and therefore not sensitive to changes.
I'm experiencing the following error, after some attempts and searching in previous issues I haven't found a solution yet:
My
logger.py
file:I'd be grateful for any hints that point me in the right direction, thanks!