From 326c2e5fccc3736ee2e39274b5e0b94960c5b049 Mon Sep 17 00:00:00 2001 From: zhanghan2021 Date: Tue, 29 Oct 2024 17:06:45 +0800 Subject: [PATCH] process alert list and insert into db --- server/db/db.go | 1 + server/main.go | 5 ++ server/model/alert.go | 13 ++++ server/service/alertservice.go | 117 +++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+) diff --git a/server/db/db.go b/server/db/db.go index 1be0dbe..751d398 100644 --- a/server/db/db.go +++ b/server/db/db.go @@ -42,6 +42,7 @@ func MysqldbInit(conf *config.MysqlDBInfo) error { MySQL.AutoMigrate(&model.PrometheusTarget{}) MySQL.AutoMigrate(&model.Rule{}) MySQL.AutoMigrate(&model.RuleTarget{}) + MySQL.AutoMigrate(&model.Alert{}) return nil } diff --git a/server/main.go b/server/main.go index e2abf09..c41b94e 100644 --- a/server/main.go +++ b/server/main.go @@ -34,6 +34,11 @@ func main() { os.Exit(-1) } + if err := service.PullAlert(); err != nil { + logger.Error("pull prometheus alerts failed, please check the code: %s", err) + os.Exit(-1) + } + server := router.InitRouter() plugin.Client = client.DefaultClient(plugin.Init(config.Config().PluginPrometheus, config.Config().PrometheusServer)) diff --git a/server/model/alert.go b/server/model/alert.go index e31eeb5..1f6a515 100644 --- a/server/model/alert.go +++ b/server/model/alert.go @@ -1,5 +1,18 @@ package model +type Alert struct { + ID int `gorm:"primary_key;AUTO_INCREMENT" json:"id"` + AlertName string `gorm:"uniqueIndex:idx_alerts, length:100" json:"alertName"` + GroupId string `gorm:"uniqueIndex:idx_alerts, length:100" json:"groupId"` + IP string `gorm:"uniqueIndex:idx_alerts, length:100" json:"ip"` + AlertLevel string `json:"level"` + Summary string `json:"summary"` + Metric string `json:"metric"` + Description string `json:"description"` + AlertTime string `json:"alertTime"` + AlertEndTime string `gorm:"uniqueIndex:idx_alerts, length:100" json:"alertEndTime"` +} + type AlertsResponse struct { Status string `json:"status"` Data struct { diff --git a/server/service/alertservice.go b/server/service/alertservice.go index 5d3fb23..9939e45 100644 --- a/server/service/alertservice.go +++ b/server/service/alertservice.go @@ -2,13 +2,37 @@ package service import ( "encoding/json" + "fmt" "io/ioutil" "net/http" + "reflect" + "strings" + "time" + "gitee.com/openeuler/PilotGo/sdk/logger" "openeuler.org/PilotGo/prometheus-plugin/config" + "openeuler.org/PilotGo/prometheus-plugin/dao" "openeuler.org/PilotGo/prometheus-plugin/model" ) +func PullAlert() error { + var previousAlerts []model.AlertResponse + + daoAlert, err := dao.QueryAlerts() + if err != nil { + return err + } + + previousAlerts, err = pullAlert() + if err != nil { + return err + } + if err = processAlerts(daoAlert, previousAlerts); err != nil { + return err + } + + return nil +} func pullAlert() ([]model.AlertResponse, error) { remote := "http://" + config.Config().PrometheusServer.Addr + "/api/v1/alerts" @@ -47,3 +71,96 @@ func pullAlert() ([]model.AlertResponse, error) { } return data, nil } + +func processAlerts(old interface{}, new []model.AlertResponse) error { + + arrType := reflect.TypeOf(old) + if arrType.Kind() != reflect.Slice { + return fmt.Errorf("Unknown") + } + elemType := arrType.Elem() + + var oldMap map[string]interface{} + if elemType == reflect.TypeOf(model.AlertResponse{}) { + oldMap = make(map[string]interface{}) + for _, a := range old.([]model.AlertResponse) { + oldMap[getAlertKey(a)] = a + } + } else if elemType == reflect.TypeOf(model.Alert{}) { + oldMap = make(map[string]interface{}) + for _, o := range old.([]model.Alert) { + oldMap[getDBAlertKey(o)] = o + } + } + + newMap := make(map[string]model.AlertResponse) + for _, a := range new { + newMap[getAlertKey(a)] = a + } + + for key := range oldMap { + if _, ok := newMap[key]; ok { + delete(newMap, key) + } else { + if elemType == reflect.TypeOf(model.Alert{}) { + oldAlert := oldMap[key].(model.Alert) + err := dao.UpdateAlert(oldAlert.AlertName, oldAlert.GroupId, oldAlert.IP, &model.Alert{ + AlertEndTime: time.Now().Format("2006-01-02 15:04:05"), + }) + if err != nil { + logger.Error("Error update alert end time for alertname=%s,group=%s,ip=%s :%v", oldAlert.AlertName, oldAlert.GroupId, oldAlert.IP, err.Error()) + } + } else if elemType == reflect.TypeOf(model.AlertResponse{}) { + oldAlert := oldMap[key].(model.AlertResponse) + err := dao.UpdateAlert(oldAlert.Labels.AlertName, oldAlert.Labels.Group, strings.Split(oldAlert.Labels.Instance, ":")[0], &model.Alert{ + AlertEndTime: time.Now().Format("2006-01-02 15:04:05"), + }) + if err != nil { + logger.Error("Error update alert end time for alertname=%s,group=%s,ip=%s :%v", oldAlert.Labels.AlertName, oldAlert.Labels.Group, strings.Split(oldAlert.Labels.Instance, ":")[0], err.Error()) + } + } + } + } + for _, n := range newMap { + alertTime, err := utcTimeToAsia(n.ActiveAt) + if err != nil { + return err + } + err = dao.SaveAlertList(&model.Alert{ + AlertName: n.Labels.AlertName, + GroupId: n.Labels.Group, + IP: strings.Split(n.Labels.Instance, ":")[0], + AlertLevel: n.Labels.Severity, + Summary: n.Annotations.Summary, + Metric: n.Labels.Metric, + Description: n.Annotations.Description, + AlertTime: alertTime, + }) + if err != nil { + logger.Error("保存失败:%v", err.Error()) + } + } + return nil +} + +func getDBAlertKey(alert model.Alert) string { + return fmt.Sprintf("%s--%s--%s", alert.AlertName, alert.GroupId, alert.IP) +} +func getAlertKey(alert model.AlertResponse) string { + return fmt.Sprintf("%s--%s--%s", alert.Labels.AlertName, alert.Labels.Group, strings.Split(alert.Labels.Instance, ":")[0]) +} +func utcTimeToAsia(utcTimeStr string) (string, error) { + utcTime, err := time.Parse(time.RFC3339Nano, utcTimeStr) + if err != nil { + return "", err + } + + loc, err := time.LoadLocation("Asia/Shanghai") + if err != nil { + fmt.Println("加载时区出错:", err) + return "", err + } + + shanghaiTime := utcTime.In(loc) + return shanghaiTime.Format("2006-01-02 15:04:05"), nil +} -- Gitee