1. 页面概览

1.1 是什么

「告警自愈」页(对应前端源码 action/web/src/views/apollo/AlertsPage.vue,页面标题「Apollo 告警与自愈」,对齐 TAD-09 告警与自愈)是 LightApollo 的告警规则、事件单、自愈、通知与静默的统一操作台。页面顶部是五张 summary 计数卡(告警规则数 / 触发事件数 / 未处理事件单 / 自愈执行数 / 自愈成功数),主体按 五个 Tab 把「检测 → 归并 → 处置 → 自愈 → 通知」闭环切开:Tab1「告警规则」配置触发条件(绑定健康检查或事件)、级别、防抖/冷却与通知渠道;Tab2「事件单」展示并处置归并后的事件;Tab3「自愈策略」维护自动修复动作(需审批的策略进入人工审批流)并展示自愈历史;Tab4「通知渠道」维护 webhook/email/钉钉/企微外发目标;Tab5「静默」在指定时间窗内屏蔽匹配的告警。

理解本页的关键是抓住后端 alert 包的两条异步链路,页面只是它们的控制面:一条是「评估」——后端 Scheduler 每 15s 驱动一次 EvaluateAll,对每条启用且绑定健康检查的规则读取 health_check_results 最新结果做条件匹配,命中则创建 firing 告警事件并按规则归并事件单(同规则持续触发不重复开单,只累积事件 id 并抬升级别);另一条是「恢复」——条件不再满足时把该规则 firing 事件置 resolved 并自动关闭未解决事件单(resolution_note 写 健康检查恢复,告警自动关闭)。页面不轮询任何运行态,看到的规则/事件单/策略/渠道/静默都是库表全量(写操作成功后才会重拉对应列表)。事件单打开的同时会联动自愈:命中绑定规则且 enabled 的自愈策略即生成自愈历史,自动型直接执行、需审批型挂 pending_approval 等人审批。

输入是用户对五类运维对象的增删改(规则条件 JSON、事件单处置 note、自愈动作、渠道 url、静默时间窗与 matcher),输出是各 Tab 的表格行、summary 计数与一行式操作结果提示。与相邻页的关系:「监控可观测」页负责健康检查(本页规则弹窗的下拉与评估依据都来自 health_checks/health_check_results),本页把「健康检查异常」翻译成「可处置的事件单 + 可执行的修复动作」,是 Apollo 健康闭环的出口。

典型使用链路:① 先到「监控可观测」页确认目标健康检查存在且启用(本页下拉才能选到);② 本页 Tab1「新建告警规则」:选触发类型 health_check、绑定健康检查、指标来源 response_time_ms、条件方式阈值比较(op >、value 2000)、级别 warning,可填防抖/冷却与通知渠道;③ 到 Tab3「新建自愈策略」绑定该规则、选 restart、勾选「需要审批后执行」;④ 等健康检查指标超阈值 → 后端评估触发 → Tab 事件单归并出现 open 事件单 → 自愈历史出现 pending_approval 行 → 本页「审批」后自动执行 restart;⑤ 健康恢复 → 事件单自动关闭;⑥ 若目标服务要发版,到 Tab5「新建静默」设时间窗让告警安静。已修复(提交 412e9c48):此前「各 Tab 首次切换不加载」「summary 两张卡恒 0」「pendingHistory 未定义致渲染异常」三处前端缺陷均已修复(各 Tab 在挂载时并行拉取、summary 补全自愈计数、待审批计数改为 pendingHistoryCount 计算属性),演示已无需绕行。

1.2 核心价值/能力表

能力说明对应页面操作
告警规则绑定健康检查或事件,condition JSON 支持健康状态匹配与阈值比较,级别/防抖/冷却/通知渠道可配Tab1 规则列表 + 新建/编辑弹窗 + 启停开关 + 删除
事件单归并同规则 firing 事件归并到同一 open 事件单并抬升级别;恢复自动关单Tab2 事件单列表 + 确认/解决弹窗
自愈策略restart/rollback/scale_up/scale_down/clean_disk 五种动作,可限制自动尝试次数Tab3 策略列表 + 新建/编辑 + 启停 + 删除
人工审批流需审批策略先落 pending_approval,审批后才执行;拒绝则不再执行Tab3 自愈历史区「审批」/「拒绝」
通知渠道webhook 真实 HTTP POST(10s 超时),email/钉钉/企微为日志占位Tab4 渠道列表 + 新建 + 行内「测试」+ 删除
静默窗口活动时间窗内匹配 matcher 的告警不再触发(空对象匹配全部)Tab5 静默列表 + 新建弹窗 + 删除
顶部总览规则数 / 触发事件数 / 未处理事件单 / 自愈执行数 / 自愈成功数五卡页顶 summary-row 五张卡

1.3 一句话总结

告警自愈页把「规则 → 事件 → 归并事件单 → 自愈 → 通知 → 静默」全链路的控制面收进五个 Tab,让健康异常自动变成可处置、可审批、可通知、可屏蔽的运维动作。

2. 访问入口

2.1 路由与菜单

路由 path/apollo/alerts
路由 nameApolloAlerts
meta.titleApollo 告警自愈
侧边栏入口ApolloLayout 侧边栏「告警自愈」,位于「监控」之后、「安全合规」之前
前端源码action/web/src/views/apollo/AlertsPage.vue
API 客户端action/web/src/api/apolloClient.js
路由注册action/web/src/router/index.js/apollo 子路由 children 下第 463~468 行,component: ApolloAlertsPage,挂 ApolloLayout

相邻页(侧边栏顺序):监控可观测 monitoring.html(前,健康检查即本页规则触发源)、安全合规 security.html(后)、部署与漂移 deployments.html(事件单处置/自愈动作常作用于部署目标)。

2.2 认证与权限

2.3 端口与 API 前缀

3. 界面布局


+--------------------------------------------------------------+
| Apollo 告警与自愈                              [新建告警规则]  |
| [alert-info 顶部说明]  [操作结果提示条(可关闭)]               |
+--------------------------------------------------------------+
| [summary 五卡] 规则数|触发事件数|未处理事件单|自愈执行数|自愈成功数 |
+--------------------------------------------------------------+
| [Tab 条] 告警规则 | 事件单 | 自愈策略 | 通知渠道 | 静默         |
+--------------------------------------------------------------+
| 规则 Tab: [告警规则(N)卡片]                                  |
|   ID|名称|级别|触发类型|指标来源|条件|通知渠道|启用|操作         |
+--------------------------------------------------------------+
| 事件单 Tab: [事件单(N)卡片]                                  |
|   ID|标题|级别|状态|处置人|创建时间|操作(确认/解决)           |
+--------------------------------------------------------------+
| 自愈策略 Tab: [自愈策略(N)卡 + 右下[新建自愈策略]]             |
|   ID|名称|动作类型|动作目标|触发规则|自动尝试|需审批|启用|操作    |
|   [自愈历史卡] 标题行含「(待审批 N 条)」                      |
|   ID|事件单|动作类型|目标|状态|时间|操作(pending_approval 行) |
+--------------------------------------------------------------+
| 通知渠道 Tab: [通知渠道(N)卡 + 右下[新建通知渠道]]            |
|   ID|名称|类型|Webhook URL|启用|操作(测试/删除)              |
+--------------------------------------------------------------+
| 静默 Tab: [静默(N)卡 + 右下[新建静默]]                        |
|   ID|名称|开始时间|结束时间|匹配条件(matcher)|创建人|操作     |
+--------------------------------------------------------------+
| 弹窗:新建/编辑规则 | 事件单确认/解决 | 新建/编辑策略 |           |
|       新建渠道 | 新建静默                                        |
+--------------------------------------------------------------+

各板块职责:

板块职责
页头 + 顶部说明 + 提示条标题「Apollo 告警与自愈」、「新建告警规则」入口、TAD-09 说明、全局操作结果提示(info/success/error 三型,可关闭)
summary 五卡GET /projects/1/alert-summary 五类计数(规则数/事件数/未处理事件单/自愈执行数/自愈成功数),失败保持全零不阻塞主列表
Tab 条五键切换 activeTab,纯本地状态;各 Tab 数据在页面挂载时并行拉取,切换即见数据(不再依赖写操作触发)
告警规则卡规则全量表格 + 行内启停/编辑/删除
事件单卡归并事件单表格 + 行内确认/解决
自愈策略卡 + 自愈历史卡策略 CRUD 表格 + 底部新建按钮;下方独立「自愈历史」卡收纳待审批记录与执行结果
通知渠道卡渠道表格 + 行内测试/删除 + 底部新建
静默卡静默表格 + 行内删除 + 底部新建
五个弹窗新建/编辑规则、事件单处置、新建/编辑策略、新建渠道、新建静默

4. 交互元素

4.1 页头、顶部说明、summary 卡与 Tab 条

控件位置含义必填/默认/可用条件操作效果触发后端调用边界与细节
页面标题页头 h2页面身份标识常驻Apollo 告警与自愈与源码 h2 逐字一致
「新建告警规则」页头右上(btn-primary)打开规则新建弹窗始终可用openCreateRule() 重置表单并弹窗无(提交才触发)默认 trigger_type=health_check、health_check_id=下拉第一个(无则空)
顶部说明标题下 alert-infoTAD-09 定位说明常驻纯文案告警规则绑定健康检查(或事件),触发后归并生成事件单;自愈策略按规则自动执行(restart / rollback / scale_up / scale_down / clean_disk),需要审批的策略经人工审批后执行(TAD-09)。
操作结果提示条说明下方最近一次操作结果alert.message 才显示按 alert.type 着色;「关闭」按钮清空单槽覆盖,无历史
summary 规则数/触发事件数五卡前两张项目内规则总数、触发事件总数挂载即拉展示 summary.rules/summary.eventsGET /projects/1/alert-summary后端键 rule_count/event_count 能命中前端别名;规则增删后随 fetchSummary 刷新
summary 未处理事件单/自愈执行数/自愈成功数五卡后三张未关闭事件单数、自愈执行次数、自愈成功次数同上展示 summary.open_incidents/healingActionCount/healingSuccessCount同上已修复(提交 412e9c48):前端别名已覆盖后端键 open_incident_count/healing_total/healing_successAlertsPage.vue:904-906,后端 alert_handlers.go:1183-1188);后两张为 computed,接口缺键时回退用已加载的 history 统计(AlertsPage.vue:663-680
Tab 条五键summary 下方切换视图常驻activeTab = t.key 纯本地切换已修复(提交 412e9c48)onMounted 并行拉取 incidents/policies/history/channels/silences(AlertsPage.vue:1397-1407),切 Tab 即见数据,不再需要写操作触发首次加载

页面用一组 ref 维护状态:PROJECT_ID(常量 1)、rules/incidents/policies/history/channels/silences(六类列表)、healthChecks(规则弹窗下拉)、loading(各列表加载位,初始仅 rules:true)、busy(当前进行中的操作键,非空时全局按钮禁用)、alert(提示条单槽)、summary(五卡计数)、五个弹窗状态(ruleModal/incidentModal/policyModal/channelModal/silenceModal)。

页面 onMounted 并行拉取 fetchSummary / fetchRules / fetchIncidents / fetchPolicies / fetchHistory / fetchChannels / fetchSilences / fetchHealthChecksAlertsPage.vue:1397-1407)。无定时轮询、无手动刷新按钮;各 Tab 数据均在挂载时加载一次,切换即见(详见 4.8)。

4.2 告警规则 Tab(行级控件)

卡片标题固定 告警规则({{ rules.length }})。空态 暂无告警规则,点击"新建告警规则"添加(项目 #{{ PROJECT_ID }})。;有数据渲染表格,列头依次 ID / 名称 / 级别 / 触发类型 / 指标来源 / 条件 / 通知渠道 / 启用 / 操作。各列取值:

取值规则(逐字对应源码)
IDr.id 等宽显示
名称加粗 r.name
级别status-badge 按 severityClass 映射:critical 红(status-revoked)/ warning 橙(status-degraded)/ info 蓝(status-registering),文案取 severityLabelcritical(严重)
触发类型triggerTypeLabelhealth_check(健康检查) / event(事件)
指标来源r.metric_source || '-'(health_status / response_time_ms / status_code)
条件conditionSummary(r.condition){health:{status}}健康状态 = unhealthy{threshold:{op,value}}> 2000;扁平 status 显 健康状态 = x
通知渠道channelSummary:数组 join ', ',空显 -
启用「已启用」(btn-success)/「已停用」(btn-outline)切换按钮,busy 非空禁用

4.2.1 行内启停开关按钮

控件位置含义可用条件操作效果触发后端调用边界与细节
「已启用/已停用」启用列(btn-success/btn-outline)切换规则启用态busy 为空handleToggleRuleop = r.enabled ? 'disable' : 'enable',成功取 data?.enabled ?? op==='enable',提示 告警规则 #{id} 已启用/已停用(success)并 fetchRules()POST /alert-rules/:id/enable/disable失败提示 启用/停用告警规则 #{id} 失败:{msg}未刷新 summary

4.2.2 行内「编辑」「删除」

控件位置含义可用条件操作效果触发后端调用边界与细节
「编辑」操作列(btn-outline)打开编辑弹窗回填busy 为空openEditRuleparseCondition 把 condition 还原为 mode/status/op/value 回填,通知渠道数组 join 逗号无(提交才触发)编辑弹窗标题 编辑告警规则 #{id}!=/= 等后端支持的 op 不在下拉选项内时选择框显示空但值保留(见 8)
「删除」操作列(btn-danger)删除规则busy 为空confirm('确定删除告警规则 "{name}"(#id)吗?') 通过后 DELETE,提示 告警规则已删除(success)并 fetchRules()+fetchSummary()DELETE /alert-rules/:id确认文案逐字见左;删除后绑定该规则的自愈策略 trigger_rule_id 悬空不再触发;失败提示 删除告警规则失败:{msg}

4.3 告警规则新建/编辑弹窗

控件位置含义必填/默认/可用条件操作效果触发后端调用边界与细节
弹窗标题弹窗头标识当前模式create 显 新建告警规则,edit 显 编辑告警规则 #{id}-点遮罩 @click.self 或「关闭」可关
名称(name)*表单首行规则名称必填;placeholder 如 web 响应超时告警空名前端拦截提示 告警规则名称(name)必填-保存 payload name trim
级别(severity)*级别下拉告警级别必填;三选 critical(严重)/warning(警告)/info(提示)写入 severity-默认 warning
触发类型(trigger_type)*触发类型下拉触发来源必填;health_check(健康检查)/event(事件)切换 health_check 时显示条件/指标区-默认 health_check;event 类型不展示条件表单(后端对 event 触发的评估见 8 边界)
健康检查(health_check_id)健康检查下拉绑定探针下拉含 不绑定(事件触发) + 各 {name}(#{id})绑定后指标/条件区可用下拉数据来自 GET /projects/1/health-checks(挂载时拉)health_check_id 默认取下拉第一项healthChecks[0]?.id,空则 '');选了 health_check 类型但留空绑定时规则不会参与评估(见 7.5)
指标来源(metric_source)下拉(health_check 时显)阈值比较的指标三选 health_status(健康状态)/response_time_ms(响应时长)/status_code(状态码)写入 metric_source-默认 health_status
条件方式下拉(health_check 时显)条件结构健康状态匹配/阈值比较(op+value)切换 health 与 threshold 子表单-默认 health
匹配健康状态(condition.status)下拉健康匹配目标healthy(健康)/degraded(降级)/unhealthy(不健康)生成 condition:{health:{status}}-默认 unhealthy
比较符(condition.op)下拉阈值比较符>/>=/</<=/== 五选(文案 >(大于) 等)生成 condition:{threshold:{op,value}}-后端支持 =!=,UI 未提供(见 8)
阈值(condition.value)number step=any阈值数值placeholder 如 2000Number(condition_value) 入 payload-空值 Number(undefined)=NaN,阈值条件恒 false(见 7.6)
防抖窗口(duration_seconds)number min=0防抖秒数placeholder Number()||0 入 payload-与 cooldown 取 max 作为抑制窗口(见 5.4)
冷却时间(cooldown_seconds)number min=0冷却秒数placeholder Number()||0 入 payload-同上
通知渠道(notification_channels,渠道名,逗号分隔)input外发渠道名列表placeholder 如 ops-webhook,dingtalk逗号 split + trim + filter 后数组入 payload(空则不携带)-下方 muted 提示 可用渠道:{渠道名顿号}或暂无渠道(Tab 通知渠道中创建)
「取消」弹窗底部关闭-ruleModal.visible=false不校验
「创建/保存」弹窗底部(submit)提交busy 为空;进行中按钮显示 保存中...create POST 成功提示 告警规则创建成功(id={id}),edit PUT 成功提示 告警规则 #{id} 更新成功;成功后关弹窗并 fetchRules()+fetchSummary()POST /projects/1/alert-rules / PUT /alert-rules/:id失败提示 保存告警规则失败:{msg}

payload 组装buildRulePayload):固定 {name, trigger_type, severity, duration_seconds, cooldown_seconds, condition}trigger_type==='health_check' 时带 metric_sourcehealth_check_id 非空时带 Number(health_check_id),event 类型 metric_source 置空串;condition 由 buildRuleCondition 按条件方式生成 {health:{status}}{threshold:{op,value}},event 类型返回 {}编辑保存为全量 PUT,会把未展示字段(如 event 类型的旧 metric_source)按当前表单覆盖。

4.4 事件单 Tab(含确认/解决弹窗)

卡片标题固定 事件单({{ incidents.length }})。空态 暂无事件单,一切正常。;表格列头 ID / 标题 / 级别 / 状态 / 处置人 / 创建时间 / 操作。取值:标题加粗 inc.title;级别徽标同规则页;状态徽标取 inc.status || 'open'incidentStatusClass 映射 open 红 / acknowledged 橙 / investigating 蓝 / resolved 绿;处置人 inc.acknowledged_by || '-';时间 formatTime(inc.created_at)

控件位置含义可用条件操作效果触发后端调用边界与细节
「确认」操作列(btn-outline)确认事件单(认领)inc.status === 'open' || inc.status === 'investigating' 才渲染;busy 为空openIncidentAction(inc,'acknowledge') 弹窗提交才触发已解决/已确认的行不显示确认按钮
「解决」操作列(btn-success)关闭事件单inc.status !== 'resolved' 才渲染;busy 为空openIncidentAction(inc,'resolve') 弹窗提交才触发已解决行不显示
处置弹窗标题弹窗头标识动作-确认事件单 #{id} / 解决事件单 #{id}-
处置说明(note)textarea rows=3处置备注placeholder 按动作变:acknowledge 如:已通知值班同学跟进排查;resolve 如:服务已重启,指标恢复正常提交 body {note: note.trim()}POST /incidents/:id/acknowledge/resolve注意:acknowledge 后端只记当前用户名为处置人、丢弃 note(见 5.4/8);resolve 才会把 note 写入 resolution_note
「取消」/「确认或解决」弹窗底部关闭/提交提交时 busy 为空;进行中按钮显示 提交中...成功提示 事件单 #{id} 已确认/已解决(状态:{status})(success),关弹窗并 fetchIncidents()+fetchSummary()同上失败提示 处理事件单 #{id} 失败:{msg}已修复(提交 412e9c48):事件单列表已在 onMounted 拉取(AlertsPage.vue:1401),进入 Tab 即见数据,不再出现「无数据行即无入口触发首次加载」的结构性空态

4.5 自愈策略 Tab(策略 + 自愈历史)

策略卡片标题固定 自愈策略({{ policies.length }}),空态 暂无自愈策略,点击"新建自愈策略"添加。;表格列头 ID / 名称 / 动作类型 / 动作目标 / 触发规则 / 自动尝试 / 需审批 / 启用 / 操作。取值:动作类型徽标按 actionClass(restart 蓝 / rollback 橙 / scale_up、scale_down 绿 / clean_disk 灰),文案 actionLabelrestart(重启);动作目标 p.action_target || '-';触发规则 ruleName(p.trigger_rule_id)(命中当前 rules 显示 名称(#id),未命中显 #id);自动尝试 p.max_auto_attempts;需审批徽标 需审批(status-degraded)/自动(status-offline);启用列按钮同规则页(「已启用/已停用」)。卡片右下角「新建自愈策略」。

策略行内控件:

控件位置含义可用条件操作效果触发后端调用边界与细节
启停按钮启用列切换策略启用态busy 为空handleTogglePolicyop = p.enabled ? 'disable' : 'enable',成功提示 自愈策略 #{id} 已启用/已停用fetchPolicies()POST /healing-policies/:id/enable/disable该端点需 PermAlertExecute;失败提示 启用/停用自愈策略 #{id} 失败:{msg}
「编辑」操作列编辑回填busy 为空openEditPolicy 回填全部字段无(提交才触发)弹窗标题 编辑自愈策略 #{id}
「删除」操作列(btn-danger)删除策略busy 为空confirm('确定删除自愈策略 "{name}"(#id)吗?') 通过后 DELETE,提示 自愈策略已删除fetchPolicies()DELETE /healing-policies/:id已产生的自愈历史记录保留;失败提示 删除自愈策略失败:{msg}
「新建自愈策略」策略卡右下(btn-primary)打开新建始终可用openCreatePolicy 重置表单默认 trigger_rule_id=rules[0]?.id(无规则则 null)、action_type=restart、max=1

4.5.1 自愈策略新建/编辑弹窗

字段位置含义必填/默认操作效果触发后端调用边界与细节
名称(name)*首行策略名必填;placeholder 如 web 自动重启策略trim 入 payload--
动作类型(action_type)*下拉修复动作必填;五选 restart(重启)/rollback(回滚)/scale_up(扩容)/scale_down(缩容)/clean_disk(清理磁盘)写入 action_type-默认 restart
触发规则(trigger_rule_id)*下拉绑定告警规则必填;选项为当前 rules 各 {name}(#{id})Number(trigger_rule_id) 入 payload-无规则时下拉为空、表单无法提交(校验见下)
动作目标(action_target)input动作目标可空;placeholder 如 env-1:web / svc 名trim 或 '' 入 payload-透传给 ActionExecutor
最大自动尝试次数(max_auto_attempts)number min=0成功次数上限默认 '1'Number()||0 入 payload-0=不限制(见 5.4 canAttempt)
需人工审批checkbox是否需审批后执行默认不勾选requires_approval bool 入 payload-勾选文案 需要审批后执行

提交校验(handleSavePolicy):名称空或 trigger_rule_id 空 → 提示 自愈策略名称与触发规则(trigger_rule_id)必填。create POST /projects/1/healing-policies 成功提示 自愈策略创建成功(id={id});edit PUT /healing-policies/:id 成功提示 自愈策略 #{id} 更新成功;成功后关弹窗并 fetchPolicies()不刷新历史);失败提示 保存自愈策略失败:{msg}

4.5.2 自愈历史卡与审批/拒绝

自愈历史卡片标题行:自愈历史 + muted (待审批 {{ pendingHistory.length }} 条)。空态 暂无自愈历史。;表格列头 ID / 事件单 / 动作类型 / 目标 / 状态 / 时间 / 操作。状态徽标 healingStatusClass:pending_approval 橙 / approved、executing 蓝 / success 绿 / failed 红 / denied 灰。

控件位置含义可用条件操作效果触发后端调用边界与细节
「审批」历史行(btn-success)通过待审批自愈h.status === 'pending_approval' 才渲染;busy 为空handleApproveHistory(h,'approve') POST,成功提示 自愈记录 #{id} 已审批(状态:{status})(success)并 fetchHistory()POST /healing-history/:id/approve后端审批通过后立即执行(见 5.4);失败提示 审批自愈记录 #{id} 失败:{msg}
「拒绝」历史行(btn-danger)拒绝待审批自愈同上confirm('确定拒绝自愈记录 #{id} 吗?将不再执行该动作。') 通过后 POST,成功提示 自愈记录 #{id} 已拒绝(状态:{status})fetchHistory()POST /healing-history/:id/deny拒绝即终态(denied),不再执行;失败提示 拒绝自愈记录 #{id} 失败:{msg}

已修复(提交 412e9c48):标题行待审批计数改用 pendingHistoryCount 计算属性(AlertsPage.vue:663history 过滤 pending_approval,模板 :248 引用),不再引用未声明的 pendingHistory,进入本 Tab 不再抛渲染异常。历史卡数据已在 onMounted 拉取(AlertsPage.vue:1403),进入 Tab 即显示存量历史。

4.6 通知渠道 Tab

卡片标题固定 通知渠道({{ channels.length }}),空态 暂无通知渠道,点击"新建通知渠道"添加。;表格列头 ID / 名称 / 类型 / Webhook URL / 启用 / 操作。类型徽标 channelClass:webhook 绿 / email 蓝 / dingtalk 橙 / wecom 灰,文案 channelLabelwebhook/email/dingtalk(钉钉)/wecom(企微);URL 列 channelUrl(ch.config)(字符串 config 先 JSON.parse 再取 url,空显 -,mono url-cell 超长省略);启用列纯展示徽标 启用(status-online)/停用(status-offline)。卡片右下「新建通知渠道」。

控件位置含义可用条件操作效果触发后端调用边界与细节
「测试」操作列(btn-outline)真实试发渠道busy 为空handleTestChannel POST,ok = data.success===true||data.ok===true||data.sent===truemsg = data?.message || (ok ? '测试消息已发送' : '测试发送失败'),提示 通知渠道 "{name}" 测试:{msg}(按 ok 着 success/error)POST /notification-channels/:id/testwebhook 真实 POST 10s 超时;email/钉钉/企微返回占位 note 恒 success;失败(catch)提示 通知渠道 "{name}" 测试失败:{errMsg}
「删除」操作列(btn-danger)删除渠道busy 为空confirm('确定删除通知渠道 "{name}"(#id)吗?') 通过后 DELETE,提示 通知渠道已删除fetchChannels()DELETE /notification-channels/:id规则里若仍引用该渠道名,发送时查不到同名渠道即跳过(见 8);失败提示 删除通知渠道失败:{msg}
「新建通知渠道」卡片右下(btn-primary)打开新建弹窗始终可用重置表单弹窗标题 新建通知渠道(项目 #{{ PROJECT_ID }})

新建渠道弹窗字段:名称(name)* placeholder 如 ops-webhook;类型(type)* 下拉四选(默认 webhook);Webhook URL(config.url)placeholder 如 https://hooks.example.com/xxx,下方 muted 提示 webhook 类型真实发送(HTTP POST,10s 超时);邮件/钉钉/企微仅模拟。 校验:名称空 → 通知渠道名称(name)必填。payload {name:trim, type, config:{url:trim}}非 webhook 类型也一律包 config.url)。POST /projects/1/notification-channels 成功提示 通知渠道创建成功(id={id}),失败 保存通知渠道失败:{msg}

4.7 静默 Tab

卡片标题固定 静默({{ silences.length }}),空态 暂无静默,点击"新建静默"添加。;表格列头 ID / 名称 / 开始时间 / 结束时间 / 匹配条件(matcher)/ 创建人 / 操作。matcher 列 stringify JSON 化(空显 -);时间列 formatTime;创建人 s.created_by || '-';操作列仅「删除」。卡片右下「新建静默」。

字段位置含义必填/默认操作效果触发后端调用边界与细节
名称(name)*弹窗首行静默名必填;placeholder 如 发布窗口静默trim 入 payload--
开始/结束时间(starts_at/ends_at)*两个 datetime-local静默窗口必填new Date(x).toISOString() 入 payload-前端先校验结束须晚于开始
匹配条件(matcher JSON)textarea rows=3匹配器可空(空对象匹配全部)JSON.parse 后入 payload-placeholder {"severity":"critical"} 或 {"rule_id":3},空对象匹配全部

前端校验(handleSaveSilence,拦截文案逐字):三必填缺失 → 静默名称与时间窗(starts_at/ends_at)必填ends_at <= starts_at结束时间必须晚于开始时间;matcher 非空且 JSON 非法 → matcher 不是合法 JSON:{e.message}。POST /projects/1/silences 成功提示 静默创建成功(id={id}),失败 保存静默失败:{msg};删除经 confirm('确定删除静默 "{name}"(#id)吗?'),成功 静默已删除,失败 删除静默失败:{msg},均刷新 fetchSilences()。后端另有同名校验 静默结束时间须晚于开始时间 双保险(见 5.4)。

4.8 全局互斥与数据刷新面

全页唯一「写互斥位」是字符串 busy:写操作开始置为操作键(saveRule/savePolicy/saveChannel/saveSilence/incidentAction/enable-{id}/disable-{id}/delRule-{id}/delPol-{id}/testCh-{id}/approve-{id}/deny-{id} 等),结束时在 finally 清空;busy 非空时全页按钮与开关 :disabled="!!busy" 防并发写。

各写操作成功后的刷新面(逐字对应源码):

首次加载已补齐(提交 412e9c48)onMounted 现并行拉取 incidents/policies/history/channels/silences(AlertsPage.vue:1397-1407),切换 Tab 即见存量数据,无需先执行一次写操作。无定时轮询:挂载后仅各写操作刷新对应列表,后端异步触发的新事件单/新历史需刷新页面或重进才能看到;summary 也只在 规则保存/删除 与 事件单处置 后刷新。

5. 后端关联

5.1 API 客户端

action/web/src/api/apolloClient.js:axios 实例 baseURL /apollo-api/v1、timeout 30000ms、请求拦截器对所有请求附加 Authorization: Bearer <token>(token 仅取 apollo_token,不回退 aip_token)。响应拦截器:HTTP 2xx 且 code===0 时把 response.data 解包为业务数据;HTTP 2xx 但 code!==0 拒绝;4xx/5xx 提取 body.message || body.error 并把 message 别名写入 error.response.data.error 后 reject——401 清 token 跳 /apollo/login,403 alert('无权限执行该操作')。页面 catch 统一以 err.response?.data?.message || err.response?.data?.error || err.message || '未知错误' 展示后端错误。

5.2 端点表

以下路径均为相对 baseURL /apollo-api/v1(Vite rewrite 后后端收 /api/v1/...)。项目 id 页面恒用 1。权限点映射与注册行号见 server.go 910~942 行。

方法路径权限页面触发点 / 说明
GET/projects/1/alert-summaryPermAlertRead页顶 summary 五卡
POST/projects/1/alert-rulesPermAlertWrite新建告警规则
GET/projects/1/alert-rulesPermAlertRead规则列表
GET/alert-rules/:idPermAlertRead(后端有,页面未调用)
PUT/alert-rules/:idPermAlertWrite编辑规则
DELETE/alert-rules/:idPermAlertWrite删除规则
POST/alert-rules/:id/enablePermAlertWrite启用规则
POST/alert-rules/:id/disablePermAlertWrite停用规则
GET/projects/1/alert-eventsPermAlertRead(后端有,页面无事件列表 Tab)
GET/projects/1/incidentsPermAlertRead事件单列表(挂载时并行拉取,见 4.8)
POST/incidents/:id/acknowledgePermAlertWrite确认事件单
POST/incidents/:id/investigatePermAlertWrite(后端有,页面无入口)
POST/incidents/:id/resolvePermAlertWrite解决事件单
POST/projects/1/healing-policiesPermAlertWrite新建自愈策略
GET/projects/1/healing-policiesPermAlertRead策略列表
GET/healing-policies/:idPermAlertRead(后端有,页面未调用)
PUT/healing-policies/:idPermAlertWrite编辑策略
DELETE/healing-policies/:idPermAlertWrite删除策略
POST/healing-policies/:id/enablePermAlertExecute启用策略
POST/healing-policies/:id/disablePermAlertExecute停用策略
POST/healing-history/:id/approvePermAlertExecute审批自愈记录
POST/healing-history/:id/denyPermAlertExecute拒绝自愈记录
GET/projects/1/healing-historyPermAlertRead自愈历史(历史按 created_at 倒序返回)
POST/projects/1/notification-channelsPermAlertWrite新建渠道
GET/projects/1/notification-channelsPermAlertRead渠道列表
GET/notification-channels/:idPermAlertRead(后端有,页面未调用)
PUT/notification-channels/:idPermAlertWrite(后端有,页面无编辑入口)
DELETE/notification-channels/:idPermAlertWrite删除渠道
POST/notification-channels/:id/testPermAlertExecute渠道测试
POST/projects/1/silencesPermAlertWrite新建静默
GET/projects/1/silencesPermAlertRead静默列表
DELETE/silences/:idPermAlertWrite删除静默
GET/projects/1/health-checksPermMonitoringRead规则弹窗健康检查下拉(跨模块,monitoring 侧端点)

5.3 响应结构示例

统一 envelope 解包后(code===0 的 data)。alert-summaryGET /projects/1/alert-summary,真实后端形状):


{
  "project_id": 1,
  "rule_count": 3,
  "event_count": 5,
  "incident_count": 2,
  "open_incident_count": 1,
  "healing_total": 4,
  "healing_success": 3
}

字段含义:rule_count 项目内规则总数;event_count 这些规则产生的告警事件总数(firing+resolved);incident_count 事件单总数;open_incident_count 未关闭(status != resolved)事件单数;healing_total 自愈已执行次数(executing/success/failed);healing_success 其中成功(success)次数(后端 alert_handlers.go:1181-1189)。前端映射已对齐(提交 412e9c48):页面 field 别名现覆盖 open_incident_count/healing_total/healing_successAlertsPage.vue:904-906),五张 summary 卡均正常显示;后两张卡为 computed,接口缺键时回退用已加载 history 统计(AlertsPage.vue:663-680)。

告警规则单项GET /projects/1/alert-rules data 数组元素,即 AlertRule):


{
  "id": 1,
  "project_id": 1,
  "name": "web 响应超时告警",
  "trigger_type": "health_check",
  "metric_source": "response_time_ms",
  "health_check_id": 3,
  "condition": { "threshold": { "op": ">", "value": 2000 } },
  "severity": "warning",
  "duration_seconds": 30,
  "cooldown_seconds": 60,
  "notification_channels": ["ops-webhook"],
  "enabled": true,
  "created_at": "2026-09-07T02:00:00+08:00",
  "updated_at": "2026-09-07T03:21:00+08:00"
}

字段说明(AlertRule):trigger_type health_check/event;metric_source health_status/response_time_ms/status_code(event 类型页面存空串);health_check_id 指针字段、未绑定时缺省;condition{health:{status}}{threshold:{op,value}} JSON(缺省则不出现);notification_channels 渠道名数组(缺省则不出现);enabled*bool,nil 视为启用、显式 false 为停用。

事件单单项GET /projects/1/incidents data 数组元素,即 Incident):


{
  "id": 1,
  "project_id": 1,
  "title": "告警规则「web 响应超时告警」触发",
  "severity": "warning",
  "status": "open",
  "source_alert_ids": { "rule_id": 1, "event_ids": [5, 8] },
  "acknowledged_by": "",
  "resolution_note": "",
  "created_at": "2026-09-07T02:01:00+08:00"
}

字段说明:title 由后端拼 告警规则「{规则名}」触发status open/acknowledged/investigating/resolved;source_alert_idsIncidentSource(rule_id + 归并的 event_ids);acknowledged_by 确认人(未确认空串);resolution_note 解决备注(自动关闭为 健康检查恢复,告警自动关闭);resolved_at 指针字段、未解决时缺省。acknowledge 响应也是 Incident——确认后 status 变 acknowledged、acknowledged_by 写当前用户名。

自愈策略单项GET /projects/1/healing-policies data 数组元素,即 SelfHealingPolicy):


{
  "id": 1,
  "project_id": 1,
  "name": "web 自动重启策略",
  "trigger_rule_id": 1,
  "action_type": "restart",
  "action_target": "env-1:web",
  "max_auto_attempts": 3,
  "requires_approval": false,
  "enabled": true,
  "created_at": "2026-09-07T02:00:00+08:00",
  "updated_at": "2026-09-07T03:21:00+08:00"
}

自愈历史单项GET /projects/1/healing-history data 数组元素,即 HealingHistoryresult 缺省则不出现):


{
  "id": 1,
  "incident_id": 1,
  "policy_id": 1,
  "action_type": "restart",
  "target": "env-1:web",
  "status": "pending_approval",
  "created_at": "2026-09-07T02:02:00+08:00"
}

状态取值 pending_approval/approved/executing/success/failed/denied。result 承载审计与执行详情:审批路径写入 {approved_by, approved_at}(拒绝写 {denied_by, denied_at}),执行完成合并执行器结果并保留审批字段mergeResult 既有键保留、新键覆盖),例如:


{
  "id": 1,
  "incident_id": 1,
  "policy_id": 1,
  "action_type": "restart",
  "target": "env-1:web",
  "status": "success",
  "result": {
    "approved_by": "alice",
    "approved_at": "2026-09-07T02:02:10+08:00",
    "action": "restart",
    "target": "env-1:web",
    "task_id": 42
  },
  "created_at": "2026-09-07T02:02:00+08:00"
}

通知渠道单项GET /projects/1/notification-channels data 数组元素):


{
  "id": 1,
  "project_id": 1,
  "name": "ops-webhook",
  "type": "webhook",
  "config": { "url": "https://hooks.example.com/xxx" },
  "enabled": true,
  "created_at": "2026-09-07T02:00:00+08:00"
}

静默单项GET /projects/1/silences data 数组元素):


{
  "id": 1,
  "project_id": 1,
  "name": "发布窗口静默",
  "starts_at": "2026-09-07T10:00:00+08:00",
  "ends_at": "2026-09-07T22:00:00+08:00",
  "matcher": { "severity": "critical" },
  "created_by": "admin",
  "created_at": "2026-09-07T09:00:00+08:00"
}

渠道测试:webhook 成功 {channel_id, type:"webhook", test:true, status_code:200};非 webhook 占位成功 {channel_id, type, test:true, note:"该渠道类型为占位实现,仅记录日志"};失败 envelope 消息有 解析 webhook 渠道配置失败: ... / webhook 渠道缺少 url 配置 / Webhook 测试请求失败: ... / Webhook 测试返回非 2xx 状态码: ...

错误示例(envelope fail):删除/审批不存在的记录返回 xxx not found;对已解决事件单确认返回 400、incident {id} 已解决,不可确认;对非待审批记录审批返回 400、healing history {id} 状态非待审批(当前 {status})

5.4 关键机制

评估引擎(EvaluateHealthCheck)。后端 alert 包 RuleEngineScheduler 周期驱动(scheduler.go:interval<=0 时默认 15s,server 以显式 interval 调用 Start)。每次对一条健康检查评估(EvaluateHealthCheck):① 直查 health_check_results 最新一条(无结果直接返回,不评估);② 取绑定该检查的 enabled=true 规则;③ 逐规则先做静默判定IsSilenced(ruleID, severity),命中活动静默即 continue 跳过,日志 告警被静默,跳过);④ 条件匹配 matchesCondition——condition.health.status 精确等于结果状态才算命中;condition.thresholdmetric_source(response_time_ms/status_code)按 op 用 compareValue 比较(支持 > >= < <= == = !=);两者都没有时兜底「非 healthy 即告警」;⑤ 不命中走恢复ResolveFiringByRule 置该规则 firing 事件 resolved,有清理到(n>0)再 autoCloseIncident——把该规则未关闭事件单按 健康检查恢复,告警自动关闭 备注关单;⑥ 命中再经 canFire 防抖冷却:同规则最近事件仍 firing 不重复触发,否则以 max(duration,cooldown) 秒内不重复;⑦ 通过则写一条 firing 事件(Source 带健康检查结果快照)→ OpenIncident 归并 → Notify 通知 → MaybeHeal 自愈。EvaluateAll 遍历所有 enabled 且 trigger_type=health_check 规则的检查去重评估(event 类型规则不在本轮评估范围)。

事件单归并与生命周期OpenIncident:按规则查现有未关闭事件单(FindOpenByRule)——存在则只把新事件 id 追加进 source_alert_ids.event_idsmaxSeverity 抬升级别(critical>warning>info),日志 事件单归并告警事件;不存在才新建,title 告警规则「%s」触发。状态机 open→acknowledged→investigating→resolved(TAD-09)。Acknowledge:已 resolved 拒绝(incident %d 已解决,不可确认),否则置 acknowledged 并写 AcknowledgedBy=当前用户名——后端不读请求 body,页面确认弹窗填的 note 不会落库。Resolve:幂等(已解决直接返回);同事务内把事件单置 resolved、写 ResolutionNote=noteResolvedAt,并闭合 source_alert_ids 里仍 firing 的源事件(置 resolved 留 resolved_at),已解决事件单人工收口后不再与 firing 事件并存(O-048 语义)。Investigate:open/acknowledged 可转 investigating,已解决拒绝、已 investigating 幂等;页面没有 investigate 入口

通知(Notifier)。规则触发事件后 Notify 按规则的 notification_channels 渠道名数组找启用的渠道:webhook 类型真实 http.Post(10s 超时客户端),payload 形如 {event_id, rule_id, severity, status, source, fired_at, channel, sent_at};email/dingtalk/wecom 仅日志占位(通知渠道(占位)已记录)。发送失败仅记日志,不影响事件单与自愈主链路。

自愈管线(SelfHealing)MaybeHeal 在事件单打开后触发:取绑定该规则且 enabled 的策略;HasActive 查「同一事件单+策略」是否已有进行中记录(防重复);canAttempt 统计该策略 success 历史数须 < MaxAutoAttempts(0=不限制),超限跳过并 logger.Warn;新建 HealingHistory——RequiresApproval=false 直接 execute(初态 approved),true 初态 pending_approval 等审批。execute:置 executing → 调 server 注入的 apolloActionExecutor(restart/scale_up/scale_down 写 agent_task 由节点 Agent 落地、rollback 走 GitOps 回滚、clean_disk 为模拟清理)→ 成功置 success、失败置 failed,结果经 mergeResult 合并(保留既有审计键,避免审批字段被执行结果覆盖)。Approve/Deny:仅 pending_approval 可操作(否则 400 状态非待审批(当前 {status}));approve 先写 result.approved_by/approved_at 再立即执行;deny 写 denied_by/denied_at 置终态 denied、不再执行。

静默匹配(SilenceManager)IsSilenced 取当前活动窗口(ListActive(now),starts_at<=now<ends_at)内全部静默逐条 matchSilence。matcher 仅识别两键:rule_id(与规则 id 数值比较,浮点/uint 均兼容)与 severity(字符串相等);空对象 {} 匹配全部;其它键静默忽略。创建校验:名称空(静默名称不能为空)、结束须晚于开始(静默结束时间须晚于开始时间);CreatedBy 为空兜底 system

调度器节奏:alert Scheduler 默认 15s 驱动 EvaluateAll(评估/恢复/自愈联动都在评估 tick 的调用链上完成,审批执行是另一条即时路径);监控侧 monitoring.Scheduler 以 30s 对健康检查各探测一轮。因此健康检查结果至少落后探测一个周期,规则触发评估又落后结果一个周期,演示时留出约 15~45s 观察窗。

6. 权限与安全

7. 常见问题与排错

以下现象均由 AlertsPage.vue 的 catch 分支、后端 handler/service 代码与既有测试归纳,可溯源复现;此前确属前端缺陷者已在提交 412e9c48 修复(见各条与 8 章)。

  1. 页顶「未处理事件单」「自愈执行数」「自愈成功数」三张卡(历史现象,已修复):旧版前端 field 别名未覆盖后端单数键 open_incident_count,且当时后端无自愈计数键。已修复(提交 412e9c48):后端 summary 现返回 open_incident_count/healing_total/healing_successalert_handlers.go:1181-1189),前端别名同步对齐(AlertsPage.vue:904-906),并通过 computed 在缺键时回退 history 统计(AlertsPage.vue:663-680),五卡均正常显示。

  2. 事件单 Tab 显示「暂无事件单,一切正常。」(历史现象,已修复):旧版 incidents 数据只在「确认/解决写操作成功后」才 fetchIncidents(),首次加载被结构性跳过。已修复(提交 412e9c48)onMounted 现并行拉取 incidents(AlertsPage.vue:1401),进入 Tab 即加载;若仍为空说明后端该项目确实无事件单,可用 GET /apollo-api/v1/projects/1/incidents 核对。

  3. 切到「自愈策略」Tab 时控制台报错/该卡渲染异常(历史现象,已修复):旧版标题模板引用未声明的 pendingHistory已修复(提交 412e9c48):待审批计数改为 pendingHistoryCount 计算属性(AlertsPage.vue:663history 过滤 pending_approval,模板 :248 引用),进入本 Tab 不再抛渲染异常。

  4. 策略/历史/渠道/静默 Tab 首次进入显示空态(历史现象,已修复):旧版这些列表只在各自写操作成功后 fetch。已修复(提交 412e9c48)onMounted 已并行拉取 policies/history/channels/silences(AlertsPage.vue:1402-1405),进入 Tab 即见存量数据。

  5. 新建告警规则弹窗的健康检查下拉为空,建了 health_check 规则却从不触发:原因是 fetchHealthChecks() 失败被静默降级为空数组(成功才填下拉);或监控侧确实没有健康检查。health_check 类型且 health_check_id 为空时,EvaluateAll 会跳过该规则(其 HealthCheckID 为 nil/0 不参与评估),规则形同虚设。处理:先到「监控可观测」页确认存在且启用的健康检查、检查 GET /projects/1/health-checks 是否 200(需 PermMonitoringRead);规则弹窗里把下拉选到具体检查再保存。

  6. 阈值比较规则从不触发或条件摘要异常:原因是 condition.value 空时 Number('')=0(或 NaN 入 JSON 被拒),response_time_ms > 0 之类条件一旦结果耗时为 0 便永不命中;或编辑老规则时后端存的 op(=/!=)不在 UI 下拉选项里。处理:新建时填具体阈值;老规则若 op 不在五选项中,先重选一次比较符再保存。另确认 metric_source 与指标语义一致(health_status 只走健康匹配才有意义)。

  7. 渠道「测试」提示失败:webhook 会真实 POST(10s 超时),后端错误 Webhook 测试请求失败: ...(URL 不可达/DNS/超时)、Webhook 测试返回非 2xx 状态码: ...(对端拒绝)、解析 webhook 渠道配置失败: .../webhook 渠道缺少 url 配置(config.url 缺失)。email/dingtalk/wecom 恒返回占位成功 note。处理:核对目标 URL 可达性与对端鉴权;URL 填错时到「监控」无关——检查渠道行的 Webhook URL 列展示值。

  8. 事件单「确认」时填的处置说明没效果:原因是确认接口 handleAcknowledgeIncident 只把当前用户名传给 Acknowledge,不解析请求体——note 只在「解决」时经 Resolve(note) 写入 resolution_note。处理:需要留痕的说明请在「解决」弹窗里填;确认只用于认领并记录确认人(由后端代码判断,属行为差异非前端 bug,见 8 边界)。

  9. 新建静默提示「matcher 不是合法 JSON」或后端报「静默结束时间须晚于开始时间」:前端先拦 JSON 语法与时间序,后端再兜底校验。处理:matcher 用合法 JSON 对象(如 {"severity":"critical"});结束时间选在开始时间之后;注意前端 new Date(datetime-local).toISOString() 会把本地时间按 UTC 序列化,跨时区核对窗口会偏移(同见 8 时间展示项)。

8. 已知缺陷与边界

缺陷/边界说明
summary 别名不匹配(已修复)已修复(提交 412e9c48):后端 summary 增补自愈计数键返回 open_incident_count/healing_total/healing_successalert_handlers.go:1181-1189),前端 field 别名同步对齐并新增「自愈成功数」卡(AlertsPage.vue:904-906),五卡正常显示
Tab 内容懒加载缺失(已修复)已修复(提交 412e9c48)onMounted 并行拉取 incidents/policies/history/channels/silences(AlertsPage.vue:1397-1407),事件单 Tab 不再结构性恒空
pendingHistory 未定义(已修复)已修复(提交 412e9c48):改用 pendingHistoryCount 计算属性(AlertsPage.vue:663history 过滤 pending_approval,模板 :248 引用),不再触发渲染异常
确认弹窗 note 无效(现实边界)后端 handleAcknowledgeIncident 只把当前用户名传给 Acknowledge、不解析请求体(server/alert_handlers.go:391-407),确认时填的 note 不落库(仅用户名入 acknowledged_by);note 只在「解决」时经 Resolve(note) 写入 resolution_notealert_handlers.go:411-434)。前端确认弹窗仍提供 note 输入框,属后端契约边界——需后端按 note 落库才能收口
项目 id 硬编码PROJECT_ID = 1 常量,注释标明「后续可改为从 URL 参数 /project_id 读取」;所有 /projects/1/... 均指向默认项目
阈值 op 选项不全后端 compareValue 支持 > >= < <= == = !=,UI 下拉仅提供前五(缺 =!=);含 =/!= 的存量规则在编辑弹窗里下拉显示空
event 触发类型缺后端消费规则可选 trigger_type=event,但评估引擎只遍历 health_check 规则;event 类型规则当前无触发源,页面也造不出事件(边界,非缺陷)
无事件列表视图GET /projects/1/alert-events 存在,页面「触发事件数」只有计数卡,没有事件明细 Tab;事件明细只能从事件单的 source_alert_ids 反查
无 investigate 入口后端支持 open→investigating(含审计),页面事件单操作仅确认/解决
渠道与规则引用软耦合规则按渠道引用通知渠道,渠道被删后引用悬空,发送时找不到同名渠道即跳过,无前端提示
自愈执行的真实性restart/scale_* 落地为 agent_task(需节点 Agent 执行)、rollback 走 GitOps、clean_disk 为模拟;演示环境无 Agent 时执行结果以 executor 返回为准,页面不做二次核对
approve 无二次确认审批即真实触发动作,页面未做 confirm(deny 有 confirm),误点会立即执行
时间展示为 UTCformatTime 对 RFC3339 去 T/Z 截前 19 位展示、不转本地时区;静默窗口 datetime-local→ISO 序列化同样是 UTC 视角,跨时区有偏差
各 Tab 无轮询/刷新onMounted 已并行加载各列表(AlertsPage.vue:1397-1407),此后仅写操作刷新对应列表;页面无定时轮询,长时间停留不会自动看到后端异步触发的新事件单/新历史(自愈/恢复是后端异步动作),需刷新页面或重进

附录 A:速查——页面文案与关键常量清单

场景源码取值/文案(逐字)
页面标题Apollo 告警与自愈
顶部说明告警规则绑定健康检查(或事件),触发后归并生成事件单;自愈策略按规则自动执行(restart / rollback / scale_up / scale_down / clean_disk),需要审批的策略经人工审批后执行(TAD-09)。
summary 卡标签告警规则数 / 触发事件数 / 未处理事件单 / 自愈执行数
Tab 标签告警规则 / 事件单 / 自愈策略 / 通知渠道 / 静默
规则列表列头ID / 名称 / 级别 / 触发类型 / 指标来源 / 条件 / 通知渠道 / 启用 / 操作
规则空态暂无告警规则,点击"新建告警规则"添加(项目 #{{ PROJECT_ID }})。
事件单空态暂无事件单,一切正常。
策略空态暂无自愈策略,点击"新建自愈策略"添加。
历史空态暂无自愈历史。
渠道空态暂无通知渠道,点击"新建通知渠道"添加。
静默空态暂无静默,点击"新建静默"添加。
级别枚举critical(严重) / warning(警告) / info(提示)
触发类型枚举health_check(健康检查) / event(事件)
动作类型枚举restart(重启) / rollback(回滚) / scale_up(扩容) / scale_down(缩容) / clean_disk(清理磁盘)
渠道类型枚举webhook / email / dingtalk(钉钉) / wecom(企微)
规则名称必填告警规则名称(name)必填
策略必填提示自愈策略名称与触发规则(trigger_rule_id)必填
渠道名称必填通知渠道名称(name)必填
静默校验静默名称与时间窗(starts_at/ends_at)必填 / 结束时间必须晚于开始时间 / matcher 不是合法 JSON:{e.message}
启停提示告警规则 #{id} 已启用/已停用 · 自愈策略 #{id} 已启用/已停用
删除确认确定删除告警规则 "{name}"(#id)吗? · 确定删除自愈策略 "{name}"(#id)吗? · 确定删除通知渠道 "{name}"(#id)吗? · 确定删除静默 "{name}"(#id)吗?
拒绝确认确定拒绝自愈记录 #{id} 吗?将不再执行该动作。
创建成功提示告警规则创建成功(id={id}) · 自愈策略创建成功(id={id}) · 通知渠道创建成功(id={id}) · 静默创建成功(id={id})
事件单处置成功事件单 #{id} 已确认/已解决(状态:{status})
渠道测试成功通知渠道 "{name}" 测试:{msg}(ok=success/ok/sent 任一 true)
自动关单备注健康检查恢复,告警自动关闭
事件单标题模板告警规则「{规则名}」触发
默认常量interval=15s(alert 评估)、cooldown/duration 默认 0、max_auto_attempts 默认 1、health_check_id 默认下拉第一项
阈值 opUI > >= < <= ==(后端另支持 = !=