Zulip OpenSearch 集成指南:将 OpenSearch 监控告警实时推送至 Zulip
【免费下载链接】zulipZulip server and web application. Open-source team chat that helps teams stay productive and focused.项目地址: https://gitcode.com/GitHub_Trending/zu/zulip
Zulip 为 OpenSearch(Elasticsearch 的开源分支)提供了官方入站 Webhook 集成,可以把 OpenSearch 的告警监控(Alert monitor)与触发器(Trigger)通知实时推送到指定 Zulip 主题中。本文以 OpenSearch 集成文档 为主线,结合仓库内 视图实现、测试用例 与 fixtures 样例 逐层拆解:从创建机器人、生成 Webhook URL,到配置 OpenSearch 通知渠道与告警监控,再到利用消息模板控制 Zulip 主题与正文格式,最终完成一套可立即投入使用的告警推送链路。
集成总览:OpenSearch 如何把通知送到 Zulip
OpenSearch 的告警机制本身不直接“认识” Zulip,二者通过自定义 Webhook(Custom webhook)这一通用协议桥接:OpenSearch 在告警触发时向一个 HTTP 端点发送POST请求,Zulip 的入站 Webhook 端点接收请求体后,将内容作为一条消息发送到指定的流(Stream)与主题(Topic)。
这里有一个关键实现细节:OpenSearch 发送的 payload 是纯文本(text/plain),即使请求头里声明了其他 Content-Type 也是如此。这一点在 视图源码 的注释中被明确强调:
OpenSearch only sends text/plain payloads, even when the Content-Type is set to other formats.
因此 Zulip 侧的处理逻辑无需解析 JSON 或 XML,而是直接以字符串形式接收整个请求体。核心处理函数api_opensearch_webhook通过@webhook_view("OpenSearch")装饰器注册为入站 Webhook 入口,并使用@typed_endpoint将整个请求体绑定为payload参数:
@webhook_view("OpenSearch") @typed_endpoint def api_opensearch_webhook( request: HttpRequest, user_profile: UserProfile, *, payload: Annotated[str, ApiParamConfig(argument_type_is_body=True)], ) -> HttpResponse: ...从源码结构看,该端点位于 Zulip 标准的入站 Webhook 路由体系中,开发者只需在 OpenSearch 侧把通知端点指向生成的 Webhook URL 即可完成对接。
第一步:在 Zulip 中创建入站 Webhook 机器人并生成 URL
要让 OpenSearch 的通知能够进入 Zulip,首先需要一个专用于该集成的机器人账号(Bot),并拿到对应的 Webhook URL。
- 在 Zulip 组织设置中进入Bots页面,点击Add a new bot,创建一个类型为Incoming webhook的机器人,并为其命名(例如
OpenSearch)。 - 为机器人选择一个目标流(Stream),通知消息将默认发送到该流。
- 创建完成后,复制页面中给出的 Webhook URL。
该 URL 遵循 Zulip 入站 Webhook 的通用格式,测试基础设施中对此有明确约束:测试类WebhookTestCase通过url_template构造请求地址,其中必须包含api_key占位符,并会按webhook_dir_name(即集成目录名opensearch)与目标流名称渲染出完整 URL(见 zerver/lib/test_classes.py 中的build_webhook_url实现)。对应的服务端端点接收该 URL 后,会校验 API key 与目标流,再由check_send_webhook_message完成消息投递。
关于 URL 的详细参数规范,可参见集成文档末尾引用的“Webhook URL 规格说明”(原文档通过
{!webhooks-url-specification.md!}宏引入,适用于所有入站 Webhook 集成)。
第二步:创建 OpenSearch 通知渠道(Notification channel)
拿到 Zulip 的 Webhook URL 后,接下来在 OpenSearch 侧配置通知渠道,让 OpenSearch 知道“告警发生时要往哪里发”。
- 打开 OpenSearch Dashboards 菜单,在Management分区下选择Notifications,点击Create channel(创建渠道)。
- 填写渠道的Name(名称)与Description(描述)。
- 在Channel type(渠道类型)中选择Custom webhook(自定义 Webhook)。
- 配置请求参数:
- Method选择POST;
- Define endpoints by选择Webhook URL;
- 将第一步生成的 Zulip Webhook URL 粘贴到Webhook URL字段中。
- 点击Send test message(发送测试消息),此时 Zulip 的目标流中应立即出现一条测试消息;确认无误后点击Create保存渠道。
这一步骤与仓库测试中的test_test_notification_from_channel用例相互印证:OpenSearch 在创建渠道时发出的测试通知是类似Test message content body for config id Uz5bK5UBeE4fYdADfbg0的纯文本(见 fixtures/test_notification.txt),Zulip 侧直接将其作为消息正文,主题回退为默认值OpenSearch alerts。
第三步:创建告警监控(Alert monitor)与触发器
通知渠道只是“发送通道”,真正决定“什么时候发、发什么内容”的是告警监控与触发器。
- 从 OpenSearch 菜单的OpenSearch Plugins分区选择Alerting,点击Create monitor(创建监控)。
- 配置监控详情:填写监控名称与描述,选择要监控的索引(Index),并定义触发条件(Trigger)。OpenSearch 会根据监控结果持续评估触发器,条件满足时进入告警状态。
- 在监控的Actions(操作)分区中,将第二步创建的通知渠道选择为Notification(通知)动作。这样告警触发时,OpenSearch 就会向该渠道(即 Zulip Webhook)发送通知。
告警监控(Alert monitor)与触发器(Trigger)本身的详细配置项(如查询条件、阈值、频率、严重级别等)属于 OpenSearch 侧能力,官方文档有专门说明,本文不再展开;Zulip 侧只需要接收并渲染其通知结果。
消息模板:用topic:首行控制 Zulip 主题
OpenSearch 发送的通知是纯文本,因此为了让消息在 Zulip 中更易读、可归类,需要使用Message template(消息模板)对内容进行格式化。模板支持两类能力:
- Markdown:用于正文排版(加粗、列表、链接等),Zulip 会正常渲染;
- Mustache 模板变量:用于引用监控上下文,例如
{{ctx.monitor.name}}、{{ctx.trigger.severity}}、{{ctx.trigger.name}}。
其中最关键的是主题(Topic)控制协议:模板的第一行如果以topic:开头,其后的内容会被 Zulip 解析为该条消息的主题;从第二行开始的内容才是消息正文。这正是集成文档强调的约定:“必须格式化为topic: DYNAMIC_TOPIC_CONTENT,且所有消息内容应从模板第二行开始”。
推荐的示例模板
集成文档提供了如下示例模板(可原样复制到 OpenSearch 的 Message template 中):
{% raw %} topic: {{ctx.monitor.name}} Alert of severity **{{ctx.trigger.severity}}** triggered by **{{ctx.trigger.name}}**. {% endraw %}该模板会把监控名称作为 Zulip 主题,正文则用 Markdown 加粗展示严重级别与触发器名称。仓库中的 fixtures/example_template.txt 给出了渲染前的原始内容:
topic: Resource Monitor Alert of severity **3** triggered by **Insufficient memory**.对应到 Zulip 中的效果是:主题为Resource Monitor,正文为加粗的告警描述。该行为在测试用例test_example_template_notification中被完整验证(见 zerver/webhooks/opensearch/tests.py)。
主题解析的底层实现
topic:协议由 视图源码 直接实现:Zulip 收到请求后,先查找 payload 中的第一个换行符,若 payload 以topic:开头且存在换行符,则截取第 7 个字符到换行符之间的内容并去除首尾空白作为主题,剩余部分作为正文;否则整段 payload 作为正文,主题回退为固定的OpenSearch alerts:
end_of_line = payload.find("\n") if payload.startswith("topic:") and end_of_line != -1: topic = payload[6:end_of_line].strip() message = payload[end_of_line + 1 :] check_send_webhook_message(request, user_profile, topic, message) else: check_send_webhook_message(request, user_profile, "OpenSearch alerts", payload)从该实现可以推断出两点使用约束:
topic:必须出现在 payload 的第一行,且以换行符与正文分隔,否则不会被识别;- 未使用
topic:前缀的通知会统一落入默认主题OpenSearch alerts,因此想要按监控维度区分主题,务必在模板首行使用topic:语法。
测试与验证:三种通知场景
Zulip 侧针对该集成编写了三组测试,覆盖了从“渠道测试消息”到“监控动作通知”再到“示例模板”的完整链路(见 zerver/webhooks/opensearch/tests.py):
| 测试用例 | 对应场景 | 输入内容(fixtures) | 期望主题 | 期望正文 |
|---|---|---|---|---|
test_test_notification_from_channel | 创建渠道时的测试通知 | test_notification.txt | OpenSearch alerts(默认) | Test message content body for config id Uz5bK5UBeE4fYdADfbg0 |
test_test_notification_from_monitor_action | OpenSearch 提供的默认消息模板 | default_template.txt | OpenSearch alerts(默认) | 含 Trigger、Severity、Period start/end 的多行告警信息 |
test_example_template_notification | 本文档提供的topic:示例模板 | example_template.txt | Resource Monitor | Alert of severity **3** triggered by **Insufficient memory**. |
这些测试通过继承WebhookTestCase并以text/plain作为 Content-Type 发起请求(见 zerver/lib/test_classes.py 中的共享测试基类),验证了三个关键事实:
- OpenSearch 的 payload 确实是纯文本,Zulip 直接按
text/plain接收; - 不携带
topic:的 payload 会进入默认主题OpenSearch alerts; - 携带
topic:首行的 payload 会被正确拆分出动态主题与正文。
OpenSearch 默认模板长什么样
若不在 OpenSearch 中自定义模板,其默认通知格式大致如下(见 fixtures/default_template.txt):
Monitor Storage size monitor just entered alert status. Please investigate the issue. - Trigger: Storage size over 1TB - Severity: 1 - Period start: 2025-02-25T00:58:39.607Z - Period end: 2025-02-25T00:59:39.607Z可以看到,默认模板没有topic:首行,且没有 Markdown 排版,所有监控的通知都会挤在同一主题下。因此集成文档强烈建议使用自定义 Message template 来格式化消息,这正是上一步“消息模板”小节的意义所在。
在 Zulip 侧验证集成效果
完成 OpenSearch 侧配置后,可以通过两种方式验证整条链路:
- 渠道层测试:在 OpenSearch 通知渠道中点击Send test message,确认 Zulip 目标流出现测试消息——验证 URL、API key 与目标流配置正确;
- 监控层测试:创建好监控与触发器后,在监控配置页点击Send test message,确认主题与正文格式符合预期——验证模板解析正确。
验证通过后,OpenSearch 的每一次真实告警触发都会自动出现在 Zulip 对应流的对应主题中,团队成员即可围绕告警展开讨论,Zulip 的消息线程(Thread)结构天然适合告警排查与协作。
相关文档与资源
- 集成配置说明:zerver/webhooks/opensearch/doc.md
- 服务端处理实现:zerver/webhooks/opensearch/view.py
- 集成测试用例:zerver/webhooks/opensearch/tests.py
- 消息样例数据:zerver/webhooks/opensearch/fixtures
- Webhook 通用测试基类:zerver/lib/test_classes.py
- 关于告警监控(Alert monitor)与触发器(Trigger)的具体配置,可查阅 OpenSearch 官方文档中对应的 “Creating an alert monitor” 与 “Triggers” 章节。
【免费下载链接】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),仅供参考