Zulip 集成 Prometheus Alertmanager:Webhook 配置、告警分组与消息渲染实战 Zulip 集成 Prometheus AlertmanagerWebhook 配置、告警分组与消息渲染实战【免费下载链接】zulipZulip server and web application. Open-source team chat that helps teams stay productive and focused.项目地址: https://gitcode.com/GitHub_Trending/zu/zulipZulip 提供了开箱即用的 Prometheus Alertmanager 集成通过一个标准 Incoming webhook即可把 Alertmanager 的告警firing / resolved实时推送进 Zulip 的某个流stream并按告警标签自动分组到对应话题topic。本文基于仓库中该集成的官方文档doc.md与源码view.py展开完整说明从 URL 生成、Alertmanager receiver 配置到name/desc两个关键参数的作用并深入讲解底层告警消息的解析与渲染逻辑帮助你直接落地一套可用的「Prometheus 告警 → Zulip 通知」链路。集成概览一个专为监控场景设计的 Webhook在 Zulip 的 webhook 体系中该集成在 integrations.py 中被注册为IncomingWebhookIntegration关键注册信息包括集成标识符alertmanager分类monitoring监控类显示名称Prometheus Alertmanager集成 Logoimages/integrations/logos/prometheus.svg截图配置使用alert.json作为演示 fixture并附加了nametopic、descdescription两个示例参数从源码结构看这个集成只依赖一个 webhook 视图函数view.py它接收 Alertmanager 标准 webhook 格式的 JSON 负载解析后通过check_send_webhook_message发送到指定流与话题。官方文档将其定位为 Get Zulip notifications from Prometheus Alertmanager!即把 Zulip 当作 Alertmanager 的一个告警接收端receiver。第一步创建 Incoming webhook 并生成 URL接入的第一步是在 Zulip 中创建机器人并拿到 webhook URL。整个流程分为两步创建 Incoming webhook bot在 Zulip 的「个人设置 → 机器人Bots」中新建机器人类型选择Incoming webhook完整流程可参考 incoming-webhooks-overview.md。创建完成后会得到该机器人专属的api_key它用于在 URL 中鉴权。生成 webhook URLZulip 的 Incoming webhook 遵循统一的 URL 规范见 webhooks-url-specification.md格式为https://zulip-server/api/v1/external/alertmanager?api_keyAPI_KEYstreamSTREAM_NAME从测试用例 tests.py 可以看到该集成的真实 URL 模板/api/v1/external/alertmanager?api_key{api_key}stream{stream}nametopicdescdescription其中api_key上述 Incoming webhook bot 的密钥必填用于鉴权stream告警消息要发送到的流名称可选缺省时发送到默认流name、desc两个可选定制参数作用见下文「配置选项」一节。第二步在 Alertmanager 中配置 Webhook Receiver拿到 URL 之后在 Alertmanager 的配置文件通常是alertmanager.yml中添加一个新的 webhook receiver并把它挂到相应的路由route上。官方文档给出的 receiver 配置如下- name: ops-zulip webhook_configs: - url: the URL generated above将the URL generated above替换为第一步生成的完整 URL 即可例如route: receiver: ops-zulip group_by: [alertname] receivers: - name: ops-zulip webhook_configs: - url: https://zulip.example.com/api/v1/external/alertmanager?api_keyxxxxxxxxstreamops-alertsnameseveritydescdescription配置完成后重载 Alertmanager一旦有告警触发firing或恢复resolvedAlertmanager 就会把告警负载 POST 到该 URLZulip 随即在对应流中生成通知消息。配置选项name与desc参数官方文档给出了两个 URL 参数用于控制告警消息的「分组维度」与「消息正文」这也是该集成最核心的定制点参数用途默认值取值来源name指定告警规则中定义的某个字段labels 或 annotations用于把状态相同的告警分组进同一条 Zulip 消息该字段的值同时作为消息的话题topic名instancelabels 或 annotations 中的字段名desc指定告警规则中定义的某个字段labels 或 annotations用于作为 Zulip 告警消息的正文文本alertnamelabels 或 annotations 中的字段名使用方式是在生成的 URL 后追加参数例如.../api/v1/external/alertmanager?api_keyxxxstreamops-alertsnameseveritydescdescription其底层实现在 view.pyname_field: Annotated[str, ApiParamConfig(name)] instance, desc_field: Annotated[str, ApiParamConfig(desc)] alertname,可见name与desc的默认值分别是instance与alertname即默认情况下Zulip 会以告警的instance标签值作为话题名以alertname作为消息正文。你可以用任何自定义字段覆盖这两个默认值。注意这两个字段可以来自告警的 labels 或 annotationsZulip 会先查 labels再查 annotations查找逻辑见下文源码分析。建议在 Prometheus 告警规则中为每个告警显式定义有意义的instance、alertname、description等标签或注解否则消息正文会出现missing field: xxx占位符。消息处理原理源码级解析该集成的全部逻辑集中在 view.py 的api_alertmanager_webhook函数中处理流程可以拆解为四步1. 遍历 alerts提取分组键与描述Alertmanager 的 webhook 负载顶层包含alerts数组其中每个元素是一个告警对象含status、labels、annotations、generatorURL等字段可参考 alert.json。Zulip 对每个告警做如下提取view.pyname labels.get(name_field, annotations.get(name_field, (unknown))).tame(check_string) desc labels.get(desc_field, annotations.get(desc_field, fmissing field: {desc_field})).tame(check_string)即话题名topic优先取 labels 中name参数指定字段其次取 annotations 中的同名注解都取不到时回退为(unknown)正文描述desc优先取 labels 中desc参数指定字段其次取 annotations 中的同名注解都取不到时回退为missing field: xxx。2. 处理 generatorURL附上告警源链接每个告警对象可能带有generatorURLPrometheus 中该告警表达式的 Grafana/Prometheus 图表链接。Zulip 会将其转换为消息中的 Markdown 链接view.pyif generatorURL in alert: url alert[generatorURL].tame(check_string).replace(tab1, tab0) body f{desc} (source) else: body desc注意细节源码会把generatorURL中的tab1替换为tab0。从仓库测试 fixture 看Prometheus 表达式图表 URL 形如http://cobalt:9090/graph?g0.expr...g0.tab1tab0表示图表页签、tab1表示表格页签替换后消息中的 source 链接会直接打开图形视图对排查告警更直观。如果告警没有generatorURL则正文只有描述文本对应 fixture single_alert_no_url.json。3. 按name分组区分 firing / resolved接下来告警按照name字段的值分组成topics字典每个分组内再按状态拆成firing与resolved两个列表view.pytopics: dict[str, dict[str, list[str]]] {} ... if name not in topics: topics[name] {firing: [], resolved: []} topics[name][alert[status].tame(check_string)].append(body)这就是文档中所述「将相同状态的告警按同一字段值合并为一条 Zulip 消息」的实现相同 topic 值 相同状态的告警会被聚合进同一条消息避免刷屏。4. 渲染消息并发送最后对每个分组、每种状态分别渲染并发送view.py状态为firing时标题为FIRING前缀图标为:alert:状态为resolved时标题为Resolved前缀图标为:squared_ok:组内只有 1 条告警时正文为单行形式{icon} **{title}** {message}组内有多条告警时正文为列表形式{icon} **{title}** * message1 * message2然后通过check_send_webhook_message(request, user_profile, topic_name, body)以name值为话题名发送到目标流。每个分组会独立发送一条消息firing与resolved分别成文。消息效果示例以下消息形态均可在 tests.py 与 fixture 中直接验证。多条 firing 告警聚合alert.json两条告警、同一name:alert: **FIRING** * CPU core temperature is 34.75C ([source](http://cobalt:9090/graph?...g0.tab0)) * CPU core temperature is 17.625C ([source](http://cobalt:9090/graph?...g0.tab0))对应测试test_error_issue_message话题名为andromeda。单条 resolved 告警single_alert.json:squared_ok: **Resolved** CPU core temperature is 34.75C ([source](http://cobalt:9090/graph?...g0.tab0))对应测试test_single_error_issue_message。无 generatorURL 的单条 firing 告警single_alert_no_url.json:alert: **FIRING** CPU core temperature is 34.75C对应测试test_single_alert_no_generator_url。用测试用例验证你的理解仓库为该集成提供了完整的回归测试tests.py它基于WebhookTestCase覆盖了三种典型场景test_error_issue_message多条 firing 告警验证聚合列表渲染与generatorURL链接转换test_single_error_issue_message单条 resolved 告警验证恢复通知与单行渲染test_single_alert_no_generator_url无generatorURL的告警验证无链接时的纯文本渲染。测试同时验证了 URL 参数传递nametopicdescdescription与负载解析application/json。当你调整 Alertmanager 告警规则或自定义name/desc字段时可以参照这些 fixture 的结构alert.json、single_alert.json、single_alert_no_url.json来预判 Zulip 中的最终消息形态。小结与最佳实践URL 鉴权与路由webhook URL 中的api_key来自 Incoming webhook bot务必妥善保管建议在 Alertmanager 的 route 中按团队/环境拆分 receiver配合name参数把不同告警源分流到不同 Zulip 流与话题。字段规划告警规则中尽量同时定义 labels如instance、severity与 annotations如description、summary。name与desc默认取instance与alertname自定义时保证所用字段在所有相关告警中都存在避免(unknown)与missing field: ...占位符。消息聚合同 topic、同状态的告警会被自动合并为一条消息多条时以列表呈现因此按告警密集程度合理选择name分组字段如按severity、host、instance可以在「信息完整」与「避免刷屏」之间取得平衡。恢复通知Alertmanager 的resolved状态会被渲染为独立的:squared_ok: **Resolved**消息便于值班人员确认故障已消除。【免费下载链接】zulipZulip server and web application. Open-source team chat that helps teams stay productive and focused.项目地址: https://gitcode.com/GitHub_Trending/zu/zulip创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考