In some cases I need to monkey-patch stderr
and stdout
to redirect them to logging
. I'm using the solutions from How to redirect stdout and stderr to logger in Python. This code nearly works:
import logging, sys
logging.basicConfig(filename='test.log', format='%(asctime)s %(levelname)s %(message)s', datefmt='%H:%M:%S')
log = logging.getLogger('foobar')
class LoggerWriter:
def __init__(self, level):
self.level = level
self.linebuf = ''
def write(self, buf):
for line in buf.rstrip().splitlines():
self.level(line.rstrip())
def flush(self):
pass
sys.stdout = LoggerWriter(log.warning)
sys.stderr = LoggerWriter(log.error)
print("hello")
blablabla # to trigger an error
but the ouput is not as desired, for example the traceback is split in too many lines. Why? How to improve the formatting?
07:37:02 WARNING hello
07:37:02 ERROR Traceback (most recent call last):
07:37:02 ERROR File "D:\test.py", line 21, in <module>
07:37:02 ERROR blablabla # to trigger an error
07:37:02 ERROR NameError
07:37:02 ERROR :
07:37:02 ERROR name 'blablabla' is not defined
How to avoid the the 3 separate lines (that should be 1 line)?
Or better: the traceback should be logged in one logging
call.
Note: I don't want to use traceback
+ sys.excepthook
(I already used this in another case), here in my application, I really need stderr/stdout patching.