From aedf73f14c36b876771646cf5c856987742c6d93 Mon Sep 17 00:00:00 2001 From: zhaoxiangchun <1422928955@qq.com> Date: Tue, 19 Jan 2021 17:28:13 +0800 Subject: [PATCH] feat(monitor): Lists the records that are currently alarting --- pkg/apis/monitor/alertrecord.go | 9 ++-- pkg/mcclient/modules/mod_alert_record.go | 2 +- pkg/mcclient/options/meter/costreports.go | 8 +-- pkg/mcclient/options/monitor/alertrecord.go | 8 +-- pkg/monitor/models/alertrecord.go | 60 +++++++++++++++------ 5 files changed, 60 insertions(+), 27 deletions(-) diff --git a/pkg/apis/monitor/alertrecord.go b/pkg/apis/monitor/alertrecord.go index 69b0973f9a..d0af8ceea4 100644 --- a/pkg/apis/monitor/alertrecord.go +++ b/pkg/apis/monitor/alertrecord.go @@ -9,10 +9,11 @@ type AlertRecordListInput struct { apis.EnabledResourceBaseListInput apis.StatusStandaloneResourceListInput - AlertId string `json:"alert_id"` - Level string `json:"level"` - State string `json:"state"` - ResType []string `json:"res_type"` + AlertId string `json:"alert_id"` + Level string `json:"level"` + State string `json:"state"` + ResTypes []string `json:"res_types"` + Alerting bool `json:"alerting"` } type AlertRecordDetails struct { diff --git a/pkg/mcclient/modules/mod_alert_record.go b/pkg/mcclient/modules/mod_alert_record.go index 5697c5e8c6..14276e1351 100644 --- a/pkg/mcclient/modules/mod_alert_record.go +++ b/pkg/mcclient/modules/mod_alert_record.go @@ -17,7 +17,7 @@ func init() { func NewAlertRecordManager() *SAlertRecordManager { man := NewMonitorV2Manager("alertrecord", "alertrecords", - []string{"id", "alert_id", "level", "state", "eval_data"}, + []string{"id", "alert_name", "res_type", "level", "state", "res_num", "eval_data"}, []string{}) return &SAlertRecordManager{ ResourceManager: &man, diff --git a/pkg/mcclient/options/meter/costreports.go b/pkg/mcclient/options/meter/costreports.go index e0d4c98916..dbd7f9ebca 100644 --- a/pkg/mcclient/options/meter/costreports.go +++ b/pkg/mcclient/options/meter/costreports.go @@ -17,9 +17,9 @@ func (opt *CostReportListOptions) Params() (jsonutils.JSONObject, error) { type CostReportCreateOptions struct { Scope string `help:"scope of cost report" json:"scope"` - PeriodType string `help:"period of cost report send, example:"month/week/day" json:"period_type"` + PeriodType string `help:"period of cost report send, example:month/week/day" json:"period_type"` Day int `help:"day of cost report send" json:"day"` - ColonTimer string `help:"hour and minute of cost report send, example:"HH:mm" json:"colon_timer"` + ColonTimer string `help:"hour and minute of cost report send, example:HH:mm" json:"colon_timer"` Emails []string `help:"emails of cost report send" json:"emails"` StartRun bool `help:"whether cost report sends instantly" json:"start_run"` } @@ -31,9 +31,9 @@ func (opt *CostReportCreateOptions) Params() (jsonutils.JSONObject, error) { type CostReportUpdateOptions struct { ID string `help:"ID of cost report" json:"-"` - PeriodType string `help:"period of cost report send, example:"month/week/day" json:"period_type"` + PeriodType string `help:"period of cost report send, example:month/week/day" json:"period_type"` Day int `help:"day of cost report send" json:"day"` - ColonTimer string `help:"hour and minute of cost report send, example:"HH:mm" json:"colon_timer"` + ColonTimer string `help:"hour and minute of cost report send, example:HH:mm" json:"colon_timer"` Emails []string `help:"emails of cost report send" json:"emails"` StartRun bool `help:"whether cost report sends instantly" json:"start_run"` } diff --git a/pkg/mcclient/options/monitor/alertrecord.go b/pkg/mcclient/options/monitor/alertrecord.go index e95305bd25..e152c4da79 100644 --- a/pkg/mcclient/options/monitor/alertrecord.go +++ b/pkg/mcclient/options/monitor/alertrecord.go @@ -9,9 +9,11 @@ import ( type AlertRecordListOptions struct { options.BaseListOptions - AlertId string `help:"id of alert"` - Level string `help:"alert level"` - State string `help:"alert state"` + AlertId string `help:"id of alert"` + Level string `help:"alert level"` + State string `help:"alert state"` + ResTypes []string `json:"res_types"` + Alerting bool `json:"alerting"` } func (o *AlertRecordListOptions) Params() (jsonutils.JSONObject, error) { diff --git a/pkg/monitor/models/alertrecord.go b/pkg/monitor/models/alertrecord.go index 38b98ead16..2be0587b86 100644 --- a/pkg/monitor/models/alertrecord.go +++ b/pkg/monitor/models/alertrecord.go @@ -93,23 +93,42 @@ func (manager *SAlertRecordManager) ListItemFilter( if err != nil { return nil, errors.Wrap(err, "SScopedResourceBaseManager.ListItemFilter") } + if query.Alerting { + alertingQuery := manager.getAlertingRecordQuery().SubQuery() + + q.Join(alertingQuery, sqlchemy.Equals(q.Field("alert_id"), alertingQuery.Field("alert_id"))).Filter( + sqlchemy.Equals(q.Field("created_at"), alertingQuery.Field("max_created_at"))) + } if len(query.Level) != 0 { - q = q.Equals("level", query.Level) + q.Filter(sqlchemy.Equals(q.Field("level"), query.Level)) } if len(query.State) != 0 { - q = q.Equals("state", query.State) + q.Filter(sqlchemy.Equals(q.Field("state"), query.State)) } if len(query.AlertId) != 0 { - q = q.Equals("alert_id", query.AlertId) + q.Filter(sqlchemy.Equals(q.Field("alert_id"), query.AlertId)) } else { q = q.IsNotEmpty("res_type").IsNotNull("res_type") } - if len(query.ResType) != 0 { - q = q.Equals("res_type", query.ResType) + if len(query.ResTypes) != 0 { + q.Filter(sqlchemy.In(q.Field("res_type"), query.ResTypes)) } return q, nil } +func (man *SAlertRecordManager) getAlertingRecordQuery() *sqlchemy.SQuery { + alertsQuery := CommonAlertManager.Query("id").Equals("state", monitor.AlertStateAlerting).IsTrue("enabled").IsNull("used_by").SubQuery() + recordSub := man.Query().SubQuery() + + recordQuery := recordSub.Query(recordSub.Field("alert_id"), sqlchemy.MAX("max_created_at", recordSub.Field("created_at"))) + recordQuery.Equals("state", monitor.AlertStateAlerting) + recordQuery.In("alert_id", alertsQuery) + recordQuery.IsNotNull("res_type").IsNotEmpty("res_type") + recordQuery.GroupBy("alert_id") + return recordQuery + +} + func (man *SAlertRecordManager) GetAlertRecord(id string) (*SAlertRecord, error) { obj, err := man.FetchById(id) if err != nil { @@ -306,10 +325,17 @@ func (manager *SAlertRecordManager) AllowGetPropertyTotalAlert(ctx context.Conte func (manager *SAlertRecordManager) GetPropertyTotalAlert(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (jsonutils.JSONObject, error) { - - alertRecords, err := manager.getNowAlertingRecord(ctx, userCred, query) + input := new(monitor.AlertRecordListInput) + err := query.Unmarshal(input) + if err != nil { + return nil, errors.Wrap(err, "Unmarshal AlertRecordListInput error") + } + alertRecords, err := manager.getNowAlertingRecord(ctx, userCred, *input) if err != nil { return nil, errors.Wrap(err, "getNowAlertingRecord error") + } + if input.Details != nil && *input.Details { + } alertCountMap := jsonutils.NewDict() for _, record := range alertRecords { @@ -328,18 +354,22 @@ func (manager *SAlertRecordManager) GetPropertyTotalAlert(ctx context.Context, u } func (manager *SAlertRecordManager) getNowAlertingRecord(ctx context.Context, userCred mcclient.TokenCredential, - param jsonutils.JSONObject) ([]SAlertRecord, error) { - now := time.Now() - startTime := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 1, now.Location()) + input monitor.AlertRecordListInput) ([]SAlertRecord, error) { + //now := time.Now() + //startTime := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 1, now.Location()) query := manager.Query() - scope, _ := param.GetString("scope") - query = manager.FilterByOwner(query, userCred, rbacutils.String2Scope(scope)) - query = query.GE("created_at", startTime.UTC().Format(timeutils.MysqlTimeFormat)) + query = manager.FilterByOwner(query, userCred, rbacutils.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") - alertsQuery := CommonAlertManager.Query("id").Equals("state", monitor.AlertStateAlerting).IsNull("used_by") - alertsQuery = CommonAlertManager.FilterByOwner(alertsQuery, userCred, rbacutils.String2Scope(scope)) + if len(input.ResTypes) != 0 { + query = query.In("res_type", input.ResTypes) + } + + alertsQuery := CommonAlertManager.Query("id").Equals("state", monitor.AlertStateAlerting).IsTrue("enabled"). + IsNull("used_by") + alertsQuery = CommonAlertManager.FilterByOwner(alertsQuery, userCred, rbacutils.String2Scope(input.Scope)) alerts := make([]SCommonAlert, 0) records := make([]SAlertRecord, 0) err := db.FetchModelObjects(CommonAlertManager, alertsQuery, &alerts)