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
相关产品推荐
相关产品推荐

