diff --git a/src/bean/entity/alert_class.go b/src/bean/entity/alert_class.go index d7726fe7d858c6963d37017b0a5b7136dd09f237..801f530b924277033533296ff127cd357785a5d8 100644 --- a/src/bean/entity/alert_class.go +++ b/src/bean/entity/alert_class.go @@ -3,14 +3,15 @@ package entity import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" type AlertClass struct { - ClassId int `json:"class_id" xorm:"'class_id' pk autoincr" ` // 主键id - ClassName string `json:"class_name" xorm:"'class_name'"` // 分类名称 - ParentId int `json:"parent_id" xorm:"'parent_id'"` // 父级id - SortOrder int `json:"sort_order" xorm:"'sort_order'"` // 排序 - CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人 - CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间 - UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人 - UpdatedAt jsontime.Time `json:"updated_at" xorm:"'updated_at'"` // 更新时间 + ClassId int `json:"class_id" xorm:"'class_id' pk autoincr" ` // 主键id + ClassName string `json:"class_name" xorm:"'class_name'"` // 分类名称 + ParentId int `json:"parent_id" xorm:"'parent_id'"` // 父级id + SortOrder int `json:"sort_order" xorm:"'sort_order'"` // 排序 + SourceFrom int `json:"source_from" xorm:"source_from"` // 数据来源 1:默认 2:自定义 + CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人 + CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间 + UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人 + UpdatedAt jsontime.Time `json:"updated_at" xorm:"'updated_at'"` // 更新时间 } func (m *AlertClass) TableName() string { diff --git a/src/bean/entity/alert_rules.go b/src/bean/entity/alert_rules.go new file mode 100644 index 0000000000000000000000000000000000000000..b322fe4389129cc6e43e120dc0b240a78d351825 --- /dev/null +++ b/src/bean/entity/alert_rules.go @@ -0,0 +1,41 @@ +package entity + +import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" + +// AlertRules 预警规则配置 +type AlertRules struct { + Id string `json:"id" xorm:"'id' pk"` // 主键id + MetricName string `json:"metric_name" xorm:"'metric_name'"` // 预警规则名称(指标名称) + DetectionType int `json:"detection_type" xorm:"'detection_type'"` // 检测类型 1:静态阈值 2:自定义 + ClassId int `json:"class_id" xorm:"'class_id'"` // 预警对象id(级联:预警分类/预警对象) + MetricConfigId string `json:"metric_config_id" xorm:"'metric_config_id'"` // 预警指标id + AlertRange string `json:"alert_range" xorm:"'alert_range'"` // 预警范围 字典值 + AlertCondition string `json:"alert_condition" xorm:"'alert_condition'"` // 预警规则 字典值 + Duration int `json:"duration" xorm:"'duration'"` // 持续时间 + DurationUnit string `json:"duration_unit" xorm:"'duration_unit'"` // 持续时间单位 s m h + CheckPeriod int `json:"check_period" xorm:"'check_period'"` // 检查周期 单位:分钟 + NotifyMethod string `json:"notify_method" xorm:"'notify_method'"` // 预警通知方式 all dingtalk sms + NotifyPushCount int `json:"notify_push_count" xorm:"'notify_push_count'"` // 消息推送次数 + NotifyPushFrequency int `json:"notify_push_frequency" xorm:"'notify_push_frequency'"` // 消息推送频率 分钟 + IsEnabled int `json:"is_enabled" xorm:"'is_enabled'"` // 是否开启 0:关闭 1:启动 + CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人 + CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间 + UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人 + UpdatedAt jsontime.Time `json:"updated_at" xorm:"'updated_at'"` // 更新时间 +} + +func (m *AlertRules) TableName() string { + return "alert_rules" +} + +type RulesAlertRange struct { + Name string `json:"name" form:"name" binding:"required"` + Value string `json:"value" form:"value" binding:"required"` + Compare string `json:"compare" form:"compare" binding:"required"` +} + +type AlertCondition struct { + ThresholdsMax int `json:"thresholds_max" form:"thresholds_max" binding:"required"` + ThresholdsMin int `json:"thresholds_min" form:"thresholds_min" binding:"required"` + RiskLevel int `json:"risk_level" form:"risk_level" binding:"required"` +} diff --git a/src/bean/entity/metric_config.go b/src/bean/entity/metric_config.go index 984e79c34c59967a3f440b9baa33beec0b269fc4..74ad45c6acb00e227d7799196ed1acad71d1f7aa 100644 --- a/src/bean/entity/metric_config.go +++ b/src/bean/entity/metric_config.go @@ -13,6 +13,7 @@ type MetricConfig struct { CheckPeriod int `json:"check_period" xorm:"'check_period'"` // 检查周期 单位:分钟 IsEnabled int `json:"is_enabled" xorm:"'is_enabled'"` // 是否开启 0:关闭 1:启动 AlertRuleType string `json:"alert_rule_type" xorm:"'alert_rule_type'"` // 预警规则类型 关联字典表 + SourceFrom int `json:"source_from" xorm:"source_from"` // 数据来源 1:默认 2:自定义 CreatedBy string `json:"created_by" xorm:"'created_by'"` // 创建人 CreatedAt jsontime.Time `json:"created_at" xorm:"'created_at'"` // 创建时间 UpdatedBy string `json:"updated_by" xorm:"'updated_by'"` // 更新人 diff --git a/src/bean/vo/request/alert_class.go b/src/bean/vo/request/alert_class.go index 91c4b532ee73f9ccf98809a0dc8e9b9b9e8d8f2b..49046eaf1044954bafe6e75ee125fd89e507de6f 100644 --- a/src/bean/vo/request/alert_class.go +++ b/src/bean/vo/request/alert_class.go @@ -1,9 +1,10 @@ package request type AddAlertClass struct { - ClassName string `json:"class_name" form:"class_name" binding:"required"` - ParentId int `json:"parent_id" form:"parent_id" binding:"omitempty,oneof=0 1"` - SortOrder int `json:"sort_order" form:"sort_order"` + ClassName string `json:"class_name" form:"class_name" binding:"required"` + ParentId int `json:"parent_id" form:"parent_id" binding:"omitempty,oneof=0 1"` + SortOrder int `json:"sort_order" form:"sort_order"` + SourceFrom int `json:"source_from" form:"source_from" binding:"omitempty,oneof=1 2"` // 数据来源 1:默认 2:自定义 } type UpdateAlertClass struct { diff --git a/src/bean/vo/request/alert_rules.go b/src/bean/vo/request/alert_rules.go new file mode 100644 index 0000000000000000000000000000000000000000..0624303673bdff97ba9950a418d2999e5d8543bc --- /dev/null +++ b/src/bean/vo/request/alert_rules.go @@ -0,0 +1,75 @@ +package request + +import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" + +type AddAlertRules struct { + MetricName string `json:"metric_name" form:"metric_name" binding:"required"` // 预警规则名称(指标名称) + DetectionType int `json:"detection_type" form:"detection_type" binding:"oneof=1 2"` // 检测类型 1:静态阈值 2:自定义 + ClassId int `json:"class_id" form:"class_id" binding:"required_if=DetectionType 1"` // 预警对象id(级联:预警分类/预警对象) + ClassParentName string `json:"class_parent_name" form:"class_parent_name" binding:"required_if=DetectionType 2"` // 预警分类名称 + ClassName string `json:"class_name" form:"class_name" binding:"required_if=DetectionType 2"` // 预警对象名称 + 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"` // 预警规则 字典值 + 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:"oneof=all dingtalk sms"` // 预警通知方式 all dingtalk sms + 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:"omitempty,oneof=0 1 2"` // 是否开启 1:是 2:否 +} + +type UpdateAlertRules struct { + Id string `json:"id" binding:"required"` + MetricName string `json:"metric_name" form:"metric_name" binding:"required"` // 预警规则名称(指标名称) + DetectionType int `json:"detection_type" form:"detection_type" binding:"oneof=1 2"` // 检测类型 1:静态阈值 2:自定义 + ClassId int `json:"class_id" form:"class_id" binding:"required"` // 预警对象id(级联:预警分类/预警对象) + ClassParentName string `json:"class_parent_name" form:"class_parent_name" binding:"required_if=DetectionType 2"` // 预警分类名称 + ClassName string `json:"class_name" form:"class_name" binding:"required_if=DetectionType 2"` // 预警对象名称 + MetricConfigName string `json:"metric_config_name" form:"metric_config_name" binding:"required_if=DetectionType 2"` // 预警指标名称(detection_type=2时有值) + Expr string `json:"expr" form:"expr" binding:"required_if=DetectionType 2"` // 指标表达式(PromQL语句) + AlertCondition string `json:"alert_condition" form:"alert_condition" binding:"required"` // 预警规则 字典值 + AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type" binding:"required_if=DetectionType 2"` // 预警规则类型 关联字典表 + AlertRange string `json:"alert_range" form:"alert_range"` // 预警范围 字典值 + 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:"gte=0"` // 检查周期 单位:分钟 + NotifyMethod string `json:"notify_method" form:"notify_method" binding:"oneof=all dingtalk sms"` // 预警通知方式 all dingtalk sms + 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:"omitempty,oneof=0 1 2"` // 是否开启 1:是 2:否 +} + +type DeleteAlertRules struct { + Id string `json:"id" form:"id"` + Ids []string `json:"ids" form:"ids" binding:"required_without=Id"` +} + +type DetailAlertRules struct { + Id string `json:"id" form:"id" binding:"required"` +} + +type ListAlertRules struct { + Id string `json:"id" form:"id"` + MetricName string `json:"metric_name" form:"metric_name"` // 预警规则名称(指标名称) + DetectionType int `json:"detection_type" form:"detection_type"` // 检测类型 1:静态阈值 2:自定义 + ClassId int `json:"class_id" form:"class_id"` // 预警对象id(级联:预警分类/预警对象) + ClassParentName string `json:"class_parent_name" form:"class_parent_name"` // 预警分类名称 + ClassName string `json:"class_name" form:"class_name"` // 预警对象名称 + MetricConfigName string `json:"metric_config_name" form:"metric_config_name"` // 预警指标名称(detection_type=2时有值) + Expr string `json:"expr" form:"expr"` // 指标表达式(PromQL语句) + AlertCondition string `json:"alert_condition" form:"alert_condition"` // 预警规则 字典值 + AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type"` // 预警规则类型 关联字典表 + AlertRange string `json:"alert_range" form:"alert_range"` // 预警范围 字典值 + Duration int `json:"duration" form:"duration"` // 持续时间 + DurationUnit string `json:"duration_unit" form:"duration_unit"` // 持续时间单位 s m h + CheckPeriod int `json:"check_period" form:"check_period"` // 检查周期 单位:分钟 + NotifyMethod string `json:"notify_method" form:"notify_method"` // 预警通知方式 all dingtalk sms + NotifyPushCount int `json:"notify_push_count" form:"notify_push_count"` // 消息推送次数 + NotifyPushFrequency int `json:"notify_push_frequency" form:"notify_push_frequency"` // 消息推送频率 分钟 + IsEnabled int `json:"is_enabled" form:"is_enabled"` // 是否开启 1:是 2:否 + Pagination +} diff --git a/src/bean/vo/request/metric_config.go b/src/bean/vo/request/metric_config.go index bf5191f509f4a607faf21a4bba96f495e461084b..6c070d02ceb63a778d6b2577237b5deea2eb84a4 100644 --- a/src/bean/vo/request/metric_config.go +++ b/src/bean/vo/request/metric_config.go @@ -10,8 +10,9 @@ type AddMetricConfig struct { Duration int `json:"duration" form:"duration"` // 持续时间 DurationUnit string `json:"duration_unit" form:"duration_unit" binding:"required,oneof=s m h"` // 持续时间单位 s m h CheckPeriod int `json:"check_period" form:"check_period" binding:"oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟 - IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"oneof=0 1 2"` // 是否开启 1:启动 2:停用 + IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"omitempty,oneof=0 1 2"` // 是否开启 1:是 2:否 AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type" binding:"required"` // 预警规则类型 关联字典表 + SourceFrom int `json:"source_from" form:"source_from" binding:"omitempty,oneof=1 2"` // 数据来源 1:默认 2:自定义 } type UpdateMetricConfig struct { @@ -23,8 +24,9 @@ type UpdateMetricConfig struct { Duration int `json:"duration" form:"duration"` // 持续时间 DurationUnit string `json:"duration_unit" form:"duration_unit" binding:"omitempty,oneof=s m h"` // 持续时间单位 s m h CheckPeriod int `json:"check_period" form:"check_period" binding:"omitempty,oneof=1 3 5 10 20 30"` // 检查周期 单位:分钟 - IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"omitempty,oneof=0 1 2"` // 是否开启 1:启动 2:停用 + IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"omitempty,oneof=0 1 2"` // 是否开启 1:是 2:否 AlertRuleType string `json:"alert_rule_type" form:"alert_rule_type"` // 预警规则类型 关联字典表 + SourceFrom int `json:"source_from" form:"source_from" binding:"omitempty,oneof=1 2"` // 数据来源 1:默认 2:自定义 } type DeleteMetricConfig struct { diff --git a/src/bean/vo/response/alert_rules.go b/src/bean/vo/response/alert_rules.go new file mode 100644 index 0000000000000000000000000000000000000000..928b253a8d159a55cd2d1f7609f7530b7eee1cb2 --- /dev/null +++ b/src/bean/vo/response/alert_rules.go @@ -0,0 +1,12 @@ +package response + +import "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/entity" + +type AlertRulesItem struct { + entity.AlertRules `xorm:"extends"` +} + +type AlertRulesList struct { + TotalCount int64 `json:"total_count"` + List []AlertRulesItem `json:"list"` +} diff --git a/src/bean/vo/response/metric_config.go b/src/bean/vo/response/metric_config.go index 470084e1f4ad13d2dc065291c90b5db367af2214..175ed1de60023f5ddf4bd7acd3b47a8e25fb2595 100644 --- a/src/bean/vo/response/metric_config.go +++ b/src/bean/vo/response/metric_config.go @@ -7,7 +7,7 @@ type MetricConfigItem struct { AlertRange []entity.AlertRange `json:"alert_range" xorm:"alert_range"` } -type UnitsList struct { +type MetricConfigList struct { TotalCount int64 `json:"total_count"` List []MetricConfigItem `json:"list"` } diff --git a/src/controller/alert_class.go b/src/controller/alert_class.go index 859393f5b9805fce7323ccfe659ac2f150faccc4..2d787b5a4bd40ae862de208044c6c7d57ef69e44 100644 --- a/src/controller/alert_class.go +++ b/src/controller/alert_class.go @@ -3,6 +3,7 @@ package controller import ( "github.com/gin-gonic/gin" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/service" @@ -17,7 +18,12 @@ func AddAlertClass(c *gin.Context) { } svc := service.AlertClassSvc{User: header.GetUser(c)} - err := svc.Add(req) + db, err := client.GetDbClient() + if err != nil { + SendJsonResponse(c, resp.DbConnectError.WithError(err), nil) + return + } + _, err = svc.Add(db.NewSession(), req) if err != nil { SendJsonResponse(c, resp.FAIL.WithError(err), nil) return @@ -33,7 +39,12 @@ func UpdateAlertClass(c *gin.Context) { } svc := service.AlertClassSvc{User: header.GetUser(c)} - err := svc.Update(req) + db, err := client.GetDbClient() + if err != nil { + SendJsonResponse(c, resp.DbConnectError.WithError(err), nil) + return + } + err = svc.Update(db.NewSession(), req) if err != nil { SendJsonResponse(c, resp.FAIL.WithError(err), nil) return diff --git a/src/controller/alert_rules.go b/src/controller/alert_rules.go new file mode 100644 index 0000000000000000000000000000000000000000..481d0d66350c2984698f452dd7784084d1c3d7d3 --- /dev/null +++ b/src/controller/alert_rules.go @@ -0,0 +1,99 @@ +package controller + +import ( + "github.com/gin-gonic/gin" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/service" +) + +// AddAlertRules 新增任务 +func AddAlertRules(c *gin.Context) { + var req request.AddAlertRules + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.AlertRulesSvc{User: header.GetUser(c)} + err := svc.Add(req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + +func UpdateAlertRules(c *gin.Context) { + var req request.UpdateAlertRules + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.AlertRulesSvc{User: header.GetUser(c)} + + err := svc.Update(req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + +func DeleteAlertRules(c *gin.Context) { + var req request.DeleteAlertRules + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + var ids []string + switch len(req.Ids) { + case 0: + ids = append(ids, req.Id) + default: + ids = req.Ids + } + + svc := service.AlertRulesSvc{User: header.GetUser(c)} + err := svc.Delete(ids) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, nil) +} + +func DetailAlertRules(c *gin.Context) { + var req request.DetailAlertRules + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.AlertRulesSvc{User: header.GetUser(c)} + data, err := svc.GetDataById(req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, data) +} + +func ListAlertRules(c *gin.Context) { + var req request.ListAlertRules + if err := c.ShouldBind(&req); err != nil { + SendJsonResponse(c, resp.InvalidParam.TranslateError(err), nil) + return + } + + svc := service.AlertRulesSvc{User: header.GetUser(c)} + data, err := svc.List(req) + if err != nil { + SendJsonResponse(c, resp.FAIL.WithError(err), nil) + return + } + SendJsonResponse(c, resp.OK, data) +} diff --git a/src/controller/metric_config.go b/src/controller/metric_config.go index a0a5d83b39ac8b4de22429fb5019ddc1eb344e9d..fc62d3751c193f74bb65f8047ce6741c9fd00420 100644 --- a/src/controller/metric_config.go +++ b/src/controller/metric_config.go @@ -3,6 +3,7 @@ package controller import ( "github.com/gin-gonic/gin" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/bean/vo/request" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/client" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/router/middleware/header" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/service" @@ -17,7 +18,12 @@ func AddMetricConfig(c *gin.Context) { } svc := service.MetricConfigSvc{User: header.GetUser(c)} - err := svc.Add(req) + db, err := client.GetDbClient() + if err != nil { + SendJsonResponse(c, resp.DbConnectError.WithError(err), nil) + return + } + _, err = svc.Add(db.NewSession(), req) if err != nil { SendJsonResponse(c, resp.FAIL.WithError(err), nil) return @@ -33,7 +39,12 @@ func UpdateMetricConfig(c *gin.Context) { } svc := service.MetricConfigSvc{User: header.GetUser(c)} - err := svc.Update(req) + db, err := client.GetDbClient() + if err != nil { + SendJsonResponse(c, resp.DbConnectError.WithError(err), nil) + return + } + err = svc.Update(db.NewSession(), req) if err != nil { SendJsonResponse(c, resp.FAIL.WithError(err), nil) return diff --git a/src/router/alertrulesrouter.go.go b/src/router/alertrulesrouter.go.go new file mode 100644 index 0000000000000000000000000000000000000000..8562b3fd81f701f9f882d246ff3793001632dbbd --- /dev/null +++ b/src/router/alertrulesrouter.go.go @@ -0,0 +1,20 @@ +package router + +import ( + "fmt" + "github.com/gin-gonic/gin" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/common/conf" + "gitlab.wodcloud.com/smart-operation/so-operation-api/src/controller" +) + +// InitAlertRulesRouter 初始化预警规则配置路由 +func InitAlertRulesRouter(e *gin.Engine) { + group := e.Group(fmt.Sprintf("%s/alert_rules", conf.Options.Prefix)) + { + group.POST("", controller.AddAlertRules) + group.PUT("", controller.UpdateAlertRules) + group.DELETE("", controller.DeleteAlertRules) + group.GET("", controller.DetailAlertRules) + group.GET("list", controller.ListAlertRules) + } +} diff --git a/src/router/router.go b/src/router/router.go index 187738e6a3a295e27ac40a8906385fb5c42a2adf..2ce6572298b7519ee15ce031411481d9bcd276cd 100644 --- a/src/router/router.go +++ b/src/router/router.go @@ -45,6 +45,8 @@ func Load(r *gin.Engine, middleware ...gin.HandlerFunc) { InitSystemMenuRouter(r) // 初始化指标配置路由 InitMetricConfigRouter(r) + // 初始化预警规则配置路由 + InitAlertRulesRouter(r) // 初始化prometheus路由 InitPrometheusRouter(r) // 初始化工单管理路由 diff --git a/src/service/alert_class.go b/src/service/alert_class.go index ac987adff94038e62fa367273f060635c10941be..d4e3e6ad5d1833205eb5369194ff26d7b475f3d6 100644 --- a/src/service/alert_class.go +++ b/src/service/alert_class.go @@ -11,23 +11,19 @@ import ( "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/jsontime" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/resp" "sort" + "xorm.io/xorm" ) type AlertClassSvc struct { User entity.SystemUserInfo } -func (m *AlertClassSvc) Add(req request.AddAlertClass) (err error) { - db, err := client.GetDbClient() - if err != nil { - err = resp.DbConnectError.WithError(err) - return err - } +func (m *AlertClassSvc) Add(session *xorm.Session, req request.AddAlertClass) (classId int, err error) { now := jsontime.Now() data := entity.AlertClass{ - CreatedBy: "", + CreatedBy: m.User.SystemAccount, CreatedAt: now, - UpdatedBy: "", + UpdatedBy: m.User.SystemAccount, UpdatedAt: now, } _ = copier.Copy(&data, &req) @@ -37,23 +33,19 @@ func (m *AlertClassSvc) Add(req request.AddAlertClass) (err error) { return } data.SortOrder = max + 1 - _, err = db.NewSession().Insert(&data) - return nil + _, err = session.Insert(&data) + classId = data.ClassId + return } -func (m *AlertClassSvc) Update(req request.UpdateAlertClass) error { - db, err := client.GetDbClient() - if err != nil { - err = resp.DbConnectError.WithError(err) - return err - } +func (m *AlertClassSvc) Update(session *xorm.Session, req request.UpdateAlertClass) error { now := jsontime.Now() data := entity.AlertClass{ - UpdatedBy: "", + UpdatedBy: m.User.SystemAccount, UpdatedAt: now, } _ = copier.Copy(&data, &req) - _, err = db.NewSession().Cols("class_name", "updated_by", "updated_at").ID(data.ClassId).Update(&data) + _, err := session.Cols("class_name", "updated_by", "updated_at").ID(data.ClassId).Update(&data) if err != nil { return err } @@ -71,7 +63,7 @@ func (m *AlertClassSvc) Move(req request.MoveAlertClass) (err error) { _ = copier.Copy(&data, &req) var list []entity.AlertClass _, err = db.NewSession().Where("class_id = ?", req.ClassId).Get(&data) - err = db.NewSession().Where("parent_id = ?", data.ParentId).OrderBy("sort_order asc").Find(&list) + err = db.NewSession().Where("parent_id = ?", data.ParentId).Where("source_from = 1").OrderBy("sort_order asc").Find(&list) var previousIndex int var nextIndex int for i := 0; i < len(list); i++ { @@ -144,6 +136,7 @@ func (m *AlertClassSvc) List(req request.ListAlertClass) (resp response.AlertCla } session := db.NewSession() defer session.Close() + session.Where("source_from = 1") if req.ClassId != 0 { session.Where("class_id = ?", req.ClassId) } @@ -163,6 +156,7 @@ func (m *AlertClassSvc) Tree(req request.ListAlertClass) (resp []*response.Alert session := db.NewSession() defer session.Close() var list []entity.AlertClass + session.Where("source_from = 1") _, err = session.OrderBy("sort_order").FindAndCount(&list) // TODO 对req进行过滤 resp, err = AlertClassTree(list) @@ -214,7 +208,7 @@ func (m *AlertClassSvc) SortOrderMax(parentId int) (max int, err error) { } _, err = db.NewSession().Table(new(entity.AlertClass)). Select("max(sort_order)"). - Where("parent_id = ?", parentId).Get(&max) + Where("parent_id = ?", parentId).Where("source_from = 1").Get(&max) return } diff --git a/src/service/alert_rules.go b/src/service/alert_rules.go new file mode 100644 index 0000000000000000000000000000000000000000..ec3c993a108943cba8b8937b38cd7c91660cd096 --- /dev/null +++ b/src/service/alert_rules.go @@ -0,0 +1,203 @@ +package service + +import ( + "github.com/google/uuid" + "github.com/jinzhu/copier" + "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" + "xorm.io/xorm" +) + +type AlertRulesSvc struct { + User entity.SystemUserInfo +} + +func (m *AlertRulesSvc) Add(req request.AddAlertRules) 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: m.User.SystemAccount, + CreatedAt: now, + UpdatedBy: m.User.SystemAccount, + UpdatedAt: now, + } + _ = copier.Copy(&data, &req) + switch req.DetectionType { + case 1: + _, err = db.Update(&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: m.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: m.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 + }) + } + + // TODO 告警规则添加到普罗米修斯表 + return nil +} + +func (m *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: m.User.SystemAccount, + UpdatedAt: now, + } + _ = copier.Copy(&data, &req) + + session := db.NewSession() + 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.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: m.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: m.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.Update(&data) + return nil, err + }) + } + return nil +} + +func (m *AlertRulesSvc) GetDataById(req request.DetailAlertRules) (resp response.AlertRulesItem, err error) { + db, err := client.GetDbClient() + if err != nil { + return + } + _, err = db.NewSession().Table(resp.TableName()).Where("id = ?", req.Id).Get(&resp) + return +} + +func (m *AlertRulesSvc) List(req request.ListAlertRules) (resp response.MetricConfigList, err error) { + db, err := client.GetDbClient() + if err != nil { + return + } + session := db.NewSession() + defer session.Close() + if req.Id != "" { + session.Where("id = ?", req.Id) + } + if req.ClassId != 0 { + session.Where("class_id = ?", req.ClassId) + } + if req.MetricName != "" { + session.Where("metric_name LIKE ?", "%"+req.MetricName+"%") + } + if req.IsEnabled != 0 { + session.Where("is_enabled = ?", req.IsEnabled) + } + resp.TotalCount, err = session.Table(new(entity.AlertRules)).Limit(req.GetPageSize(), (req.GetPage()-1)*req.GetPageSize()). + OrderBy("id").FindAndCount(&resp.List) + return +} + +func (m *AlertRulesSvc) Delete(ids []string) (err error) { + db, err := client.GetDbClient() + if err != nil { + return + } + // TODO 批量删除表中的多出数据 + _, err = db.NewSession().In("id", ids).Delete(new(entity.AlertRules)) + return +} diff --git a/src/service/metric_config.go b/src/service/metric_config.go index 6961c1cfd1944ebe4aa9849187db331af76f49dc..fc266b864483cf40e860cd1bcc48c732390802e0 100644 --- a/src/service/metric_config.go +++ b/src/service/metric_config.go @@ -8,53 +8,42 @@ import ( "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 MetricConfigSvc struct { User entity.SystemUserInfo } -func (m *MetricConfigSvc) Add(req request.AddMetricConfig) error { - db, err := client.GetDbClient() - if err != nil { - err = resp.DbConnectError.WithError(err) - return err - } +func (m *MetricConfigSvc) Add(session *xorm.Session, req request.AddMetricConfig) (id string, err error) { now := jsontime.Now() - mc := entity.MetricConfig{ + data := entity.MetricConfig{ Id: uuid.New().String(), - CreatedBy: "", + CreatedBy: m.User.SystemAccount, CreatedAt: now, - UpdatedBy: "", + UpdatedBy: m.User.SystemAccount, UpdatedAt: now, } - _ = copier.Copy(&mc, &req) - mc.AlertRange = util.ConvertToString(req.AlertRange) - - _, err = db.NewSession().Insert(&mc) + _ = copier.Copy(&data, &req) + data.AlertRange = util.ConvertToString(req.AlertRange) + _, err = session.Insert(&data) if err != nil { - return err + return } - return nil + id = data.Id + return } -func (m *MetricConfigSvc) Update(req request.UpdateMetricConfig) error { - db, err := client.GetDbClient() - if err != nil { - err = resp.DbConnectError.WithError(err) - return err - } +func (m *MetricConfigSvc) Update(session *xorm.Session, req request.UpdateMetricConfig) error { now := jsontime.Now() - mc := entity.MetricConfig{ - UpdatedBy: "", + data := entity.MetricConfig{ + UpdatedBy: m.User.SystemAccount, UpdatedAt: now, } - _ = copier.Copy(&mc, &req) - mc.AlertRange = util.ConvertToString(req.AlertRange) - - _, err = db.NewSession().ID(req.Id).Update(&mc) + _ = copier.Copy(&data, &req) + data.AlertRange = util.ConvertToString(req.AlertRange) + _, err := session.ID(req.Id).Update(&data) if err != nil { return err } @@ -70,7 +59,7 @@ func (m *MetricConfigSvc) GetDataById(req request.DetailMetricConfig) (resp resp return } -func (m *MetricConfigSvc) List(req request.ListMetricConfig) (resp response.UnitsList, err error) { +func (m *MetricConfigSvc) List(req request.ListMetricConfig) (resp response.MetricConfigList, err error) { db, err := client.GetDbClient() if err != nil { return