mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 02:37:24 +08:00
fix(monitor): history alert report (#23278)
This commit is contained in:
@@ -24,4 +24,5 @@ func init() {
|
||||
cmd.List(new(options.AlertRecordListOptions))
|
||||
cmd.Show(new(options.AlertRecordShowOptions))
|
||||
cmd.GetProperty(new(options.AlertRecordTotalOptions))
|
||||
cmd.GetProperty(new(options.AlertRecordHistoryAlertOptions))
|
||||
}
|
||||
|
||||
@@ -53,20 +53,6 @@ type AlertRecordDetails struct {
|
||||
TriggerTime time.Time
|
||||
}
|
||||
|
||||
func (self AlertRecordDetails) GetMetricTags() map[string]string {
|
||||
ret := map[string]string{
|
||||
"id": self.Id,
|
||||
"alert_id": self.AlertId,
|
||||
"alert_name": self.AlertName,
|
||||
"domain_id": self.DomainId,
|
||||
"project_domain": self.ProjectDomain,
|
||||
"res_type": self.ResType,
|
||||
"tenant": self.Tenant,
|
||||
"tenant_id": self.TenantId,
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type AlertRecordCreateInput struct {
|
||||
apis.StandaloneResourceCreateInput
|
||||
|
||||
@@ -99,3 +85,26 @@ type AlertRecordRule struct {
|
||||
SilentPeriod string `json:"silent_period"`
|
||||
Reducer string `json:"reducer"`
|
||||
}
|
||||
|
||||
type AlertRecordHistoryAlertData struct {
|
||||
ProjectId string `json:"project_id"`
|
||||
Project string `json:"project"`
|
||||
DomainId string `json:"domain_id"`
|
||||
Domain string `json:"domain"`
|
||||
ResType string `json:"res_type"`
|
||||
ResNum int64 `json:"res_num"`
|
||||
}
|
||||
|
||||
func (self AlertRecordHistoryAlertData) GetMetricTags() map[string]string {
|
||||
return map[string]string{
|
||||
"project_id": self.ProjectId,
|
||||
"domain_id": self.DomainId,
|
||||
"domain": self.Domain,
|
||||
"project": self.Project,
|
||||
"res_type": self.ResType,
|
||||
}
|
||||
}
|
||||
|
||||
type AlertRecordHistoryAlert struct {
|
||||
Data []AlertRecordHistoryAlertData `json:"data"`
|
||||
}
|
||||
|
||||
+17
-50
@@ -19,13 +19,12 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/tsdb"
|
||||
"yunion.io/x/onecloud/pkg/cloutpost/options"
|
||||
"yunion.io/x/onecloud/pkg/cloudmon/options"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/auth"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/monitor"
|
||||
@@ -40,67 +39,35 @@ const (
|
||||
func AlertHistoryReport(ctx context.Context, userCred mcclient.TokenCredential, isStart bool) {
|
||||
err := func() error {
|
||||
s := auth.GetAdminSession(ctx, options.Options.Region)
|
||||
params := map[string]interface{}{
|
||||
"field": "res_type",
|
||||
"scope": "system",
|
||||
"filter.0": fmt.Sprintf("created_at.ge('%s')", time.Now().Add(time.Hour*-24)),
|
||||
}
|
||||
ret, err := monitor.AlertRecordManager.Get(s, "distinct-field", jsonutils.Marshal(params))
|
||||
resp, err := monitor.AlertRecordManager.Get(s, "history-alert", nil)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "distinct-filed")
|
||||
return errors.Wrapf(err, "history-alert")
|
||||
}
|
||||
alerts := api.AlertRecordHistoryAlert{}
|
||||
err = resp.Unmarshal(&alerts)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "Unmarshal AlertRecordHistoryAlert")
|
||||
}
|
||||
resTypes := []string{}
|
||||
ret.Unmarshal(&resTypes, "res_type")
|
||||
metrics := []influxdb.SMetricData{}
|
||||
for _, resType := range resTypes {
|
||||
records := []api.AlertRecordDetails{}
|
||||
for {
|
||||
query := map[string]interface{}{
|
||||
"limit": 40,
|
||||
"offset": len(records),
|
||||
"@state": "alerting",
|
||||
"scope": "system",
|
||||
"filter.0": fmt.Sprintf(`res_type.equals('%s')`, resType),
|
||||
"filter.1": fmt.Sprintf("created_at.ge('%s')", time.Now().Add(time.Hour*-24)),
|
||||
}
|
||||
ret, err := monitor.AlertRecordManager.List(s, jsonutils.Marshal(query))
|
||||
if err != nil {
|
||||
log.Errorf("AlertRecordManager.List error: %v", err)
|
||||
break
|
||||
}
|
||||
part := []api.AlertRecordDetails{}
|
||||
err = jsonutils.Update(&part, ret.Data)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
records = append(records, part...)
|
||||
if len(records) >= ret.Total {
|
||||
break
|
||||
}
|
||||
}
|
||||
for _, alert := range alerts.Data {
|
||||
metric := influxdb.SMetricData{}
|
||||
metric.Name = ALERT_RECORD_HISTORY_MEASUREMENT
|
||||
cnt := 0
|
||||
for i, record := range records {
|
||||
cnt += int(record.ResNum)
|
||||
if i == 0 {
|
||||
for k, v := range record.GetMetricTags() {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: k,
|
||||
Value: v,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
metric.Timestamp = time.Now()
|
||||
metric.Metrics = []influxdb.SKeyValue{
|
||||
{
|
||||
Key: "res_num",
|
||||
Value: fmt.Sprintf("%d", cnt),
|
||||
Value: fmt.Sprintf("%d", alert.ResNum),
|
||||
},
|
||||
}
|
||||
for k, v := range alert.GetMetricTags() {
|
||||
metric.Tags = append(metric.Tags, influxdb.SKeyValue{
|
||||
Key: k,
|
||||
Value: v,
|
||||
})
|
||||
}
|
||||
metrics = append(metrics, metric)
|
||||
}
|
||||
|
||||
urls, err := tsdb.GetDefaultServiceSourceURLs(s, options.Options.SessionEndpointType)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetServiceURLs")
|
||||
|
||||
@@ -64,6 +64,18 @@ func (o *AlertRecordTotalOptions) Property() string {
|
||||
return "total-alert"
|
||||
}
|
||||
|
||||
type AlertRecordHistoryAlertOptions struct {
|
||||
options.BaseListOptions
|
||||
}
|
||||
|
||||
func (o *AlertRecordHistoryAlertOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return options.ListStructToParams(o)
|
||||
}
|
||||
|
||||
func (o *AlertRecordHistoryAlertOptions) Property() string {
|
||||
return "history-alert"
|
||||
}
|
||||
|
||||
type AlertRecordShieldListOptions struct {
|
||||
options.BaseListOptions
|
||||
|
||||
|
||||
@@ -459,47 +459,72 @@ func (manager *SAlertRecordManager) GetPropertyTotalAlert(ctx context.Context, u
|
||||
return alertCountMap, nil
|
||||
}
|
||||
|
||||
/*func (manager *SAlertRecordManager) getNowAlertingRecord(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
input monitor.AlertRecordListInput) ([]SAlertRecord, error) {
|
||||
//now := time.Now()
|
||||
//startTime := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 1, now.Location())
|
||||
ownerId, err := manager.FetchOwnerId(ctx, jsonutils.Marshal(&input))
|
||||
// 获取过去一天的报警历史分布
|
||||
func (manager *SAlertRecordManager) GetPropertyHistoryAlert(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
) (*monitor.AlertRecordHistoryAlert, error) {
|
||||
q := manager.Query().GE("created_at", time.Now().Add(-time.Hour*24)).IsNotEmpty("eval_data").NotEquals("state", monitor.AlertStateOK)
|
||||
alerts := []SAlertRecord{}
|
||||
err := q.All(&alerts)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "FetchOwnerId error")
|
||||
}
|
||||
if ownerId == nil {
|
||||
ownerId = userCred
|
||||
}
|
||||
query := manager.Query()
|
||||
query = manager.FilterByOwner(ctx, query, manager, userCred, ownerId, rbacscope.String2Scope(input.Scope))
|
||||
//query = query.GE("created_at", startTime.UTC().Format(timeutils.MysqlTimeFormat))
|
||||
query = query.Equals("state", monitor.AlertStateAlerting)
|
||||
query = query.IsNotNull("res_type").IsNotEmpty("res_type").Desc("created_at")
|
||||
|
||||
if len(input.ResType) != 0 {
|
||||
query = query.Equals("res_type", input.ResType)
|
||||
}
|
||||
|
||||
alertsQuery := CommonAlertManager.Query("id").Equals("state", monitor.AlertStateAlerting).IsTrue("enabled").
|
||||
IsNull("used_by")
|
||||
alertsQuery = CommonAlertManager.FilterByOwner(ctx, alertsQuery, CommonAlertManager, userCred, userCred, rbacscope.String2Scope(input.Scope))
|
||||
alerts := make([]SCommonAlert, 0)
|
||||
records := make([]SAlertRecord, 0)
|
||||
err = db.FetchModelObjects(CommonAlertManager, alertsQuery, &alerts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, "q.All")
|
||||
}
|
||||
ret := map[string]map[string]map[string]int64{}
|
||||
domainIds, projectIds := []string{}, []string{}
|
||||
domainMap := map[string]string{}
|
||||
projectMap := map[string]string{}
|
||||
for _, alert := range alerts {
|
||||
tmp := *query
|
||||
recordModel, err := db.NewModelObject(manager)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "NewModelObject %s", manager.Keyword())
|
||||
if _, ok := ret[alert.DomainId]; !ok {
|
||||
ret[alert.DomainId] = map[string]map[string]int64{}
|
||||
domainIds = append(domainIds, alert.DomainId)
|
||||
}
|
||||
if err := (&tmp).Equals("alert_id", alert.GetId()).First(recordModel); err == nil {
|
||||
records = append(records, *(recordModel.(*SAlertRecord)))
|
||||
} else {
|
||||
log.Warningf("get records of alert_id %s error: %v", alert.GetId(), err)
|
||||
if _, ok := ret[alert.DomainId][alert.ProjectId]; !ok {
|
||||
ret[alert.DomainId][alert.ProjectId] = map[string]int64{}
|
||||
projectIds = append(projectIds, alert.ProjectId)
|
||||
}
|
||||
if _, ok := ret[alert.DomainId][alert.ProjectId][alert.ResType]; !ok {
|
||||
ret[alert.DomainId][alert.ProjectId][alert.ResType] = 0
|
||||
}
|
||||
eval := make([]monitor.EvalMatch, 0)
|
||||
err := alert.EvalData.Unmarshal(&eval)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ret[alert.DomainId][alert.ProjectId][alert.ResType] += int64(len(eval))
|
||||
}
|
||||
domains := []db.STenant{}
|
||||
err = db.TenantCacheManager.GetDomainQuery().In("id", domainIds).All(&domains)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetDomainQuery.In.All")
|
||||
}
|
||||
for _, domain := range domains {
|
||||
domainMap[domain.Id] = domain.Name
|
||||
}
|
||||
|
||||
projects := []db.STenant{}
|
||||
err = db.TenantCacheManager.GetTenantQuery().In("id", projectIds).All(&projects)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetTenantQuery.In.All")
|
||||
}
|
||||
for _, project := range projects {
|
||||
projectMap[project.Id] = project.Name
|
||||
}
|
||||
result := &monitor.AlertRecordHistoryAlert{}
|
||||
for domainId, projects := range ret {
|
||||
for projectId, resTypes := range projects {
|
||||
for resType, alert := range resTypes {
|
||||
result.Data = append(result.Data, monitor.AlertRecordHistoryAlertData{
|
||||
ProjectId: projectId,
|
||||
Project: projectMap[projectId],
|
||||
DomainId: domainId,
|
||||
Domain: domainMap[domainId],
|
||||
ResType: resType,
|
||||
ResNum: alert,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return records, nil
|
||||
}*/
|
||||
return result, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user