如何限制或屏蔽structlog异常报告中的局部变量长度?
如何限制或屏蔽structlog异常报告中的局部变量长度?
哥们,我之前也踩过这个坑——structlog默认的异常追踪会一股脑把所有局部变量都打出来,碰到那种几百KB甚至几MB的大变量,日志直接变得又长又没用。下面给你分享两个亲测有效的解决办法:
一、完全屏蔽特定变量
如果有某个特定的变量(比如huge_dataset、large_response这种)每次都会搞大日志,我们可以自定义一个异常处理器,把它从追踪信息里过滤掉。
首先写一个继承自structlog默认异常处理器的自定义类:
from structlog._loggers import ExceptionPrettyPrinter class FilteredExceptionPrinter(ExceptionPrettyPrinter): def __call__(self, logger, method_name, event_dict): # 先让父类处理基础的异常栈信息 event_dict = super().__call__(logger, method_name, event_dict) # 处理异常文本,过滤目标变量 if 'exc_text' in event_dict: filtered_lines = [] skip_var_content = False # 要屏蔽的变量名,这里可以改成你要过滤的那个 target_var = "huge_data" for line in event_dict['exc_text'].split('\n'): # 碰到目标变量的定义行 if target_var in line and line.startswith(' '): filtered_lines.append(f' {target_var}: [已过滤 - 变量过大]') skip_var_content = True continue # 如果是变量的多行内容(比如字典、列表的展开行),直接跳过 if skip_var_content and line.startswith(' '): continue # 碰到下一个变量的行,结束跳过 if skip_var_content and not line.startswith(' '): skip_var_content = False filtered_lines.append(line) event_dict['exc_text'] = '\n'.join(filtered_lines) return event_dict
然后在配置structlog的时候,把这个自定义处理器替换掉默认的:
import structlog structlog.configure( processors=[ structlog.stdlib.add_log_level, FilteredExceptionPrinter(), # 用自定义处理器替代默认的ExceptionPrettyPrinter structlog.stdlib.render_to_log_kwargs, ], logger_factory=structlog.stdlib.LoggerFactory(), )
这样一来,目标变量就会被替换成提示文本,它的所有大内容也会被跳过,日志瞬间清爽很多。
二、截断长变量的输出长度
如果不想完全屏蔽,只是想把过长的变量内容截断,只保留开头一部分,那可以修改上面的处理器,改成截断逻辑:
from structlog._loggers import ExceptionPrettyPrinter class TruncatedExceptionPrinter(ExceptionPrettyPrinter): def __call__(self, logger, method_name, event_dict): event_dict = super().__call__(logger, method_name, event_dict) if 'exc_text' in event_dict: truncated_lines = [] # 自定义截断长度,比如保留前100个字符 max_length = 100 for line in event_dict['exc_text'].split('\n'): # 识别变量定义行 if ' = ' in line and line.startswith(' '): var_name, var_value = line.split(' = ', 1) if len(var_value) > max_length: # 截断并添加提示 line = f"{var_name} = {var_value[:max_length]}... [已截断,原长度{len(var_value)}]" truncated_lines.append(line) event_dict['exc_text'] = '\n'.join(truncated_lines) return event_dict
同样,把这个处理器配置到structlog里就行,所有超过长度的变量都会被自动截断,还会提示原长度,方便你知道这个变量有多大。
小提示
如果你的项目用的是structlog结合JSON格式日志,那处理逻辑会稍微不同——你需要去修改异常栈的结构化数据,而不是文本内容,但核心思路还是一样的:通过自定义处理器拦截并修改异常相关的字段。
内容来源于stack exchange
相关产品推荐
相关产品推荐

