From e15bdbce92ff45a7d7bfeb441e93b96dc441cd33 Mon Sep 17 00:00:00 2001 From: ning <710leo@gmail.com> Date: Wed, 6 Aug 2025 11:09:53 +0800 Subject: [PATCH] refactor: optimize import prom alert rule --- center/router/router_alert_rule.go | 45 ++++++++++++++++++++++++++---- models/prom_alert_rule.go | 4 +-- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/center/router/router_alert_rule.go b/center/router/router_alert_rule.go index 4ded0044..b8276201 100644 --- a/center/router/router_alert_rule.go +++ b/center/router/router_alert_rule.go @@ -308,19 +308,52 @@ func (rt *Router) alertRuleAddByImportPromRule(c *gin.Context) { var f promRuleForm ginx.Dangerous(c.BindJSON(&f)) + // 首先尝试解析带 groups 的格式 var pr struct { Groups []models.PromRuleGroup `yaml:"groups"` } err := yaml.Unmarshal([]byte(f.Payload), &pr) - if err != nil { - ginx.Bomb(http.StatusBadRequest, "invalid yaml format, please use the example format. err: %v", err) - } - if len(pr.Groups) == 0 { - ginx.Bomb(http.StatusBadRequest, "input yaml is empty") + var groups []models.PromRuleGroup + + if err != nil || len(pr.Groups) == 0 { + // 如果解析失败或没有 groups,尝试解析规则数组格式 + var rules []models.PromRule + err = yaml.Unmarshal([]byte(f.Payload), &rules) + if err != nil { + // 最后尝试解析单个规则格式 + var singleRule models.PromRule + err = yaml.Unmarshal([]byte(f.Payload), &singleRule) + if err != nil { + ginx.Bomb(http.StatusBadRequest, "invalid yaml format. err: %v", err) + } + + // 验证单个规则是否有效 + if singleRule.Alert == "" && singleRule.Record == "" { + ginx.Bomb(http.StatusBadRequest, "input yaml is empty or invalid") + } + + rules = []models.PromRule{singleRule} + } + + // 验证规则数组是否为空 + if len(rules) == 0 { + ginx.Bomb(http.StatusBadRequest, "input yaml contains no rules") + } + + // 将规则数组包装成 group + groups = []models.PromRuleGroup{ + { + Name: "imported_rules", + Rules: rules, + }, + } + } else { + // 使用已解析的 groups + groups = pr.Groups } - lst := models.DealPromGroup(pr.Groups, f.DatasourceQueries, f.Disabled) + lst := models.DealPromGroup(groups, f.DatasourceQueries, f.Disabled) username := c.MustGet("username").(string) bgid := ginx.UrlParamInt64(c, "id") ginx.NewRender(c).Data(rt.alertRuleAdd(lst, username, bgid, c.GetHeader("X-Language")), nil) diff --git a/models/prom_alert_rule.go b/models/prom_alert_rule.go index 12fdf4a4..b7f4f5e0 100644 --- a/models/prom_alert_rule.go +++ b/models/prom_alert_rule.go @@ -67,7 +67,7 @@ func ConvertAlert(rule PromRule, interval string, datasouceQueries []DatasourceQ Disabled: disabled, PromForDuration: convertInterval(rule.For), PromQl: rule.Expr, - PromEvalInterval: convertInterval(interval), + CronPattern: fmt.Sprintf("@every %ds", convertInterval(interval)), EnableInBG: AlertRuleEnableInGlobalBG, NotifyRecovered: AlertRuleNotifyRecovered, NotifyRepeatStep: AlertRuleNotifyRepeatStep60Min, @@ -88,7 +88,7 @@ func DealPromGroup(promRule []PromRuleGroup, dataSourceQueries []DatasourceQuery for _, group := range promRule { interval := group.Interval if interval == "" { - interval = "15s" + interval = "60s" } for _, rule := range group.Rules { if rule.Alert != "" {