feat(alerts): 内置规则默认启用并绑定默认通道,开箱即用
CI / Backend (go vet + test) (push) Canceled after 0s
CI / Frontend (lint + build + test) (push) Canceled after 0s

- 新种规则 Enabled: true;启动时执行 SeedAlertRules(此前仅部署成功调用,存量环境拿不到升级)
- 存量一次性迁移:内置名单内且从未关联通道的规则补绑默认通道并启用;用户已自配通道的不动
- 管理员只需给「默认告警」通道填 Webhook 并启用;通道未就绪时命中只记发送历史(failed+原因),不影响规则评估
This commit is contained in:
opsx committed 2026-10-29 13:14:05 +08:00
1 parent c08190458f
commit c5739d1a06
2 files changed
+27 -8

No files matched your search

+2
View File
@@ -138,6 +138,8 @@ func main() {
log.Println("Seeding default data...")
seed.Seed()
// 补齐/升级内置告警规则(幂等):启动即执行,存量环境也能拿到「默认启用+绑默认通道」
seed.SeedAlertRules()
// 安全迁移:历史明文 kubeconfig → 加密存储,并清理明文文件
services.MigrateClusterKubeconfigs()
+25 -8
View File
@@ -4,7 +4,8 @@ package seed
// 致命类(出现即报):FATAL / panic / OutOfMemoryError / StackOverflowError
// 突增类(超阈值才报):应用 error 过多 / ingress-nginx 4xx / 5xx
// 绑定数据源:部署成功自动注册的 LogSource(managed)。
// 规则默认不启用(通知通道由管理员后期在设置页配置后再开启),ChannelIDs 留空。
// 规则默认启用并绑定「默认告警」通道:管理员只需在设置页给默认通道填好 Webhook 并启用即可收告警;
// 通道未就绪时命中只会把失败原因写进发送历史,不影响规则评估。
import (
"slices"
"time"
@@ -96,17 +97,34 @@ var legacyInfraRules = []string{"Kubernetes 节点 NotReady", "容器 OOMKilled"
// SeedAlertRules 补齐内置告警规则(幂等;公开给启动与部署成功两处调用)
func SeedAlertRules() {
// 先清掉历史遗留的基础设施类规则(只删名字精确匹配的这两条)
// 先清掉历史遗留的基础设施类规则,并把内置规则升级为「默认启用 + 绑默认通道」
// (仅处理从未关联过通道的规则;用户已自行配置过通道的规则不动)
db := repository.GetDB()
defaultChannelID := ensurePlaceholderChannel(db)
builtinNames := make(map[string]bool, len(builtinRules))
for _, r := range builtinRules {
builtinNames[r.name] = true
}
db.Lock()
kept := db.AlertRules[:0]
changed := false
for _, rule := range db.AlertRules {
if !slices.Contains(legacyInfraRules, rule.Name) {
kept = append(kept, rule)
if slices.Contains(legacyInfraRules, rule.Name) {
changed = true
continue
}
if builtinNames[rule.Name] && len(rule.ChannelIDs) == 0 {
rule.ChannelIDs = channelIDsFor(defaultChannelID)
if !rule.Enabled {
rule.Enabled = true
rule.UpdatedAt = time.Now()
}
changed = true
}
kept = append(kept, rule)
}
if len(kept) != len(db.AlertRules) {
db.AlertRules = kept
db.AlertRules = kept
if changed {
db.RequestSave()
}
db.Unlock()
@@ -141,7 +159,6 @@ func SeedAlertRules() {
// - 管理员填好 Webhook 再启用即可,不必逐条给规则关联通道
// - 之所以不放"已启用 + 空地址":那样每次命中都会投递失败刷屏
// 这里直接操作 db 而不调 services,避免 seed ↔ services 的包循环依赖。
defaultChannelID := ensurePlaceholderChannel(db)
newID := db.NextID("alertRules")
db.Lock()
@@ -154,7 +171,7 @@ func SeedAlertRules() {
db.AlertRules = append(db.AlertRules, models.AlertRule{
ID: newID, Name: r.name, SourceID: target.id,
Query: r.query, WindowMin: r.windowMin, Threshold: r.threshold,
Enabled: false, CooldownMin: r.cooldown,
Enabled: true, CooldownMin: r.cooldown,
ChannelIDs: channelIDsFor(defaultChannelID),
CreatedAt: time.Now(), UpdatedAt: time.Now(),
})