news 2026/9/15 5:10:11

Nightingale 告警静默(Alert Mute)HTTP API 完整指南:面向外部 A2A Agent 与 curl 的接口实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Nightingale 告警静默(Alert Mute)HTTP API 完整指南:面向外部 A2A Agent 与 curl 的接口实战

Nightingale 告警静默(Alert Mute)HTTP API 完整指南:面向外部 A2A Agent 与 curl 的接口实战

【免费下载链接】nightingaleNightingale is to monitoring and alerting what Grafana is to visualization.项目地址: https://gitcode.com/GitHub_Trending/ni/nightingale

导读

Nightingale 的告警静默规则(alert_mute)用于在指定时间范围内按标签条件压制匹配的告警事件,是机房维护窗口、夜间批量任务免打扰、已知问题降噪的标准手段。本文以仓库内面向外部 A2A Agent 的接口说明文档 http-api.md 为主体,系统讲解静默规则的 HTTP API 全貌——包括 9 个端点的路径、方法与请求体格式、权限模型、预览与试运行校验接口、过期规则批量清理,以及"直接修改数据库"的兜底方案,并结合 router.go、router_mute.go、models/alert_mute.go、alert/mute/mute.go 等源码,深入剖析匹配引擎的判定顺序与 9 秒缓存生效机制。读完本文,外部 Agent 或运维脚本即可通过 HTTP 完成静默规则的查询、创建、更新、批量改字段、删除、命中预览与试运行全流程。

说明:应用内 AI 助手(in-app assistant)不应使用这些 HTTP 端点,而应直接调用内置功能工具(FC tools);本文档面向的是外部 A2A Agent,或在给用户提供 curl 命令时使用。


一、API 总览:一张表看懂 9 个端点

所有端点均挂在/api/n9e前缀下,路由定义位于 center/router/router.go。完整清单如下:

操作MethodPath说明
列表(跨业务组)GET/api/n9e/busi-groups/alert-mutes返回当前用户可见的静默规则;支持query搜索、分页,以及expired=1查询已过期规则
列表(单个业务组)GET/api/n9e/busi-group/:id/alert-mutes指定业务组下的静默规则
详情GET/api/n9e/busi-group/:id/alert-mute/:amid单条规则详情
创建POST/api/n9e/busi-group/:id/alert-mutes请求体是单个AlertMute JSON 对象
更新PUT/api/n9e/busi-group/:id/alert-mute/:amid单对象请求体,整体替换——先 GET、再修改、再 PUT
批量改字段PUT/api/n9e/busi-group/:id/alert-mutes/fields请求体为{"ids":[...],"fields":{...}},适合批量禁用/续期
删除DELETE/api/n9e/busi-group/:id/alert-mutes请求体为{"ids":[1,2,3]}
命中预览POST/api/n9e/busi-group/:id/alert-mutes/preview预览一条静默规则草稿会命中哪些当前活跃事件;创建大范围静默前务必先跑
试运行POST/api/n9e/alert-mute-tryrun用规则草稿对某个历史事件做一次匹配试运行
批量清理过期DELETE/api/n9e/alert-mutes需要 admin 权限;异步在后台清理已过期的定时(fixed-period)静默规则(周期静默不清除)

从 router.go 的路由定义可以看到,每个端点都串联了多个中间件:rt.auth()做身份认证、rt.user()注入用户上下文、rt.perm("/alert-mutes")系列做菜单权限校验,部分写操作还叠加了rt.bgrw()(业务组读写权限)与rt.admin()(管理员权限)。


二、认证与权限模型

2.1 认证方式

所有请求都使用 Bearer Token 认证:

Authorization: Bearer <token>

token为当前登录用户在 Nightingale 中签发并持久化于user_token表的访问令牌(可参考 models/user_token.go)。调用前需先通过登录/SSO 流程获取 token。

2.2 权限要求

  • 创建 / 更新 / 删除:需要业务组读写权限(bgrw)+ 对应的/alert-mutes/*菜单权限;
  • 列表 / 详情(只读操作):仅需业务组只读权限即可。

对应到路由中间件(router.go):

  • rt.perm("/alert-mutes"):基础菜单权限,覆盖列表与详情;
  • rt.perm("/alert-mutes/add"):创建与试运行;
  • rt.perm("/alert-mutes/put"):更新与批量改字段;
  • rt.perm("/alert-mutes/del"):删除;
  • rt.bgrw():业务组读写权限,创建/删除/批量改字段均要求;
  • rt.admin():批量清理过期规则(DELETE /api/n9e/alert-mutes)额外要求系统管理员身份。

简言之:只读操作门槛低,写操作必须同时具备业务组读写权限与对应菜单权限,批量清理则必须是 admin


三、核心数据模型:AlertMute 字段与 JSON 序列化

http-api.md明确指出"直接修改数据库(兜底)"时表名为alert_mute,其中tags/periodic_mutes/severities/datasource_ids是 JSON / 序列化字段。其数据模型定义在 models/alert_mute.go,关键点:

  • DB 存储形态与 API 形态分离DatasourceIdsPeriodicMutesSeverities在 GORM 中映射为字符串(JSON 序列化后的文本),而对外 JSON 输出分别由DatasourceIdsJsonPeriodicMutesJsonSeveritiesJson承载;FE2DB()负责从 API 形态序列化到 DB 形态,DB2FE()负责反向解析(models/alert_mute.go);
  • Tags字段以ormx.JSONArr存储,是一组TagFilter的 JSON 数组,每个元素形如{"key":..., "func":..., "value":...}
  • MuteTimeType0=固定时间区间(TimeRange),1=周期静默(Periodic);
  • MuteType0=屏蔽事件与通知(默认,命中后事件不产生也不通知),1=只屏蔽通知(事件照常产生记录,仅不发送通知);
  • Activated查询时动态计算的展示字段gorm:"-"),表示"此刻是否处于生效时间内",并非存储状态。

Verify()(models/alert_mute.go)包含两条硬校验:

  1. datasource_ids为空或包含0时自动归一化为[0](即"全部数据源");
  2. etime <= btime直接报错oops... etime(%d) <= btime(%d))——这条校验对周期静默同样生效,因此即使周期匹配不读取 btime/etime,创建时也必须让两者满足etime > btime

四、逐个端点详解与 curl 实战

4.1 列表查询

跨业务组列表

curl -G "http://<n9e-host>:17000/api/n9e/busi-groups/alert-mutes" \ -H "Authorization: Bearer <token>" \ --data-urlencode "query=web01" \ --data-urlencode "expired=1"
  • 返回当前用户可见业务组下的全部静默规则;
  • query参数做模糊搜索(源码中是对cause字段做like匹配,见 models/alert_mute.go);
  • expired=1用于查询已过期的固定区间静默规则(mute_time_type=0 AND etime < now)。

单业务组列表

curl -G "http://<n9e-host>:17000/api/n9e/busi-group/12/alert-mutes" \ -H "Authorization: Bearer <token>"

4.2 详情查询

curl "http://<n9e-host>:17000/api/n9e/busi-group/12/alert-mute/345" \ -H "Authorization: Bearer <token>"

返回单条规则完整 JSON,包含datasource_idsseveritiesperiodic_mutestags等解析后的数组形态字段,以及动态计算的activated字段。更新前务必先 GET(见下节)。

4.3 创建

curl -X POST "http://<n9e-host>:17000/api/n9e/busi-group/12/alert-mutes" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "note": "Maintenance window: mute web01 alerts", "cause": "web01 planned maintenance, expected 2 hours", "prod": "metric", "cate": "prometheus", "datasource_ids": [], "severities": [1, 2, 3], "tags": [ {"key": "ident", "func": "==", "value": "web01"} ], "mute_time_type": 0, "btime": 1737000000, "etime": 1737007200, "periodic_mutes": [], "cluster": "0" }'

要点:

  • 请求体是单个AlertMute 对象,不是数组
  • mute_time_type=0(固定区间)时必须满足etime > btime,否则Verify()直接拒绝;
  • datasource_ids为空数组即"全部数据源"(会自动归一化为[0]);
  • tags为空数组意味着无条件静默该业务组内全部告警,属于高风险配置,务必谨慎;
  • 完整的字段表、时间模式与 tags 运算符说明见配套文档 reference.md。

4.4 更新(整体替换)

curl -X PUT "http://<n9e-host>:17000/api/n9e/busi-group/12/alert-mute/345" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "note": "Maintenance window: mute web01 alerts (extended)", "cause": "maintenance extended", "prod": "metric", "cate": "prometheus", "datasource_ids": [], "severities": [1, 2, 3], "tags": [{"key": "ident", "func": "==", "value": "web01"}], "mute_time_type": 0, "btime": 1737000000, "etime": 1737014400, "periodic_mutes": [], "cluster": "0" }'

关键语义:PUT 是整体替换(replaced wholesale)。从源码 models/alert_mute.go 可见,Update会把新对象的字段整体Select("*").Updates(arm)覆盖写回,仅保留IdGroupIdCreateAtCreateBy四个不可变字段。因此标准操作流程是:GET 详情 → 在返回 JSON 基础上修改 → 原样 PUT,任何漏传字段都会被覆盖为空值,切勿只传想改的字段。

4.5 批量改字段

curl -X PUT "http://<n9e-host>:17000/api/n9e/busi-group/12/alert-mutes/fields" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "ids": [345, 346, 347], "fields": {"disabled": 1} }'
  • fields支持任意可更新字段的键值对,典型场景:批量禁用({"disabled":1})、批量续期(修改etime)、批量改标签;
  • 底层走UpdateFieldsMap(models/alert_mute.go),仅更新传入字段,不触碰其他列——与 4.4 的整体替换形成鲜明对比;
  • 处理器实现见 router_mute.go 的alertMutePutFields

4.6 删除

curl -X DELETE "http://<n9e-host>:17000/api/n9e/busi-group/12/alert-mutes" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"ids": [345, 346, 347]}'

底层对应models.AlertMuteDel(models/alert_mute.go),按 ID 批量物理删除。应用内 AI 助手场景下删除建议走 UI(告警管理 → 告警屏蔽),或先disabled:1临时禁用(更安全)。


五、命中预览与试运行:创建大范围静默前的安全阀

这是http-api.md重点强调的两个"校验类"端点,用于在创建大范围静默前验证影响面,避免误伤。

5.1 命中预览:POST /api/n9e/busi-group/:id/alert-mutes/preview

请求体为一条 AlertMute 草稿 JSON(与创建时同构,group_id取自 URL 路径参数)。处理器alertMutePreview(router_mute.go)的逻辑是:

  1. f.Verify()校验并解析 tags 为ITags
  2. 从活跃事件表alert_cur_event中按业务组、产品、严重级别、数据源等条件取出候选事件(AlertCurEventGetsFromAlertMute);
  3. 逐个用common.MatchTags做标签匹配,返回所有会被这条静默命中的活跃事件列表
curl -X POST "http://<n9e-host>:17000/api/n9e/busi-group/12/alert-mutes/preview" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "note": "check impact before large mute", "prod": "metric", "cate": "prometheus", "datasource_ids": [], "severities": [1,2,3], "tags": [], "mute_time_type": 0, "btime": 1737000000, "etime": 1737007200, "periodic_mutes": [], "cluster": "0" }'

如果返回的事件数量远超预期(例如空 tags 命中了整个业务组),说明影响面过大,应在创建前调整条件。

5.2 试运行:POST /api/n9e/alert-mute-tryrun

用一个规则草稿对某个具体历史事件做一次匹配试运行,返回 "event match mute" 或 "event not match mute"。处理器alertMuteTryRun(router_mute.go)的流程:

  1. 绑定表单:AlertMute草稿 +EventId(历史事件 ID)+PassTimeCheck标志;
  2. 通过AlertHisEventGetById取历史事件并转为当前事件形态、构建 TagsMap;
  3. PassTimeCheck=true,把静默时间强制改为"每天 00:00~00:00"的周期形式,从而跳过时间窗口判断、只验证业务组/数据源/严重级别/标签是否匹配
  4. 调用引擎核心函数mute.MatchMute得到匹配结果。
curl -X POST "http://<n9e-host>:17000/api/n9e/alert-mute-tryrun" \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{ "event_id": 98765, "pass_time_check": true, "alert_mute": { "note": "tryrun", "prod": "metric", "cate": "prometheus", "datasource_ids": [], "severities": [1,2,3], "tags": [{"key": "ident", "func": "==", "value": "web01"}], "mute_time_type": 0, "btime": 1737000000, "etime": 1737007200, "periodic_mutes": [], "cluster": "0" } }'

该端点非常适合排查"为什么这条静默不生效"——用真实事件逐条验证草稿配置。


六、批量清理过期静默:DELETE /api/n9e/alert-mutes

固定区间的静默规则到期后不会自动删除(仅不再加载进匹配缓存),长时间运行会积累大量无效数据。管理员可通过该端点异步清理:

curl -X DELETE "http://<n9e-host>:17000/api/n9e/alert-mutes" \ -H "Authorization: Bearer <token>"
  • 必须 admin 权限(路由中带rt.admin());
  • 后台异步批量删除"已过期的固定区间静默"(mute_time_type=0 AND etime > 0 AND etime < now AND create_at < now),周期静默(periodic)不会被清理
  • 底层实现见 models/alert_mute.go 的AlertMuteBatchDelete,支持按业务组限制范围与分批 limit,处理器为 router_mute.go 的alertMuteBatchDelete

七、兜底方案:直接修改数据库

当 HTTP API 无法满足需求(例如需要跨业务组批量迁移、修复脏数据)时,http-api.md给出了最后的兜底手段:

  • 表名alert_mute
  • JSON/序列化字段tags(TagFilter 数组 JSON)、periodic_mutes(PeriodicMute 数组 JSON)、severities(int 数组 JSON)、datasource_ids(int 数组 JSON);
  • 生效机制:修改后内存缓存最长约9 秒自动重载(见 memsto/alert_mute_cache.go,轮询间隔为time.Duration(9000) * time.Millisecond),无需重启服务
  • 务必先备份再修改

需要注意的语义细节(详见配套排障文档 troubleshooting.md):

  • 已过期的固定区间静默不会加载进匹配缓存,直接改 DB 时同样遵循该规则;
  • prod/cate/cluster字段仅用于展示,不参与匹配,不要指望用它们过滤事件。

八、源码级原理:匹配引擎如何判定"命中静默"

理解这些 HTTP 端点返回结果的前提,是掌握底层匹配语义。核心函数MatchMute位于 alert/mute/mute.go,按固定顺序逐门校验,任一关卡失败即判定未命中

顺序关卡源码逻辑失败常见原因
0缓存同步内存缓存轮询约 9s 重载(memsto/alert_mute_cache.go)刚改完规则立即测试,缓存尚未刷新
1业务组group_id隔离事件与规则不在同一业务组(最常见根因)
2启用状态Disabled == 1直接返回 false规则被禁用
3数据源datasource_ids非全量时,事件datasource_id必须在列表中数据源不匹配
4时间固定区间[btime, etime]闭区间判定(IsWithinTimeRange);周期静默按星期 + HH:mm 判定(IsWithinPeriodicMute,models/alert_mute.go)触发时间不在窗口内;enable_days_of_week写法错误
5严重级别severities非空时,事件Severity必须在列表中级别不匹配
6标签多条 tagsAND 关系common.MatchTags,alert/common/key.go)事件缺少任一标签或值不匹配

几个值得展开的引擎语义:

  • 静默发生在事件评估阶段alert/process/process.go):命中静默的事件被直接丢弃——不落库(不产生当前/历史告警记录)、不发送通知,仅在服务日志与静默计数指标中留痕;
  • 不会误判恢复:被静默事件的 hash 仍会记入告警集合,因此已触发的告警不会因为静默而"假装恢复";同理,静默不会清除已产生的活跃告警——"静默生效后历史告警页仍能看到旧事件"是正常现象;
  • 周期静默的时间判定不读取 btime/etime(源码 models/alert_mute.go 只看enable_days_of_week+enable_stime/enable_etime),btime/etime 仅为通过etime > btime硬校验而存在;
  • 跨午夜原生支持enable_stime > enable_etime(如22:00~06:00)按">= stime< etime"判定;
  • 星期编号0=周日 … 6=周六,时间判定使用 n9e 进程的本地时区;
  • in/not in运算符的值为空格分隔字符串(ParseTagFilterstrings.Fields切分,models/alert_mute.go),写成逗号分隔会匹配失败。

prodcatecluster三字段在MatchMute中完全不参与判定,属于纯展示字段。


九、常见坑位速查

结合配套排障文档 troubleshooting.md 与源码,外部调用方最容易踩的坑:

现象原因处理
etime <= btime报错Verify()硬校验,周期静默同样要求确保etime > btime;或使用应用内工具传duration参数自动计算
周期静默在 btime/etime 边界行为异常周期匹配不读btime/etime,只看星期+时段想实现"仅某个月生效"需到期手动禁用/删除
enable_days_of_week1-5Monday to Friday不生效引擎对空格分隔数字串做 contains 匹配"1 2 3 4 5",或用"weekday"等别名
in值写逗号分隔不生效解析用strings.Fields(按空白切分)改为空格分隔
tags 有 key 无 value空值参与精确匹配,几乎必然失配先确认真实标签值再填
想屏蔽"某条告警规则"事件标签含rulename{"key":"rulename","func":"==","value":"<规则名>"}
大范围误静默tags 为空数组 = 静默整个业务组创建前先跑preview端点核对影响面

十、与内置 Agent 工具的分工

http-api.md开篇即强调:应用内 AI 助手不应使用这些端点,而应使用内置 FC 工具(如create_alert_muteupdate_alert_mutelist_alert_mutesget_alert_mute_detail),工具的完整工作流见 SKILL.md。二者适用边界:

  • 内置工具:运行在 n9e 进程内、已认证为当前用户,直接调用即可,支持duration参数自动换算时间戳、空业务组时自动弹出选择表单、修改走"提案确认"机制等高级能力,是应用内推荐路径;
  • HTTP API:面向外部 A2A Agent,或用户明确索要 curl 命令时使用;需要自行管理 token、自行计算 btime/etime、注意 PUT 整体替换语义。

两者共享同一套数据模型与匹配引擎,因此本章讲解的字段、校验、匹配顺序与缓存机制,对两种调用方式完全一致——这也是理解本 API 全部行为的最佳捷径。


延伸阅读

  • http-api.md:本文核心文档
  • reference.md:静默规则完整字段表、两种时间模式、tags 运算符与完整示例
  • troubleshooting.md:"静默不生效"逐门排障链与行为语义表
  • models/alert_mute.go:数据模型、Verify校验、FE2DB/DB2FE序列化与批量删除
  • alert/mute/mute.go:匹配引擎MatchMute六道关卡
  • alert/common/key.go:标签匹配MatchTags与六种运算符实现
  • center/router/router.go:路由与权限中间件定义
  • center/router/router_mute.go:预览、试运行、批量清理等处理器实现

【免费下载链接】nightingaleNightingale is to monitoring and alerting what Grafana is to visualization.项目地址: https://gitcode.com/GitHub_Trending/ni/nightingale

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 5:10:10

MFC对话框全屏播放视频:从ActiveX控件到窗口样式与消息处理

简介&#xff1a;这是一份面向Visual C开发者的全屏播放视频示例工程&#xff0c;基于MFC对话框框架实现&#xff0c;主要解决Windows下视频播放与窗口/全屏切换的核心问题&#xff0c;适合有一定C基础、希望入门多媒体开发的读者。压缩包内共13个文件&#xff0c;包括MFC对话框…

作者头像 李华
网站建设 2026/9/15 5:10:00

高通车载芯片EDL救砖实战指南:SA8838/8155/8295变砖诊断与QCN恢复

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 5:09:25

软考高项怎么学?过来人亲述选老师、避坑与12周备考路线

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 5:09:16

MATLAB中用RUN优化器自动调优XGBoost回归超参数

简介&#xff1a;RUN-XGBOOST龙格库塔优化xgboost回归预测&#xff0c;是一套面向Matlab用户的多输入单输出回归建模实现&#xff0c;适合需要快速搭建预测模型或研究龙格库塔算法与XGBoost结合优化的学习者。压缩包共包含10个文件&#xff0c;主要为7个m脚本、1个xlsx数据集、…

作者头像 李华
网站建设 2026/9/15 5:06:41

搞懂域名服务器才谈得上100个农村电商平台避坑指南

搞懂域名服务器才谈得上100个农村电商平台避坑指南 域名解析报错、服务器配置混乱,这是建站新手最容易踩的坑。很多老板以为买个模板就能上100个农村电商平台,结果卡在工信部ICP备案系统审核这一步,钱花了站没起来。这份避坑指南专门讲透技术底层,让你不再被忽悠。 1.…

作者头像 李华
网站建设 2026/9/15 5:06:08

Wireshark流量包分析实战:从SMB共享取证到攻击溯源

1. 靶场开局&#xff1a;把 SMB 共享里的 pcap 安全拿到本地1.1 为什么靶场总喜欢用 SMB 共享派发流量包做过靶场或者参加过 CTF 流量分析题的朋友应该都有体会&#xff0c;最常见的拿包方式就是给你一个下载链接&#xff0c;或者直接告诉你"流量包放在 SMB 共享里"。…

作者头像 李华