Commit 9e673939 authored by 李科's avatar 李科

feat: 添加PrometheusRule规则

parent c8678c48
...@@ -36,7 +36,7 @@ type RulesAlertRange struct { ...@@ -36,7 +36,7 @@ type RulesAlertRange struct {
} }
type AlertCondition 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"` 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"` RiskLevel int `json:"risk_level" form:"risk_level" binding:"required,oneof=1 2 3 4"`
} }
......
...@@ -13,14 +13,14 @@ type AddAlertRules struct { ...@@ -13,14 +13,14 @@ type AddAlertRules struct {
MetricConfigId string `json:"metric_config_id" form:"'metric_config_id'" binding:"required_if=DetectionType 1"` // 预警指标id 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) 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语句) 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"` // 预警规则类型 关联字典表 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"` // 预警范围 字典值 AlertRange []entity.RulesAlertRange `json:"alert_range" form:"alert_range" binding:"required,dive"` // 预警范围 字典值
Duration int `json:"duration" form:"duration" binding:"gte=0"` // 持续时间 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 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"` // 检查周期 单位:分钟 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 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"` // 消息推送次数 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"` // 消息推送频率 分钟 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:否 IsEnabled int `json:"is_enabled" form:"is_enabled" binding:"oneof=1 2"` // 是否开启 1:是 2:否
......
...@@ -18,7 +18,7 @@ type AlertRulesSvc struct { ...@@ -18,7 +18,7 @@ type AlertRulesSvc struct {
User entity.SystemUserInfo User entity.SystemUserInfo
} }
func (a *AlertRulesSvc) Add(req request.AddAlertRules) error { func (a *AlertRulesSvc) Add(req request.AddAlertRules) (err error) {
db, err := client.GetDbClient() db, err := client.GetDbClient()
if err != nil { if err != nil {
err = resp.DbConnectError.WithError(err) err = resp.DbConnectError.WithError(err)
...@@ -39,20 +39,10 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) error { ...@@ -39,20 +39,10 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) error {
data.NotifyRecipients = util.ConvertToString(req.NotifyRecipients) data.NotifyRecipients = util.ConvertToString(req.NotifyRecipients)
switch req.DetectionType { switch req.DetectionType {
case 1: case 1:
// TODO 暂时不能做事务,需要先插入数据,再进行查询
_, err = db.Insert(&data) _, err = db.Insert(&data)
if err != nil { if err != nil {
return err 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: // 自定义 case 2: // 自定义
_, err = db.Transaction(func(session *xorm.Session) (interface{}, error) { _, err = db.Transaction(func(session *xorm.Session) (interface{}, error) {
// 添加自定义分类 // 添加自定义分类
...@@ -103,7 +93,17 @@ func (a *AlertRulesSvc) Add(req request.AddAlertRules) 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 return nil
} }
......
...@@ -9,7 +9,9 @@ import ( ...@@ -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/common/conf"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/pkg/beagle/constant"
"gitlab.wodcloud.com/smart-operation/so-operation-api/src/service/k8s" "gitlab.wodcloud.com/smart-operation/so-operation-api/src/service/k8s"
"go.uber.org/zap"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"log"
"strings" "strings"
) )
...@@ -17,10 +19,7 @@ type PrometheusRuleSvc struct { ...@@ -17,10 +19,7 @@ type PrometheusRuleSvc struct {
User entity.SystemUserInfo User entity.SystemUserInfo
} }
func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) { func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) (err error) {
header := make(map[string]string)
header["Authorization"] = "Bearer " + conf.Options.KubernetesToken
svc := k8s.PrometheusRule{Header: header}
pr := monitoringv1.PrometheusRule{} pr := monitoringv1.PrometheusRule{}
prometheusRuleName := k8s.GetPrometheusRuleName(data.Id) prometheusRuleName := k8s.GetPrometheusRuleName(data.Id)
pr.Name = prometheusRuleName pr.Name = prometheusRuleName
...@@ -31,12 +30,9 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) { ...@@ -31,12 +30,9 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) {
groupInterval := monitoringv1.Duration(fmt.Sprintf("%d%s", data.CheckPeriod, "m")) groupInterval := monitoringv1.Duration(fmt.Sprintf("%d%s", data.CheckPeriod, "m"))
group.Interval = &groupInterval group.Interval = &groupInterval
ruleFor := monitoringv1.Duration(fmt.Sprintf("%d%s", data.Duration, data.DurationUnit)) 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)) group.Name = k8s.GetPrometheusRuleGroupName(data.MetricConfigId, string(*group.Interval))
for _, v := range data.AlertRange { 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) data.Expr = strings.ReplaceAll(data.Expr, v.VariableName, item)
} }
for _, v := range data.AlertCondition { for _, v := range data.AlertCondition {
...@@ -52,13 +48,24 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) { ...@@ -52,13 +48,24 @@ func (p *PrometheusRuleSvc) Create(data response.AlertRulesItem) {
}, },
Annotations: map[string]string{ Annotations: map[string]string{
"value": "{{ $value }}", "value": "{{ $value }}",
"summary": "概述", "summary": fmt.Sprintf("分组名:%s, 检查周期:%s, 持续时间:%s", group.Name, string(groupInterval), string(ruleFor)),
"description": "描述", "description": "",
}, },
} }
expr := fmt.Sprintf("%d <= %s <=%d", v.ThresholdsMin, data.Expr, v.ThresholdsMax) expr := fmt.Sprintf("%d <= %s <=%d", v.ThresholdsMin, data.Expr, v.ThresholdsMax)
rule.Expr = intstr.FromString(expr) rule.Expr = intstr.FromString(expr)
group.Rules = append(group.Rules, rule) 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
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment