From ecd4a9407984dae848879273e2ccc4d763fcdf1e Mon Sep 17 00:00:00 2001 From: zhaoxiangchun <1422928955@qq.com> Date: Thu, 28 May 2020 21:17:48 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9B=91=E6=8E=A7=E6=95=B0=E6=8D=AE=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E5=A2=9E=E5=8A=A0=E5=AF=B9=E4=BB=BB=E6=84=8F=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E8=8C=83=E5=9B=B4=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/apis/monitor/unifiedmonitor_const.go | 1 + pkg/monitor/models/unifiedmonitor.go | 47 ++++++++++++++++------- pkg/monitor/tsdb/driver/influxdb/query.go | 7 +++- pkg/monitor/validators/validators.go | 46 ++++++++++++++++------ 4 files changed, 75 insertions(+), 26 deletions(-) diff --git a/pkg/apis/monitor/unifiedmonitor_const.go b/pkg/apis/monitor/unifiedmonitor_const.go index cf462ea9ea..4c2a182a9d 100644 --- a/pkg/apis/monitor/unifiedmonitor_const.go +++ b/pkg/apis/monitor/unifiedmonitor_const.go @@ -22,6 +22,7 @@ type MetricFunc struct { type MetricInputQuery struct { From string `json:"from"` + To string `json:"to"` Interval string `json:"interval"` MetricQuery []*AlertQuery `json:"metric_query"` } diff --git a/pkg/monitor/models/unifiedmonitor.go b/pkg/monitor/models/unifiedmonitor.go index c65ab05850..87119657b5 100644 --- a/pkg/monitor/models/unifiedmonitor.go +++ b/pkg/monitor/models/unifiedmonitor.go @@ -149,7 +149,7 @@ func (self *SUnifiedMonitorManager) PerformQuery(ctx context.Context, userCred m } for _, q := range inputQuery.MetricQuery { setDefaultValue(q, inputQuery) - err = self.ValidateInputQuery(*q) + err = self.ValidateInputQuery(q) if err != nil { return jsonutils.NewDict(), err } @@ -178,37 +178,56 @@ func doQuery(query monitor.MetricInputQuery) (*mq.Metrics, error) { return metricQ.ExecuteQuery() } -func (self *SUnifiedMonitorManager) ValidateInputQuery(query monitor.AlertQuery) error { +func (self *SUnifiedMonitorManager) ValidateInputQuery(query *monitor.AlertQuery) error { if query.From == "" { query.From = "30m" } if query.Model.Interval == "" { query.Model.Interval = "5m" } + if query.To == "" { + query.To = "now" + } if _, err := time.ParseDuration(query.Model.Interval); err != nil { return httperrors.NewInputParameterError("Invalid interval format: %s", query.Model.Interval) } - return validators.ValidateAlertConditionQuery(query) + return validators.ValidateSelectOfMetricQuery(*query) } func setDefaultValue(query *monitor.AlertQuery, inputQuery *monitor.MetricInputQuery) { setDataSourceId(query) query.From = inputQuery.From - query.To = "now" + query.To = inputQuery.To query.Model.Interval = inputQuery.Interval + if len(query.Model.GroupBy) == 0 { - query.Model.GroupBy = append(query.Model.GroupBy, monitor.MetricQueryPart{ - Type: "field", - Params: []string{"*"}, + query.Model.GroupBy = append(query.Model.GroupBy, + monitor.MetricQueryPart{ + Type: "field", + Params: []string{"*"}, + }) + } + + query.Model.GroupBy = append(query.Model.GroupBy, + monitor.MetricQueryPart{ + Type: "time", + Params: []string{inputQuery.Interval}, + }, + monitor.MetricQueryPart{ + Type: "fill", + Params: []string{"linear"}, }) + + for i, sel := range query.Model.Selects { + if len(sel) > 1 { + continue + } + sel = append(sel, monitor.MetricQueryPart{ + Type: "mean", + Params: []string{}, + }) + query.Model.Selects[i] = sel } - //query.Model.GroupBy = append(query.Model.GroupBy, monitor.MetricQueryPart{ - // Type: "time", - // Params: []string{inputQuery.Interval}, - //}, monitor.MetricQueryPart{ - // Type: "fill", - // Params: []string{"none"}, - //}) } func setDataSourceId(query *monitor.AlertQuery) { diff --git a/pkg/monitor/tsdb/driver/influxdb/query.go b/pkg/monitor/tsdb/driver/influxdb/query.go index 21bb92d1e3..615a698c95 100644 --- a/pkg/monitor/tsdb/driver/influxdb/query.go +++ b/pkg/monitor/tsdb/driver/influxdb/query.go @@ -87,7 +87,12 @@ func (query *Query) renderTags() []string { } func (query *Query) renderTimeFilter(queryCtx *tsdb.TsdbQuery) string { - from := "now() - " + queryCtx.TimeRange.From + from := "" + if strings.Contains(queryCtx.TimeRange.From, "now-") { + from = "now() - " + strings.Replace(queryCtx.TimeRange.From, "now-", "", 1) + } else { + from = "now() - " + queryCtx.TimeRange.From + } to := "" if queryCtx.TimeRange.To != "now" && queryCtx.TimeRange.To != "" { diff --git a/pkg/monitor/validators/validators.go b/pkg/monitor/validators/validators.go index 051629b572..65feafad6b 100644 --- a/pkg/monitor/validators/validators.go +++ b/pkg/monitor/validators/validators.go @@ -99,24 +99,48 @@ func ValidateAlertQueryModel(input monitor.MetricQuery) error { return nil } -func ValidateSelectOfMetricQuery(input monitor.MetricQuery) error { - for _, sel := range input.Selects { +func ValidateSelectOfMetricQuery(input monitor.AlertQuery) error { + if err := ValidateFromAndToValue(input); err != nil { + return err + } + + if err := ValidateAlertQueryModel(input.Model); err != nil { + return err + } + + for _, sel := range input.Model.Selects { if len(sel) == 0 { return httperrors.NewInputParameterError("select for nothing in query") } } - if len(input.GroupBy) == 0 { - input.GroupBy = append(input.GroupBy, monitor.MetricQueryPart{ - Type: "fill", - Params: []string{"none"}, - }, monitor.MetricQueryPart{ - Type: "time", - Params: []string{input.Interval}, - }) - } return nil } +func ValidateFromAndToValue(input monitor.AlertQuery) error { + fromRaw := strings.Replace(input.From, "now-", "", 1) + + fromDur, err := time.ParseDuration("-" + fromRaw) + if err != nil { + return err + } + + if input.To == "now" { + return nil + } else if strings.HasPrefix(input.To, "now-") { + withoutNow := strings.Replace(input.To, "now-", "", 1) + + toDur, err := time.ParseDuration("-" + withoutNow) + if err == nil { + if toDur >= fromDur { + return nil + } + return httperrors.NewInputParameterError("query from:%s,to:%s err", input.From, input.To) + } + return err + } + return httperrors.NewInputParameterError("query to:%s format err", input.To) +} + func ValidateAlertConditionReducer(input monitor.Condition) error { return nil }