You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jupyter Notebook中如何让logging.exception输出带颜色的异常回溯

Jupyter Notebook中如何让logging.exception输出带颜色的异常回溯

嗨,这个问题我之前也碰到过!默认情况下logging.exception()输出的回溯确实是黑白的,和Jupyter原生抛出异常时的彩色样式不一样,其实原因很简单:Jupyter的彩色回溯是IPython专门做了格式处理的,而logging默认的输出没有加颜色标记。不过我们可以通过自定义日志格式化器来解决这个问题,下面给你两种实用的方法:

方法一:给异常回溯单独添加颜色

这种方法只针对异常回溯部分上色,其他日志内容保持原样,比较轻量:

首先导入需要的模块,IPython自带的颜色工具类能帮我们轻松调用终端颜色码:

import logging
from IPython.utils.coloransi import TermColors

然后定义一个自定义的日志格式化器,重写异常回溯的格式化逻辑:

class ColoredExceptionFormatter(logging.Formatter):
    def formatException(self, exc_info):
        # 获取默认的黑白回溯文本
        raw_tb = super().formatException(exc_info)
        # 给回溯加上Jupyter常用的浅红色,最后恢复默认颜色
        return f"{TermColors.LIGHT_RED}{raw_tb}{TermColors.NORMAL}"

接下来配置logging使用这个格式化器:

# 获取根日志器,先清理掉默认的处理器避免重复输出
root_logger = logging.getLogger()
for handler in root_logger.handlers[:]:
    root_logger.removeHandler(handler)

# 创建新的输出处理器,绑定自定义格式化器
console_handler = logging.StreamHandler()
formatter = ColoredExceptionFormatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)

# 添加处理器并设置日志级别
root_logger.addHandler(console_handler)
root_logger.setLevel(logging.DEBUG)

现在测试你的代码,就能看到带红色的异常回溯了:

a = []
try:
    a[1]
except Exception as e:
    logging.exception(e)

方法二:给整个日志(含级别、回溯)添加对应颜色

如果想让日志的不同级别(比如INFO、ERROR)也带上颜色,同时回溯保持彩色,可以用这个更全面的格式化器:

class FullColoredFormatter(logging.Formatter):
    # 给不同日志级别分配对应颜色
    LEVEL_COLORS = {
        logging.DEBUG: TermColors.LIGHT_BLUE,
        logging.INFO: TermColors.LIGHT_GREEN,
        logging.WARNING: TermColors.LIGHT_YELLOW,
        logging.ERROR: TermColors.LIGHT_RED,
        logging.CRITICAL: TermColors.LIGHT_RED + TermColors.BOLD
    }

    def format(self, record):
        # 给日志级别名称上色
        color = self.LEVEL_COLORS.get(record.levelno, TermColors.NORMAL)
        record.levelname = f"{color}{record.levelname}{TermColors.NORMAL}"
        
        # 处理异常回溯:找到回溯起始位置,给整个回溯块上色
        result = super().format(record)
        if record.exc_info:
            tb_start = result.find("Traceback (most recent call last):")
            if tb_start != -1:
                result = f"{result[:tb_start]}{TermColors.LIGHT_RED}{result[tb_start:]}{TermColors.NORMAL}"
        return result

配置的时候把之前的ColoredExceptionFormatter换成这个FullColoredFormatter就行,这样ERROR级别的日志名称会是红色,回溯也会是红色,和Jupyter原生的样式更贴近。

小提示

如果不想修改全局的日志配置,你可以创建自己的专属日志器,只给这个日志器绑定彩色格式化器,比如:

my_logger = logging.getLogger("my_project_logger")
my_logger.setLevel(logging.DEBUG)

# 清理默认处理器
for handler in my_logger.handlers[:]:
    my_logger.removeHandler(handler)

# 添加彩色处理器
handler = logging.StreamHandler()
handler.setFormatter(FullColoredFormatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
my_logger.addHandler(handler)

之后用my_logger.exception(e)输出异常,就不会影响其他日志的输出样式啦~

备注:内容来源于stack exchange,提问作者user19976975

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 14:47:30