Skip to content

Instantly share code, notes, and snippets.

@Timmate
Last active June 25, 2022 17:32
Show Gist options
  • Save Timmate/ad26f88b57b945d3c4766502d84b922e to your computer and use it in GitHub Desktop.
Save Timmate/ad26f88b57b945d3c4766502d84b922e to your computer and use it in GitHub Desktop.
import logging
# w/o below lines with reloading `logging` no log file will be saved in Jupyter/IPython env, see here: https://stackoverflow.com/questions/31169540/python-logging-not-saving-to-file
from imp import reload
reload(logging)
from contextlib import redirect_stdout, redirect_stderr
LOG_FILE_NAME = 'log.txt'
# from https://stackoverflow.com/a/36296215
class StreamToLogger(object):
"""
Fake file-like stream object that redirects writes to a logger instance.
"""
def __init__(self, logger, log_level=logging.INFO):
self.logger = logger
self.log_level = log_level
self.linebuf = ''
def write(self, buf):
temp_linebuf = self.linebuf + buf
self.linebuf = ''
for line in temp_linebuf.splitlines(True):
# From the io.TextIOWrapper docs:
# On output, if newline is None, any '\n' characters written
# are translated to the system default line separator.
# By default sys.stdout.write() expects '\n' newlines and then
# translates them so this is still cross platform.
if line[-1] == '\n':
self.logger.log(self.log_level, line.rstrip())
else:
self.linebuf += line
def flush(self):
if self.linebuf != '':
self.logger.log(self.log_level, self.linebuf.rstrip())
self.linebuf = ''
# for logging both to console and file. Idea with handlers taken from here: https://stackoverflow.com/a/46098711
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s:%(levelname)s:%(name)s: %(message)s',
handlers=[
logging.FileHandler(LOG_FILE_NAME),
logging.StreamHandler()
],
)
# for logging to file only
# logging.basicConfig(
# level=logging.DEBUG,
# format='%(asctime)s:%(levelname)s:%(name)s: %(message)s',
# filename=LOG_FILE_NAME,
# filemode='a'
# )
stdout_logger = logging.getLogger('STDOUT')
sl_out = StreamToLogger(stdout_logger, logging.INFO)
stderr_logger = logging.getLogger('STDERR')
sl_err = StreamToLogger(stderr_logger, logging.ERROR)
with redirect_stdout(sl_out), redirect_stderr(sl_err):
<put your code here>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment