【问题标题】:Logging while nbconvert executenbconvert 执行时记录
【发布时间】:2018-11-24 14:02:31
【问题描述】:

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

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

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

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

python3 my_jupyter_notebook.py

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

【问题讨论】:

    标签: python jupyter-notebook jupyter jupyter-lab nbconvert


    【解决方案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
    

    【讨论】:

    • 不确定这是否真的回答了 OP 的问题:通过 nbconvert 运行笔记本时,如何让笔记本中生成的记录器消息显示在终端中?
    【解决方案2】:

    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.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-18
      • 2011-11-09
      • 1970-01-01
      • 2013-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-18
      相关资源
      最近更新 更多