diff --git a/src/bean/entity/alert_rules.go b/src/bean/entity/alert_rules.go index 995c46e1386e1d8ba48ac57e18a4c45f1bfacbf4..ef3f6f66c3e82510fe084c7459ad5c9c3a8d61a6 100644 --- a/src/bean/entity/alert_rules.go +++ b/src/bean/entity/alert_rules.go @@ -36,7 +36,7 @@ type RulesAlertRange struct { } type AlertCondition struct { - ThresholdsMin int `json:"thresholds_min" form:"thresholds_min" binding:"required,lt=ThresholdsMax"` + ThresholdsMin int `json:"thresholds_min" form:"thresholds_min" binding:"required,ltfield=ThresholdsMax"` ThresholdsMax int `json:"thresholds_max" form:"thresholds_max" binding:"required"` RiskLevel int `json:"risk_level" form:"risk_level" binding:"required,oneof=1 2 3 4"` } diff --git a/src/bean/vo/request/alert_rules.go b/src/bean/vo/request/alert_rules.go index 2b624fea143605befbbf7a26a7b4991db82b2985..5ae87424236f0a698a1410c1a1e58310f18b1a30 100644 --- a/src/bean/vo/request/alert_rules.go +++ b/src/bean/vo/request/alert_rules.go @@ -13,14 +13,14 @@ type AddAlertRules struct { MetricConfigId string `json:"metric_config_id" form:"'metric_config_id'" binding:"required_if=DetectionType 1"` // 预警指标id MetricConfigName string `json:"metric_config_name" form:"metric_config_name" binding:"required_if=DetectionType 2"` // 预警指标名称(映射entity.MetricConfig.MetricName) Expr string `json:"expr" form:"expr" binding:"required_if=DetectionType 2"` // 指标表达式(PromQL语句) - AlertCondition []entity.AlertCondition `json:"alert_condition" form:"alert_condition" binding:"required"` // 预警规则 字典值 + AlertCondition []entity.AlertCondition `json:"alert_condition" form:"alert_condition" binding:"required,dive"` // 预警规则 字典值 AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type" binding:"required_if=DetectionType 2"` // 预警规则类型 关联字典表 AlertRange []entity.RulesAlertRange `json:"alert_range" form:"alert_range" binding:"required,dive"` // 预警范围 字典值 Duration int `json:"duration" form:"duration" binding:"gte=0"` // 持续时间 DurationUnit string `json:"duration_unit" form:"duration_unit" binding:"oneof=s m h"` // 持续时间单位 s m h CheckPeriod int `json:"check_period" form:"check_period" binding:"oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟 NotifyMethod []string `json:"notify_method" form:"notify_method" binding:"max=2,dive,oneof=dingtalk sms"` // 预警通知方式 dingtalk sms - NotifyRecipients []entity.NotifyRecipients `json:"notify_recipients" form:"notify_recipients" binding:"dive"` // 预警推送用户 + NotifyRecipients []entity.NotifyRecipients `json:"notify_recipients" form:"notify_recipients" binding:"required,dive"` // 预警推送用户 NotifyPushCount int `json:"notify_push_count" form:"notify_push_count" binding:"gte=1"` // 消息推送次数 NotifyPushFrequency int `json:"notify_push_frequency" form:"notify_push_frequency" binding:"gte=1"` // 消息推送频率 分钟 IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"oneof=1 2"` // 是否开启 1:是 2:否 diff --git a/src/service/alert_rules.go b/src/service/alert_rules.go index da64e4edfe337372bda1fd8474a494f2f6a54735..2ce25d3afc74c0364feba8ad0e5511c864ebba59 100644 --- a/src/service/alert_rules.go +++ b/src/service/alert_rules.go @@ -18,7 +18,7 @@ type AlertRulesSvc struct { User entity.SystemUserInfo } -func (a *AlertRulesSvc) Add(req request.AddAlertRules) error { +func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) { db, err := client.GetDbClient() if err != nil { err = resp.DbConnectError.WithError(err) @@ -39,20 +39,10 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) error { data.NotifyRecipients = util.ConvertToString(req.NotifyRecipients) switch req.DetectionType { case 1: - // TODO 暂时不能做事务,需要先插入数据,再进行查询 _, err = db.Insert(&data) if err != nil { return err } - - var item response.AlertRulesItem - item, err = a.GetDataById(request.DetailAlertRules{Id: data.Id}) - - // TODO 1.插入数据到 prometheus.yml --> rule_files - prSvc := PrometheusRuleSvc{User: a.User} - prSvc.Create(item) - _ = item - case 2: // 自定义 _, err = db.Transaction(func(session *xorm.Session) (interface{}, error) { // 添加自定义分类 @@ -103,7 +93,17 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) error { } } - // TODO 告警规则添加到普罗米修斯表 + var item response.AlertRulesItem + item, err = a.GetDataById(request.DetailAlertRules{Id: data.Id}) // 查询完整数据 + prSvc := PrometheusRuleSvc{User: a.User} // 插入数据到 prometheus.yml --> rule_files + err = prSvc.Create(item) + if err != nil { + _, err = db.Delete(&data) + if err != nil { + return err + } + return + } return nil } diff --git a/src/service/prometheusrule.go b/src/service/prometheusrule.go index cac5e77ba7ce3059dcb987e9608c205ae848ef6a..1b8b8563108d72ee196d4cb1e7f65b1e2272b679 100644 --- a/src/service/prometheusrule.go +++ b/src/service/prometheusrule.go @@ -9,7 +9,9 @@ import ( "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/service/k8s" + "go.uber.org/zap" "k8s.io/apimachinery/pkg/util/intstr" + "log" "strings" ) @@ -17,10 +19,7 @@ type PrometheusRuleSvc struct { User entity.SystemUserInfo } -func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) { - header := make(map[string]string) - header["Authorization"] = "Bearer " + conf.Options.KubernetesToken - svc := k8s.PrometheusRule{Header: header} +func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) { pr := monitoringv1.PrometheusRule{} prometheusRuleName := k8s.GetPrometheusRuleName(data.Id) pr.Name = prometheusRuleName @@ -31,12 +30,9 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) { groupInterval := monitoringv1.Duration(fmt.Sprintf("%d%s", data.CheckPeriod, "m")) group.Interval = &groupInterval ruleFor := monitoringv1.Duration(fmt.Sprintf("%d%s", data.Duration, data.DurationUnit)) - - // [{"variable_name":"$pod$","metric_name":"http_requests_total","metric_label":"pod","chinese_name":"demoString","is_required":true,"is_linked":true,"value":"LeaseGrant","compare":"="}] - // [{"thresholds_max":100,"thresholds_min":0,"risk_level":4}] group.Name = k8s.GetPrometheusRuleGroupName(data.MetricConfigId, string(*group.Interval)) for _, v := range data.AlertRange { - item := fmt.Sprintf("%s%s%s", v.MetricLabel, v.Compare, v.Value) // pod=LeaseGrant + item := fmt.Sprintf(`%s%s"%s"`, v.MetricLabel, v.Compare, v.Value) // http_requests_total{method="GET",pod="LeaseGrant"} data.Expr = strings.ReplaceAll(data.Expr, v.VariableName, item) } for _, v := range data.AlertCondition { @@ -52,13 +48,24 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) { }, Annotations: map[string]string{ "value": "{{ $value }}", - "summary": "概述", - "description": "描述", + "summary": fmt.Sprintf("分组名:%s, 检查周期:%s, 持续时间:%s", group.Name, string(groupInterval), string(ruleFor)), + "description": "", }, } expr := fmt.Sprintf("%d <= %s <=%d", v.ThresholdsMin, data.Expr, v.ThresholdsMax) rule.Expr = intstr.FromString(expr) group.Rules = append(group.Rules, rule) } - _ = svc + pr.Spec.Groups = append(pr.Spec.Groups, group) + header := make(map[string]string) + header["Authorization"] = "Bearer " + conf.Options.KubernetesToken + prSvc := k8s.PrometheusRule{Header: header} + conf.Logger.Info("创建规则", zap.Any("pr", pr)) + err = prSvc.Create(&pr) + if err != nil { + log.Println("添加失败" + err.Error()) + } else { + log.Println("添加成功") + } + return }