Sentry的一个重要部分是如何将类似事件聚合在一起并创建汇总。事实证明这是一个相当复杂的问题,并且可能会让用户感到困惑,因为有些信息可能无法正确分组。
事件的结构化数据决定了如何创建汇总。这取决于可用数据和语言。
一、分组优先顺序
分组根据事件中可用的接口(接口)切换行为。
- 如果事件中使用的接口不同,则这些事件不会组合在一起。
- 如果报表中涉及堆栈跟踪或异常,则分组将仅考虑此信息。
- 如果涉及模板,则分组将考虑模板。
- 作为后备,事件的消息将用于分组。
二、由Stacktrace分组
当Sentry在事件数据中检测到堆栈跟踪时(直接或作为异常的一部分),分组有效地完全基于堆栈跟踪。这种分组相当复杂,但很容易理解。
第一个也是最重要的部分是Sentry仅按应用程序中报告的堆栈跟踪帧进行分组。并非所有SDK都可以报告此情况,但如果提供了该信息,则会将其用于分组。这意味着如果堆栈跟踪仅在堆栈的与应用程序无关的部分中从一个事件修改为另一个事件,则它仍然将其分组。
根据信息,可以为每个堆栈跟踪帧使用以下数据:
- 模块名称
- 规范化文件名(从修订哈希等中删除)
- 规范化的上下文行(如果提供的话,基本上是受影响行的源代码的清理版本)
这种分组通常效果很好,但如果不处理,会导致两个恼人的问题。
- 最小化的JavaScript源代码将以非常糟糕的方式破坏分组。 因此,您应确保Sentry可以访问您的Source Map文件。
- 如果通过使用装饰器引入新级别来修改堆栈跟踪,则堆栈跟踪将发生更改,分组也将发生更改。 对于这个问题,许多SDK支持隐藏不相关的堆栈跟踪帧。 例如,Python SDK将跳过所有堆栈帧,并将一个名为__traceback_hide__的局部变量设置为True。
三、按异常分组
如果没有可用的堆栈跟踪但是异常信息,则分组将考虑异常的类型和值。如果其中任何一个不存在,则跳过它。由于更改错误消息,此分组的可靠性要低得多。
四、按模板分组
如果涉及模板,则逻辑类似于通过堆栈跟踪进行分组,但显然信息较少,因为模板跟踪具有较少的可用数据。然而,一般概念适用。
五、后备分组
如果其他一切都失败了,分组会回落到消息中。理想情况下,分组仅使用不带参数的消息,但如果不可用,则使用消息属性。
六、使用指纹自定义分组
对于一些非常高级的用例,SDK可以覆盖Sentry默认分组。
通常会出现两种常见情况:
- 查询RPC或外部API服务,因此堆栈跟踪通常是相同的(即使传出请求非常不同)
- 一般错误(例如数据库连接错误)具有许多不同的堆栈跟踪,并且从不组合在一起。
要解决这些问题,Sentry协议支持指纹属性。
在支持的SDK中,此属性可以与事件信息一起传递,并且应该是字符串数组:
Sentry.configureScope((scope) => {
scope.setFingerprint(['my-view-function']);
});
此外,如果您只是希望附加信息,从而使分组略显不那么激进,您也可以通过添加特殊字符串{{default}}作为其中一项来实现。