[英]Redirect STDOUT and STDERR to python logger and also to jupyter notebook
重要提示:我正在研究 jupyter notebook。
我想創建一個記錄器,我會將 STDOUT 和 STDERR 重定向到該記錄器,但我也想在 jupyter notebook 輸出控制台上看到這些輸出。
到目前為止,我已經實施的是:
import logging
import sys
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):
for line in buf.rstrip().splitlines():
self.logger.log(self.log_level, line.rstrip())
def flush(self):
pass
logging.basicConfig(filename='my_log.log',
filemode='a',
# stream=sys.stdout,
level=logging.DEBUG,
format='%(asctime)s;%(name)s;%(levelname)s;%(message)s')
# redirect stdout and stderr to logger
stdout_logger = logging.getLogger('STDOUT')
sl = StreamToLogger(stdout_logger, logging.INFO)
sys.stdout = sl
stderr_logger = logging.getLogger('STDERR')
s2 = StreamToLogger(stderr_logger, logging.ERROR)
sys.stderr = s2
log = logging.getLogger('my_log')
# An info log
log.info('This is an info')
# A stdout message
print("This is an STDOUT")
# A stderr message
1 / 0
第一個問題:前面的代碼,如果存儲在.py文件中,能夠將stdout和stderr重定向到my_log.log文件。 但是我在普通終端控制台中丟失了消息。
我想要的是將stderr和stdout 都重定向到日志文件,並且還能夠在控制台上看到它們。
第二個問題:我正在處理 jupyter 筆記本,我希望能夠從那里登錄。 這意味着所有 stdout 和 stderr 從 jupyter notebook 輸出重定向到日志文件,但也將其保留在 jupyter notebook 控制台上。 我意識到上面的代碼將標准輸出重定向到日志文件而不是標准錯誤,因此我所有的打印('XX')都在我的日志文件中,而我的異常仍然在筆記本控制台上。
似乎 jupyter notebooks 以不同的方式處理 STDOUT 和 STDERR
謝謝你的幫助
可能有點晚了。
我有類似的要求,我能找到的最好方法是類似於以下代碼。 我用它來跟蹤將運行數天的模型訓練的輸出。 它可以記錄通過調用文件Std2File.enable(file_name)
並通過調用回滾Std2File.disable()
它可以登錄到文件並將其顯示給筆記本。 唯一的缺點是筆記本上顯示的輸出將始終顯示在調用enable
的單元格中。
class Std2File(object):
"""
Redirect stoout and stderr to a local file.
It is designed for use case of notebook where after you close a notebook you can record the stdout and stderr
"""
stdout = None
stderr = None
fd = None
def __init__(self, f, std):
self.std = std
self.f = f
@staticmethod
def enable(f='/tmp/std_copy.log'):
if Std2File.stdout is None:
Std2File.stdout = sys.stdout
Std2File.stderr = sys.stderr
Std2File.fd = open(f, 'a+')
sys.stdout = Std2File(Std2File.fd, sys.stdout)
sys.stderr = Std2File(Std2File.fd, sys.stderr)
print('\n\nbackup stdout/stderr to %s at %s\n' % (f, dt.datetime.now()))
@staticmethod
def disable():
if Std2File.stdout is not None:
sys.stdout = Std2File.stdout
sys.stderr = Std2File.stderr
Std2File.stderr = Std2File.stdout = None
Std2File.fd.close()
Std2File.fd = None
def __getattr__(self, name):
return object.__getattribute__(self.f, name)
def write(self, x):
self.std.write(x)
self.std.flush()
self.f.write(x)
self.f.flush()
def flush(self):
self.std.flush()
self.f.flush()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.