mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
fix(monitor): show alert count (#24028)
This commit is contained in:
@@ -64,4 +64,5 @@ type MonitorResourceJointDetails struct {
|
||||
SendState string `json:"send_state"`
|
||||
State string `json:"state"`
|
||||
IsSetShield bool `json:"is_set_shield"`
|
||||
AlertCount int `json:"alert_count"`
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ type MonitorResourceAlertListOptions struct {
|
||||
Ip string `help:"IP address" json:"ip"`
|
||||
StartTime time.Time `help:"start time for top query, format: 2025-01-01 00:00:00" json:"start_time"`
|
||||
EndTime time.Time `help:"end time for top query, format: 2025-01-01 00:00:00" json:"end_time"`
|
||||
Top int `help:"return top N resources by alert count (default: 5)" json:"top"`
|
||||
Top *int `help:"return top N resources by alert count (default: 5)" json:"top"`
|
||||
}
|
||||
|
||||
func (o *MonitorResourceAlertListOptions) GetMasterOpt() string {
|
||||
|
||||
@@ -16,6 +16,7 @@ package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -453,6 +454,12 @@ func min(a, b int) int {
|
||||
return b
|
||||
}
|
||||
|
||||
type SAlertRecordCount struct {
|
||||
Count int
|
||||
ResIds string
|
||||
AlertId string
|
||||
}
|
||||
|
||||
func (man *SMonitorResourceAlertManager) FetchCustomizeColumns(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
@@ -461,66 +468,104 @@ func (man *SMonitorResourceAlertManager) FetchCustomizeColumns(
|
||||
fields stringutils2.SSortedStrings,
|
||||
isList bool,
|
||||
) []monitor.MonitorResourceJointDetails {
|
||||
input := &monitor.MonitorResourceJointListInput{}
|
||||
query.Unmarshal(input)
|
||||
rows := make([]monitor.MonitorResourceJointDetails, len(objs))
|
||||
alertRecordIds := make([]string, len(objs))
|
||||
alertIds := make([]string, len(objs))
|
||||
resourceIds := make([]string, len(objs))
|
||||
for i := range rows {
|
||||
obj := objs[i].(*SMonitorResourceAlert)
|
||||
alertRecordIds[i] = obj.AlertRecordId
|
||||
alertIds[i] = obj.AlertId
|
||||
resourceIds[i] = obj.MonitorResourceId
|
||||
}
|
||||
records := map[string]SAlertRecord{}
|
||||
err := db.FetchModelObjectsByIds(AlertRecordManager, "id", alertRecordIds, &records)
|
||||
if err != nil {
|
||||
log.Errorf("fetch alert records error: %v", err)
|
||||
return rows
|
||||
}
|
||||
alerts := map[string]SCommonAlert{}
|
||||
err = db.FetchModelObjectsByIds(CommonAlertManager, "id", alertIds, &alerts)
|
||||
if err != nil {
|
||||
log.Errorf("fetch alerts error: %v", err)
|
||||
return rows
|
||||
}
|
||||
resources := map[string]SMonitorResource{}
|
||||
err = db.FetchModelObjectsByIds(MonitorResourceManager, "res_id", resourceIds, &resources)
|
||||
if err != nil {
|
||||
log.Errorf("fetch monitor resources error: %v", err)
|
||||
return rows
|
||||
}
|
||||
shields := make([]SAlertRecordShield, 0)
|
||||
err = AlertRecordShieldManager.Query().GE("end_time", time.Now()).In("res_id", resourceIds).In("alert_id", alertIds).All(&shields)
|
||||
if err != nil {
|
||||
log.Errorf("fetch alert record shields error: %v", err)
|
||||
return rows
|
||||
}
|
||||
shieldsMap := map[string]bool{}
|
||||
for _, shield := range shields {
|
||||
shieldsMap[fmt.Sprintf("%s-%s", shield.ResId, shield.AlertId)] = true
|
||||
}
|
||||
recordCountMap := map[string][]SAlertRecordCount{}
|
||||
if !input.StartTime.IsZero() && !input.EndTime.IsZero() {
|
||||
sq := AlertRecordManager.Query().GE("created_at", input.StartTime).LE("created_at", input.EndTime).In("alert_id", alertIds).SubQuery()
|
||||
q := sq.Query(
|
||||
sqlchemy.COUNT("count", sq.Field("id")),
|
||||
sq.Field("alert_id"),
|
||||
sq.Field("res_ids"),
|
||||
).GroupBy(sq.Field("alert_id"), sq.Field("res_ids"))
|
||||
|
||||
recordCount := []SAlertRecordCount{}
|
||||
err = q.All(&recordCount)
|
||||
if err != nil {
|
||||
log.Errorf("fetch alert records error: %v", err)
|
||||
return rows
|
||||
}
|
||||
for i := range recordCount {
|
||||
_, ok := recordCountMap[recordCount[i].AlertId]
|
||||
if !ok {
|
||||
recordCountMap[recordCount[i].AlertId] = make([]SAlertRecordCount, 0)
|
||||
}
|
||||
recordCountMap[recordCount[i].AlertId] = append(recordCountMap[recordCount[i].AlertId], recordCount[i])
|
||||
}
|
||||
}
|
||||
for i := range rows {
|
||||
rows[i] = monitor.MonitorResourceJointDetails{}
|
||||
rows[i] = objs[i].(*SMonitorResourceAlert).getMoreDetails(rows[i])
|
||||
obj := objs[i].(*SMonitorResourceAlert)
|
||||
rows[i].ResId = obj.MonitorResourceId
|
||||
rows[i].ResType = obj.ResType
|
||||
if record, ok := records[obj.AlertRecordId]; ok {
|
||||
rows[i].SendState = record.SendState
|
||||
rows[i].State = record.State
|
||||
}
|
||||
if alert, ok := alerts[obj.AlertId]; ok {
|
||||
rows[i].AlertName = alert.Name
|
||||
rows[i].Level = alert.Level
|
||||
silentPeriod, _ := alert.GetSilentPeriod()
|
||||
rule, _ := alert.GetAlertRules(silentPeriod)
|
||||
rows[i].AlertRule = jsonutils.Marshal(rule)
|
||||
}
|
||||
if res, ok := resources[obj.MonitorResourceId]; ok {
|
||||
rows[i].ResName = res.Name
|
||||
rows[i].ResType = res.ResType
|
||||
}
|
||||
if _, ok := shieldsMap[fmt.Sprintf("%s-%s", obj.MonitorResourceId, obj.AlertId)]; ok {
|
||||
rows[i].IsSetShield = true
|
||||
}
|
||||
if recordCount, ok := recordCountMap[obj.AlertId]; ok {
|
||||
rows[i].AlertCount = 0
|
||||
for _, record := range recordCount {
|
||||
if strings.Contains(record.ResIds, obj.MonitorResourceId) {
|
||||
rows[i].AlertCount += record.Count
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
func (obj *SMonitorResourceAlert) getMoreDetails(detail monitor.MonitorResourceJointDetails) monitor.MonitorResourceJointDetails {
|
||||
detail.ResType = obj.ResType
|
||||
detail.ResId = obj.MonitorResourceId
|
||||
resources, err := MonitorResourceManager.GetMonitorResources(monitor.MonitorResourceListInput{ResId: []string{obj.
|
||||
MonitorResourceId}})
|
||||
if err != nil {
|
||||
log.Errorf("getMonitorResource:%s err:%v", obj.MonitorResourceId, err)
|
||||
return detail
|
||||
}
|
||||
if len(resources) == 0 {
|
||||
return detail
|
||||
}
|
||||
if detail.ResType == "" {
|
||||
detail.ResType = resources[0].ResType
|
||||
}
|
||||
detail.ResName = resources[0].Name
|
||||
//detail.ResId = resources[0].ResId
|
||||
|
||||
if len(obj.AlertRecordId) != 0 {
|
||||
record, err := AlertRecordManager.GetAlertRecord(obj.AlertRecordId)
|
||||
if err != nil {
|
||||
log.Errorf("get alertRecord:%s err:%v", obj.AlertRecordId, err)
|
||||
return detail
|
||||
}
|
||||
//detail.AlertRule = record.AlertRule
|
||||
detail.SendState = record.SendState
|
||||
detail.State = record.State
|
||||
}
|
||||
alert, err := CommonAlertManager.GetAlert(obj.AlertId)
|
||||
if err != nil {
|
||||
log.Errorf("SMonitorResourceAlert get alert by id :%s err:%v", obj.AlertId, err)
|
||||
return detail
|
||||
}
|
||||
detail.AlertName = alert.Name
|
||||
detail.Level = alert.Level
|
||||
silentPeriod, _ := alert.GetSilentPeriod()
|
||||
rule, _ := alert.GetAlertRules(silentPeriod)
|
||||
detail.AlertRule = jsonutils.Marshal(rule)
|
||||
|
||||
now := time.Now()
|
||||
shields, err := AlertRecordShieldManager.GetRecordShields(monitor.AlertRecordShieldListInput{ResId: obj.MonitorResourceId,
|
||||
AlertId: obj.AlertId, EndTime: &now})
|
||||
if err != nil {
|
||||
log.Errorf("SMonitorResourceAlert get GetRecordShields by resId: %s, alertId: %s, err: %v", obj.MonitorResourceId, obj.AlertId, err)
|
||||
return detail
|
||||
}
|
||||
if len(shields) != 0 {
|
||||
detail.IsSetShield = true
|
||||
}
|
||||
return detail
|
||||
}
|
||||
|
||||
func (manager *SMonitorResourceAlertManager) ResourceScope() rbacscope.TRbacScope {
|
||||
return manager.SScopedResourceBaseManager.ResourceScope()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user