package service import ( "errors" "github.com/google/uuid" "github.com/jinzhu/copier" json "github.com/json-iterator/go" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/response" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/util" "xorm.io/xorm" ) type AlertRulesSvc struct { User entity.SystemUserInfo } func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) { db, err := client.GetDbClient() if err != nil { err = resp.DbConnectError.WithError(err) return err } now := jsontime.Now() data := entity.AlertRules{ Id: uuid.New().String(), CreatedBy: a.User.SystemAccount, CreatedAt: now, UpdatedBy: a.User.SystemAccount, UpdatedAt: now, } _ = copier.Copy(&data, &req) data.AlertCondition = util.ConvertToString(req.AlertCondition) data.AlertRange = util.ConvertToString(req.AlertRange) data.NotifyMethod = util.ConvertToString(req.NotifyMethod) data.NotifyRecipients = util.ConvertToString(req.NotifyRecipients) switch req.DetectionType { case 1: _, err = db.Insert(&data) if err != nil { return err } case 2: // 自定义 _, err = db.Transaction(func(session *xorm.Session) (interface{}, error) { // 添加自定义分类 var ( classParentId int classId int addMetricConfig request.AddMetricConfig metricConfigId string ) alertClassSvc := AlertClassSvc{User: a.User} classParentId, err = alertClassSvc.Add(session, request.AddAlertClass{ ClassName: req.ClassParentName, SortOrder: -1, SourceFrom: 2, }) if err != nil { return nil, err } classId, err = alertClassSvc.Add(session, request.AddAlertClass{ ClassName: req.ClassName, ParentId: classParentId, SortOrder: -1, SourceFrom: 2, }) if err != nil { return nil, err } data.ClassId = classId // 添加指标配置 metricConfigSvc := MetricConfigSvc{User: a.User} _ = copier.Copy(&addMetricConfig, &req) addMetricConfig.SourceFrom = 2 addMetricConfig.MetricName = req.MetricConfigName metricConfigId, err = metricConfigSvc.Add(session, addMetricConfig) if err != nil { return nil, err } data.MetricConfigId = metricConfigId // 添加预警规则配置 _, err = session.Insert(&data) return nil, err }) if err != nil { return err } } 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 } func (a *AlertRulesSvc) Update(req request.UpdateAlertRules) error { db, err := client.GetDbClient() if err != nil { err = resp.DbConnectError.WithError(err) return err } now := jsontime.Now() data := entity.AlertRules{ UpdatedBy: a.User.SystemAccount, UpdatedAt: now, } _ = copier.Copy(&data, &req) data.AlertCondition = util.ConvertToString(req.AlertCondition) data.AlertRange = util.ConvertToString(req.AlertRange) data.NotifyMethod = util.ConvertToString(req.NotifyMethod) data.NotifyRecipients = util.ConvertToString(req.NotifyRecipients) session := db.NewSession() defer session.Close() var dbAlertRules entity.AlertRules _, err = session.Table(data.TableName()).ID(data.Id).Get(&dbAlertRules) if err != nil { return err } switch req.DetectionType { case 1: _, err = db.ID(data.Id).Update(&data) if err != nil { return err } case 2: // 自定义 _, err = db.Transaction(func(session *xorm.Session) (interface{}, error) { // 更新自定义分类 var ( updateMetricConfig request.UpdateMetricConfig alertClassItem response.AlertClassItem ) alertClassSvc := AlertClassSvc{User: a.User} alertClassItem, err = alertClassSvc.GetDataById(request.DetailAlertClass{ClassId: dbAlertRules.ClassId}) if err != nil { return nil, err } err = alertClassSvc.Update(session, request.UpdateAlertClass{ ClassId: dbAlertRules.ClassId, ClassName: req.ClassName, }) if err != nil { return nil, err } err = alertClassSvc.Update(session, request.UpdateAlertClass{ ClassId: alertClassItem.ParentId, ClassName: req.ClassParentName, }) if err != nil { return nil, err } // 更新指标配置 metricConfigSvc := MetricConfigSvc{User: a.User} _ = copier.Copy(&updateMetricConfig, &req) updateMetricConfig.SourceFrom = 2 updateMetricConfig.Id = dbAlertRules.MetricConfigId err = metricConfigSvc.Update(session, updateMetricConfig) if err != nil { return nil, err } // 更新预警规则配置 _, err = session.ID(data.Id).Update(&data) return nil, err }) if err != nil { return err } } return nil } func (a *AlertRulesSvc) UpdateIsEnabled(req request.UpdateIsEnabledAlertRules) error { db, err := client.GetDbClient() if err != nil { err = resp.DbConnectError.WithError(err) return err } now := jsontime.Now() data := entity.AlertRules{ Id: req.Id, IsEnabled: req.IsEnabled, UpdatedBy: a.User.SystemAccount, UpdatedAt: now, } session := db.NewSession() defer session.Close() _, err = session.Table(data.TableName()).Cols("is_enabled,updated_by,updated_at").Where("id = ?", req.Id).Update(&data) return err } func (a *AlertRulesSvc) GetDataById(req request.DetailAlertRules) (resp response.AlertRulesItem, err error) { list, err := a.List(request.ListAlertRules{Id: req.Id}) if err != nil { return } if len(list.List) >= 1 { resp = list.List[0] } return } func (a *AlertRulesSvc) List(req request.ListAlertRules) (resp response.AlertRulesList, err error) { db, err := client.GetDbClient() if err != nil { return } session := db.NewSession() defer session.Close() session.Table(new(entity.AlertRules)).Alias("r").Select("r.*,acp.class_name class_parent_name,ac.class_name,mc.expr,mc.metric_name metric_config_name,mc.alert_rule_type") session.Join("LEFT", "metric_config mc", "mc.id = r.metric_config_id") session.Join("LEFT", "alert_class ac", "ac.class_id = r.class_id") session.Join("LEFT", "alert_class acp", "acp.class_id = ac.parent_id") if req.Id != "" { session.Where("r.id = ?", req.Id) } if req.NotifyMethod != "" && req.NotifyMethod != "all" { session.Where("r.notify_method LIKE ?", "%\""+req.NotifyMethod+"\"%") // ["dingtalk","sms"] } if req.IsEnabled > 0 { session.Where("r.is_enabled = ?", req.IsEnabled) } if req.StartTime != "" { session.Where("r.created_at >= ?", req.StartTime) } if req.EndTime != "" { session.Where("r.created_at <= ?", req.EndTime) } if req.Keyword != "" { // 预警对象/预警分类/预警指标 session.Where("r.metric_name LIKE ?", "%"+req.Keyword+"%"). Or("mc.metric_name LIKE ?", "%"+req.Keyword+"%"). Or("ac.class_name LIKE ?", "%"+req.Keyword+"%"). Or("acp.class_name LIKE ?", "%"+req.Keyword+"%") } resp.TotalCount, err = session.Limit(req.GetPageSize(), (req.GetPage()-1)*req.GetPageSize()).FindAndCount(&resp.List) for i := 0; i < len(resp.List); i++ { _ = json.Unmarshal([]byte(resp.List[i].AlertRules.AlertCondition), &resp.List[i].AlertCondition) _ = json.Unmarshal([]byte(resp.List[i].AlertRules.AlertRange), &resp.List[i].AlertRange) _ = json.Unmarshal([]byte(resp.List[i].AlertRules.NotifyMethod), &resp.List[i].NotifyMethod) _ = json.Unmarshal([]byte(resp.List[i].AlertRules.NotifyRecipients), &resp.List[i].NotifyRecipients) } return } func (a *AlertRulesSvc) Delete(ids []string) (err error) { var exist bool db, err := client.GetDbClient() if err != nil { return } alertSvc := AlertSvc{User: a.User} for _, id := range ids { exist, err = alertSvc.IndexDocExist(request.ExistAlert{AlertRulesId: id}) if err != nil { return } if !exist { _, err = db.NewSession().Where("id = ?", id).Delete(new(entity.AlertRules)) } else { return errors.New("alert_rules_id already exists in opensearch") } } return }