mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
support simple query
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package monitor
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/cmd/climc/shell"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules/monitor"
|
||||
options "yunion.io/x/onecloud/pkg/mcclient/options/monitor"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmd := shell.NewResourceCmd(monitor.UnifiedMonitorManager).WithKeyword("monitor")
|
||||
cmd.Show(&options.SimpleQueryOptions{})
|
||||
}
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
package monitor
|
||||
|
||||
import "time"
|
||||
|
||||
var (
|
||||
UNIFIED_MONITOR_FIELD_OPT_TYPE = []string{"Aggregations", "Selectors"}
|
||||
UNIFIED_MONITOR_GROUPBY_OPT_TYPE = []string{"time", "tag", "fill"}
|
||||
@@ -83,3 +85,25 @@ type MetricInputQuery struct {
|
||||
Signature string `json:"signature"`
|
||||
ShowMeta bool `json:"show_meta"`
|
||||
}
|
||||
|
||||
type SimpleQueryInput struct {
|
||||
// 资源Id, 可以不填, 代表查询指定监控的所有监控数据
|
||||
Id string `json:"id"`
|
||||
// 查询指定数据库
|
||||
// default: telegraf
|
||||
Database string `json:"database"`
|
||||
// 监控指标: https://github.com/codelinz/cloudpods/blob/monitor/pkg/cloudprovider/metrics.go
|
||||
MetricName string `json:"metric_name"`
|
||||
// 开始时间
|
||||
StartTime time.Time `json:"start_time"`
|
||||
// 结束时间
|
||||
EndTime time.Time `json:"end_time"`
|
||||
// 指定标签
|
||||
Tags map[string]string `json:"tags"`
|
||||
}
|
||||
|
||||
type SimpleQueryOutput struct {
|
||||
Id string `json:"id"`
|
||||
Time time.Time `json:"time"`
|
||||
Value float64 `json:"value"`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package monitor
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
)
|
||||
|
||||
type SimpleQueryOptions struct {
|
||||
Id string `json:"id"`
|
||||
Database string `json:"database"`
|
||||
MetricName string `json:"metric_name"`
|
||||
StartTime string `json:"start_time"`
|
||||
EndTime string `json:"end_time"`
|
||||
Tags []string `json:"tags"`
|
||||
}
|
||||
|
||||
func (o *SimpleQueryOptions) GetId() string {
|
||||
return "simple-query"
|
||||
}
|
||||
|
||||
func (o *SimpleQueryOptions) Params() (jsonutils.JSONObject, error) {
|
||||
ret := jsonutils.Marshal(o).(*jsonutils.JSONDict)
|
||||
ret.Remove("tags")
|
||||
tags := map[string]string{}
|
||||
for _, tag := range o.Tags {
|
||||
if strings.Contains(tag, "=") {
|
||||
info := strings.Split(tag, "=")
|
||||
if len(info) == 2 {
|
||||
tags[info[0]] = info[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(tags) > 0 {
|
||||
ret.Set("tags", jsonutils.Marshal(tags))
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/gotypes"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis/monitor"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
@@ -33,6 +34,7 @@ import (
|
||||
mq "yunion.io/x/onecloud/pkg/monitor/metricquery"
|
||||
"yunion.io/x/onecloud/pkg/monitor/tsdb"
|
||||
"yunion.io/x/onecloud/pkg/monitor/validators"
|
||||
"yunion.io/x/onecloud/pkg/util/influxdb"
|
||||
"yunion.io/x/onecloud/pkg/util/rbacutils"
|
||||
)
|
||||
|
||||
@@ -507,3 +509,87 @@ func fillSerieTags(series *tsdb.TimeSeriesSlice) {
|
||||
(*series)[i] = serie
|
||||
}
|
||||
}
|
||||
|
||||
func (self *SUnifiedMonitorManager) GetPropertySimpleQuery(ctx context.Context, userCred mcclient.TokenCredential,
|
||||
input *monitor.SimpleQueryInput) ([]monitor.SimpleQueryOutput, error) {
|
||||
if len(input.Database) == 0 {
|
||||
input.Database = "telegraf"
|
||||
}
|
||||
if len(input.MetricName) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("metric_name")
|
||||
}
|
||||
metric := strings.Split(input.MetricName, ".")
|
||||
if len(metric) != 2 {
|
||||
return nil, httperrors.NewInputParameterError("invalid metric_name %s", input.MetricName)
|
||||
}
|
||||
measurement, field := metric[0], metric[1]
|
||||
sqlstr := "select id, " + field + " from " + measurement + " where "
|
||||
if input.Tags == nil {
|
||||
input.Tags = map[string]string{}
|
||||
}
|
||||
if len(input.Id) > 0 {
|
||||
input.Tags["id"] = input.Id
|
||||
}
|
||||
if input.EndTime.IsZero() {
|
||||
input.EndTime = time.Now()
|
||||
}
|
||||
if input.StartTime.IsZero() {
|
||||
input.StartTime = input.EndTime.Add(time.Hour * -1)
|
||||
}
|
||||
if input.EndTime.Sub(input.StartTime).Hours() > 1 {
|
||||
return nil, httperrors.NewInputParameterError("The query interval is greater than one hour")
|
||||
}
|
||||
st := input.StartTime.Format("2006-01-02T15:04:05Z")
|
||||
et := input.EndTime.Format("2006-01-02T15:04:05Z")
|
||||
conditions := []string{}
|
||||
for k, v := range input.Tags {
|
||||
conditions = append(conditions, fmt.Sprintf("%s = %s", k, v))
|
||||
}
|
||||
conditions = append(conditions, fmt.Sprintf("time >= '%s'", st))
|
||||
conditions = append(conditions, fmt.Sprintf("time <= '%s'", et))
|
||||
sqlstr += strings.Join(conditions, " and ")
|
||||
dataSource, err := DataSourceManager.GetDefaultSource()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "s.GetDefaultSource")
|
||||
}
|
||||
db := influxdb.NewInfluxdb(dataSource.Url)
|
||||
err = db.SetDatabase(input.Database)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("not support database %s", input.Database)
|
||||
}
|
||||
dbRtn, err := db.Query(sqlstr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "sql selected error")
|
||||
}
|
||||
ret := []monitor.SimpleQueryOutput{}
|
||||
for _, dbResults := range dbRtn {
|
||||
for _, dbResult := range dbResults {
|
||||
for _, value := range dbResult.Values {
|
||||
if len(value) != 3 ||
|
||||
gotypes.IsNil(value[0]) ||
|
||||
gotypes.IsNil(value[1]) ||
|
||||
gotypes.IsNil(value[2]) {
|
||||
continue
|
||||
}
|
||||
timestamp, err := value[0].Int()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
id, err := value[1].GetString()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
v, err := value[2].Float()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ret = append(ret, monitor.SimpleQueryOutput{
|
||||
Id: id,
|
||||
Time: time.UnixMilli(timestamp),
|
||||
Value: v,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user