轻松处理复杂的警报。 或者说Balerter的创建历史

轻松处理复杂的警报。 或者说Balerter的创建历史

每个人都喜欢警报。

当然,当事情发生(或修复)时得到通知比坐下来查看图表并寻找异常要好得多。

为此创建了许多工具。 来自 Prometheus 生态系统的 Alertmanager 和来自 VictoriaMetrics 产品组的 vmalert。 Grafana 中的 Zabbix 通知和警报。 在 bash 和 Telegram 机器人中自行编写的脚本,定期提取一些 URL 并告诉您是否出现问题。 很多一切。

我们公司也使用了不同的解决方案,直到遇到复杂性,或者更确切地说,无法创建复杂的复合警报。 我们想要的和我们最终做的都低于标准。 TLDR:这就是开源项目的出现方式 巴勒特

在相当长的一段时间里,我们都在 Grafana 中配置的警报生活得很好。 是的,这不是最好的方法。 始终建议使用一些专门的解决方案,例如 Alertmanager。 我们也不止一次考虑搬家。 然后,一点一点地,我们想要更多。

比如说某个图表与之前的 M 小时相比,何时下跌/上涨了 XX% 并且已经存在了 N 分钟? 看来你可以尝试使用 Grafana 或 Alertmanager 来实现这一点,但这并不容易。 (或者也许不可能,我现在不说)

当必须根据不同来源的数据做出警报决策时,事情会变得更加复杂。 实例:

我们检查两个 Clickhouse 数据库中的数据,然后将其与 Postgres 中的一些数据进行比较,并决定发出警报。 发出信号或取消

我们已经积累了很多类似的愿望,让我们思考我们的决定。 然后我们尝试编译该服务的第一个需求/功能列表,该列表尚未创建。

  • 访问不同的数据源。 例如,普罗米修斯、Clickhouse、Postgres

  • 向各种渠道发送警报 - telegram、slack 等。

  • 在思考的过程中,我清楚地意识到我想要的不是声明性描述,而是编写脚本的能力

  • 按计划运行脚本

  • 无需重新启动服务即可轻松更新脚本

  • 无需从源代码重建服务即可以某种方式扩展功能的能力

该列表是近似的,很可能不是很准确。 有些点发生了变化,有些点消失了。 一切如常。

事实上,Balerter 的历史就是这样开始的。

轻松处理复杂的警报。 或者说Balerter的创建历史

我将尝试简要描述一下最终发生的事情以及它是如何运作的。 (是的,当然,这还没有结束,产品开发还有很多计划,今天就到此为止)

它是如何工作的呢?

您用 Lua 编写一个脚本,在其中显式发送请求(到 Prometheus、Clickhouse 等)。 您收到答案并以某种方式处理和比较它们。 然后打开/关闭某种警报。 Balerter 本身会向您配置的渠道(电子邮件、电报、slack 等)发送通知。 该脚本按指定的时间间隔执行。 而且......总的来说,就是这样)

最好用一个例子来展示:

-- @interval 10s
-- @name script1

local minRequestsRPS = 100

local log = require("log")
local ch1 = require("datasource.clickhouse.ch1")

local res, err = ch1.query("SELECT sum(requests) AS rps FROM some_table WHERE date = now()")
if err ~= nil then
    log.error("clickhouse 'ch1' query error: " .. err)
    return
end

local resultRPS = res[1].rps

if resultRPS < minResultRPS then
    alert.error("rps-min-limit", "Requests RPS are very small: " .. tostring(resultRPS))
else
    alert.success("rps-min-limit", "Requests RPS ok")
end 

这里发生了什么:

  • 我们指示该脚本应每 10 秒执行一次

  • 指示脚本的名称(用于 API、用于在日志中显示、用于测试)

  • 连接日志输出模块

  • 连接模块以访问具有名称的 clickhouse ch1 (连接本身在配置中配置)

  • 向 clickhouse 发送请求

  • 如果出现错误,我们会在日志中显示一条消息并退出

  • 将查询结果与常量进行比较(在实际示例中,我们可以例如从 Postgres 数据库获取该值)

  • 启用或禁用带有 ID 的警报 rps-min-limit

  • 如果警报状态发生变化,您将收到通知

这个例子非常简单易懂。 然而,当然,现实生活中的脚本可能相当冗长且复杂。 很容易感到困惑并犯错误。

因此,一个合乎逻辑的愿望已经成熟——能够为脚本编写测试。 在 v0.4.0 版本中出现了这个。

测试脚本

对上面示例中的脚本进行示例测试:

-- @test script1
-- @name script1-test

test = require('test')

local resp = {
    {
        rps = 10
    }
} 

test.datasource('clickhouse.ch1').on('query', 'SELECT sum(requests) AS rps FROM some_table WHERE date = now()').response(resp)

test.alert().assertCalled('error', 'rps-min-limit', 'Requests RPS are very small: 10')
test.alert().assertNotCalled('success', 'rps-min-limit', 'Requests RPS ok')

步骤:

  • 指示为其编写测试的脚本的名称

  • 测试名称(用于日志)

  • 连接测试模块

  • 我们说针对 clickhouse 的特定请求应该返回什么结果 ch1

  • 我们检查是否调用了带有指定消息的警报(错误)rps-min-limit

  • 检查 rps-min-limit 警报是否未禁用(成功)

巴勒特还能做什么?

我将尝试谈谈我认为最重要的 Balerter 技能。 你可以在官方网站上看到所有详细信息 https://balerter.com

  • 接收数据来自

    • 点击之家

    • Postgres的

    • MySQL的

    • 普罗米修斯

    • 洛基

  • 向频道发送通知

    • 松弛

    • 电报

    • 系统日志

    • 通知(计算机上的 UI 通知)

    • 邮箱地址

    • 不和

  • 根据您的数据构建图表,将图像上传到 S3 兼容存储并将其附加到通知(带图片的例子)

  • 允许您在脚本之间交换数据 - 全局键/值存储

  • 在 Lua 中编写您自己的库并在脚本中使用它们(默认情况下,提供 lua 库用于处理 json、csv)

  • 从您的脚本发送 HTTP 请求(当然,还接收响应)

  • 提供 API(尚未达到我们想要的功能)

  • 以 Prometheus 格式导出指标

您还希望能够做什么?

很明显,用户和我们希望能够使用语法控制脚本的启动 cron的。 这将在 v1.0.0 版本之前完成

我想支持更多的数据源和通知传递渠道。 例如,有人肯定会怀念 MongoDB。 弹性搜索一些。 向您的手机发送短信和/或拨打电话。 我们希望不仅能够从文件接收脚本,而且还能够从数据库接收脚本。 最后,我们希望有一个更加用户友好的网站和更好的项目文档。

总有人会遗漏一些东西)在这里,我们依靠社区的请求来正确设置优先级。 并在社区的帮助下实现一切

总之

我们用 巴勒特 我已经坚持了一段时间了。 几十个脚本守护着我们内心的平静。 我希望这项工作对其他人有用。

欢迎提出您的问题和公关。

来源: habr.com

添加评论