簡體   English   中英

將 STDOUT 和 STDERR 重定向到 python 記錄器和 jupyter notebook

[英]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文件中,能夠將stdoutstderr重定向到my_log.log文件。 但是我在普通終端控制台中丟失了消息。

我想要的是將stderrstdout 都重定向到日志文件,並且還能夠在控制台上看到它們。

第二個問題:我正在處理 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM