5

我有一个需要从命令行运行的 Jupyter 笔记本。为此,我有以下命令:

jupyter nbconvert --execute my_jupyter_notebook.ipynb --to python

此命令创建一个 python 脚本,然后执行它。但是,我使用 Python 中的日志库来记录某些事件。当它从上面的命令执行脚本时,终端上什么也看不到。

但是,当我手动执行转换后的 jupyter 时,如下所示,我可以在终端上看到所有日志:

python3 my_jupyter_notebook.py

我尝试添加额外的参数,如 --debug 和 --stdout 但那些只是输出所有代码,而不仅仅是日志。是否可以在执行 nbconvert 执行命令时在终端上输出日志记录结果?

4

2 回答 2

1

这是一个代码,用于捕获在执行 nbconvert 期间产生的警告和异常并将它们传递给记录器。Jupyter 和 nbconvert 使用不同的方式处理异常。

from logging import getLogger
import sys
import traceback
import warnings
import IPython
import logging

logger = getLogger(name)
logging.basicConfig(stream=sys.stdout, level=logging.WARNING)

# Catch Traceback 
def showtraceback(self):
    traceback_lines = traceback.format_exception(*sys.exc_info())
    del traceback_lines[1]
    message = ''.join(traceback_lines)
    logger.error(traceback_lines[-1] + str(message))
IPython.core.interactiveshell.InteractiveShell.showtraceback = showtraceback

# Catch Warning 
def warning_on_one_line(message, category, filename, lineno, file=None, line=None):
    logger.warning(str(message) + '\n' + str(filename) + ' : ' + str(lineno))
    return '%s:%s: %s:%s\n' % (filename, lineno, category.__name__, message)
warnings.formatwarning = warning_on_one_line
于 2018-07-31T10:23:47.940 回答
0

Jupyter 修改了sys.stderrsys.stdout流,因此它们不再指向“标准”stderrstdout(双关语)。但是,它们在 下存储原始文件句柄的副本_original_stdstream_copy,您可以创建一个显式写入原始流的日志处理程序。

def console_handler(stream='stdout'):
    """
    Create a handler for logging to the original console.
    """
    assert stream in {'stdout', 'stderr'}, "stream must be one of 'stdin' or 'stdout'"
    # Get the file handle of the original std stream.
    fh = getattr(sys, stream)._original_stdstream_copy
    # Create a writable IO stream.
    stream = io.TextIOWrapper(io.FileIO(fh, 'w'))
    # Set up a stream handler.
    return logging.StreamHandler(stream)

您可以按如下方式使用该功能。

import logging

logging.basicConfig(...)  # Or some more sophisticated setup.
logger = logging.getLogger('myLogger')
logger.add_handler(console_handler())
logger.error('something went wrong')  # This will write to stderr.
于 2021-09-17T17:42:43.443 回答