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

如何在Sentry中将自定义类实例默认显示替换为自定义字典?

解决Sentry中自定义类实例显示优化问题

方法1:重写类的__repr__方法

直接在utils.MyClass中重写__repr__方法,返回包含目标属性的字典格式字符串,Sentry会直接展示该字符串内容:

class MyClass:
    def __init__(self, attr1, attr2):
        self.attr1 = attr1
        self.attr2 = attr2
        self._private_attr = "secret"  # 可按需排除私有属性

    def __repr__(self):
        # 自定义需要展示的属性,也可通过字典推导过滤私有属性
        return str({
            "attr1": self.attr1,
            "attr2": self.attr2,
            # 可选:批量展示非私有属性
            # "public_attrs": {k: v for k, v in self.__dict__.items() if not k.startswith("_")}
        })

修改后Sentry中会显示类似obj: {'attr1': 'value1', 'attr2': 'value2'}的内容,替代默认的对象地址。

方法2:用Sentrybefore_send钩子全局处理

如果不想修改业务类代码,可通过Sentry的before_send钩子,在事件上报前批量转换MyClass实例:

import sentry_sdk
import utils

def serialize_myclass(obj):
    if isinstance(obj, utils.MyClass):
        # 自定义序列化逻辑,支持嵌套对象递归处理
        return {
            "type": "utils.MyClass",
            "attr1": obj.attr1,
            "attr2": obj.attr2,
            # 示例:处理嵌套的自定义类实例
            # "nested_obj": serialize_myclass(obj.nested_obj) if isinstance(obj.nested_obj, utils.MyClass) else obj.nested_obj
        }
    return obj

def before_send(event, hint):
    # 递归遍历事件中的所有数据,替换MyClass实例
    def traverse(data):
        if isinstance(data, dict):
            return {k: traverse(v) for k, v in data.items()}
        elif isinstance(data, list):
            return [traverse(item) for item in data]
        else:
            return serialize_myclass(data)
    
    # 处理异常栈中的变量
    if "exception" in event:
        for exc in event["exception"]["values"]:
            if "stacktrace" in exc:
                for frame in exc["stacktrace"]["frames"]:
                    if "vars" in frame:
                        frame["vars"] = traverse(frame["vars"])
    return event

# 初始化Sentry时传入钩子
sentry_sdk.init(
    dsn="YOUR_DSN",
    before_send=before_send
)

方法3:自定义Sentry序列化器

通过扩展Sentry的Serializer类,注册后自动处理特定类型对象,更符合SDK扩展规范:

import sentry_sdk
from sentry_sdk.serializer import Serializer
import utils

class MyClassSerializer(Serializer):
    def serialize(self, obj, **kwargs):
        if isinstance(obj, utils.MyClass):
            return {
                "class": type(obj).__qualname__,
                "attributes": {k: v for k, v in obj.__dict__.items() if not k.startswith("_")}
            }
        # 非目标类型交给父类处理
        return super().serialize(obj, **kwargs)

# 注册全局序列化器
sentry_sdk.serializer.add_global_serializer(MyClassSerializer())

sentry_sdk.init(dsn="YOUR_DSN")

注意事项

  • 若对象存在循环引用,需在序列化逻辑中添加递归限制或已处理对象标记,避免死循环;
  • 敏感属性(如密钥、密码)务必过滤,禁止上报至Sentry。

内容的提问来源于stack exchange,提问作者Cyril N.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 20:09:30