feat(climc): add monitor-unifiedmonitor-query command

This commit is contained in:
Zexi Li
2023-12-08 10:05:02 +08:00
parent 8eaa742333
commit 590cba97bb
6 changed files with 100 additions and 21 deletions
+17 -1
View File
@@ -15,7 +15,10 @@
package monitor
import (
"yunion.io/x/pkg/errors"
"yunion.io/x/onecloud/cmd/climc/shell"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modules/monitor"
options "yunion.io/x/onecloud/pkg/mcclient/options/monitor"
)
@@ -24,5 +27,18 @@ func init() {
cmd := shell.NewResourceCmd(monitor.UnifiedMonitorManager).SetPrefix("monitor")
cmd.Show(&options.SimpleQueryOptions{})
cmd.GetProperty(&options.MeasurementsQueryOptions{})
cmd.GetProperty(&options.DatabasesQueryOptions{})
// cmd.GetProperty(&options.DatabasesQueryOptions{})
R(new(options.MetricQueryOptions), "monitor-unifiedmonitor-query", "Perform metrics query", func(s *mcclient.ClientSession, opts *options.MetricQueryOptions) error {
input, err := opts.GetQueryInput()
if err != nil {
return err
}
resp, err := monitor.UnifiedMonitorManager.PerformQuery(s, input)
if err != nil {
return errors.Wrap(err, "PerformQuery")
}
printObject(resp)
return nil
})
}
-15
View File
@@ -1,15 +0,0 @@
package monitor
import (
"testing"
"yunion.io/x/jsonutils"
"yunion.io/x/log"
)
func TestMetricQueryInput_AddMetric(t *testing.T) {
q := NewMetricQuery("cpu")
q.Select("usage_active").MEAN()
q.Select("usage_active_per_core")
log.Infof("%s", jsonutils.Marshal(q))
}
@@ -15,6 +15,8 @@
package monitor
import (
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/apis/monitor"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
@@ -47,5 +49,6 @@ func NewUnifiedMonitorManager() *SUnifiedMonitorManager {
}
}
func (m *SUnifiedMonitorManager) PerformQuery(s *mcclient.ClientSession, input *monitor.MetricQueryInput) {
func (m *SUnifiedMonitorManager) PerformQuery(s *mcclient.ClientSession, input *monitor.MetricQueryInput) (jsonutils.JSONObject, error) {
return m.PerformClassAction(s, "query", jsonutils.Marshal(input))
}
+2 -2
View File
@@ -24,8 +24,8 @@ 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"`
StartTime string `json:"start_time" help:"e.g.: 2023-12-06T21:54:42.123Z"`
EndTime string `json:"end_time" help:"e.g.: 2023-12-18T21:54:42.123Z"`
Tags []string `json:"tags"`
}
+76 -1
View File
@@ -14,7 +14,16 @@
package monitor
import "yunion.io/x/jsonutils"
import (
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
api "yunion.io/x/onecloud/pkg/apis/monitor"
"yunion.io/x/onecloud/pkg/mcclient/modules/monitor"
)
type MeasurementsQueryOptions struct {
Scope string `json:"scope"`
@@ -39,3 +48,69 @@ func (o DatabasesQueryOptions) Params() (jsonutils.JSONObject, error) {
func (o DatabasesQueryOptions) Property() string {
return "databases"
}
type MetricQueryOptions struct {
MeasurementsQueryOptions
MEASUREMENT string `help:"metric measurement. e.g.: cpu, vm_cpu, vm_mem, disk..."`
FIELD string `help:"metric field. e.g.: usage_active, free..."`
Interval string `help:"metric interval. e.g.: 5m, 1h"`
From string `help:"start time(RFC3339 format). e.g.: 2023-12-06T21:54:42.123Z"`
To string `help:"end time(RFC3339 format). e.g.: 2023-12-18T21:54:42.123Z"`
Tags []string `help:"filter tags. e.g.: vm_name=vm1"`
GroupBy []string `help:"group by tag"`
UseMean bool `help:"calcuate mean result for field"`
SkipCheckSeries bool `help:"skip checking series: not fetch extra tags from region service"`
}
func (o MetricQueryOptions) GetQueryInput() (*api.MetricQueryInput, error) {
input := monitor.NewMetricQueryInput(o.MEASUREMENT)
input.Interval(o.Interval)
if o.SkipCheckSeries {
input.SkipCheckSeries(true)
}
input.Scope(o.Scope)
// parse time
if o.From != "" {
fromTime, err := time.Parse(time.RFC3339, o.From)
if err != nil {
return nil, errors.Wrapf(err, "invalid from time: %q", o.From)
}
input.From(fromTime)
}
if o.To != "" {
toTime, err := time.Parse(time.RFC3339, o.To)
if err != nil {
return nil, errors.Wrapf(err, "invalid to time: %q", o.To)
}
input.To(toTime)
}
sel := input.Selects().Select(o.FIELD)
if o.UseMean {
sel.MEAN()
}
where := input.Where()
for _, tag := range o.Tags {
if strings.Contains(tag, "=") {
info := strings.Split(tag, "=")
if len(info) == 2 {
where.Equal(info[0], info[1])
} else {
return nil, errors.Errorf("invalid tag: %q, len: %d", tag, len(info))
}
} else {
return nil, errors.Errorf("invalid tag: %q", tag)
}
}
groupBy := input.GroupBy()
for _, tag := range o.GroupBy {
groupBy.TAG(tag)
}
return input.ToQueryData(), nil
}
+1 -1
View File
@@ -554,7 +554,7 @@ func (self *SUnifiedMonitorManager) GetPropertySimpleQuery(ctx context.Context,
queryData := data.ToQueryData()
dbRtn, err := self.performQuery(ctx, userCred, queryData)
if err != nil {
return nil, errors.Wrapf(err, "performQuery with data: %s", queryData)
return nil, errors.Wrapf(err, "performQuery with data: %s", jsonutils.Marshal(queryData))
}
ret := []monitor.SimpleQueryOutput{}