26

我正在使用 Sentry(在 django 项目中),我想知道如何正确聚合错误。我将某些用户操作记录为错误,因此没有底层系统异常,并且正在使用该culprit属性设置一个友好的错误名称。该消息是模板化的,并且包含一条公共消息(“用户 'x' 无法执行操作,因为 'y'”),但绝不完全相同(不同的用户,不同的条件)。

Sentry 显然在后台使用了一组属性来确定是否将错误聚合为相同的异常,但是尽管查看了代码,但我无法弄清楚如何。

任何人都可以缩短我必须深入研究代码并告诉我需要设置哪些属性才能按照我的意愿管理聚合的捷径吗?

[更新 1:事件分组]

此行出现在 sentry.models.Group 中:

class Group(MessageBase):
    """
    Aggregated message which summarizes a set of Events.
    """
    ...

    class Meta:
        unique_together = (('project', 'logger', 'culprit', 'checksum'),)
    ...

这是有道理的——我目前正在设置的项目、记录器和罪魁祸首——问题是checksum。我将进一步调查,但是“校验和”表明二进制等价,这永远不会起作用 - 必须可以对具有不同属性的相同异常的实例进行分组?

[更新 2:事件校验和]

事件校验和来自sentry.manager.get_checksum_from_event方法:

def get_checksum_from_event(event):
    for interface in event.interfaces.itervalues():
        result = interface.get_hash()
        if result:
            hash = hashlib.md5()
            for r in result:
                hash.update(to_string(r))
            return hash.hexdigest()
    return hashlib.md5(to_string(event.message)).hexdigest()

下一站——活动interfaces从何而来?

[更新 3:事件接口]

我已经弄清楚接口是指描述传递给哨兵事件的数据的标准机制,并且我正在使用标准sentry.interfaces.Messagesentry.interfaces.User接口。

根据异常实例,这两者都将包含不同的数据——因此校验和永远不会匹配。有什么方法可以将这些从校验和计算中排除?(或者至少是User接口值,因为它必须不同——Message我可以标准化的接口值。)

[更新4:解决方案]

下面分别介绍和接口的两个get_hash函数:MessageUser

# sentry.interfaces.Message
def get_hash(self):
    return [self.message]

# sentry.interfaces.User
def get_hash(self):
    return []

看看这两个,只有Message.get_hash接口会返回一个由get_checksum_for_event方法获取的值,因此这是将返回的值(散列等)。这样做的最终效果是校验和在消息上进行评估单独 - 这在理论上意味着我可以标准化消息并保持用户定义的唯一性。

我已经在这里回答了我自己的问题,但希望我的调查对遇到同样问题的其他人有用。(顺便说一句,我还提交了针对 Sentry 文档的拉取请求作为其中的一部分 ;-))

(注意任何使用/扩展 Sentry 和自定义接口的人 - 如果你想避免你的接口被用于对异常进行分组,请返回一个空列表。)

4

2 回答 2

20

请参阅我在问题本身中的最终更新。事件聚合在“项目”、“记录器”、“罪魁祸首”和“校验和”属性的组合上。其中前三个相对容易控制——第四个,“校验和”是作为事件一部分发送的数据类型的函数。

Sentry 使用“接口”的概念来控制传入数据的结构,每个接口都带有一个实现get_hash,用于为传入的数据返回一个哈希值。Sentry 带有许多标准接口(' Message'、'User'、'HTTP'、'Stacktrace'、'Query'、'Exception'),这些都有自己的get_hash. 默认值(继承自 Interface 基类)是一个空列表,不会影响校验和。

在没有任何有效接口的情况下,事件消息本身被散列并作为校验和返回,这意味着消息需要是唯一的才能对事件进行分组。

于 2012-11-11T15:29:57.660 回答
1

我遇到了异常的常见问题。目前我们的系统只捕获异常,我很困惑为什么其中一些合并到一个错误中,而另一些则没有。根据您上面的信息,我提取了“get_hash”方法并试图找到“引发”我的错误的差异。我发现分组错误都来自一个自写的异常类型,它有一个空的 Exception.message 值。

get_hash 输出:

[<class 'StorageException'>, StorageException()]

并且多个错误来自具有填充消息值的异常类(jinja模板引擎)

[<class 'jinja2.exceptions.UndefinedError'>, UndefinedError('dict object has no attribute LISTza_*XYZ*',)]

不同的异常消息触发不同的报告,在我的情况下,合并是由于缺少 Exception.message 值引起的。

执行:

class StorageException(Exception):

def __init__(self, value):
    Exception.__init__(self)
    self.value = value
于 2013-10-23T15:50:25.600 回答