This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-cli.git


The following commit(s) were added to refs/heads/master by this push:
     new a7c4cca  Add the sub-commands for query sorted metrics/records (#163)
a7c4cca is described below

commit a7c4ccae106e4a5a0b6296f860396f289444058d
Author: mrproliu <[email protected]>
AuthorDate: Wed Sep 14 11:11:21 2022 +0800

    Add the sub-commands for query sorted metrics/records (#163)
---
 CHANGES.md                                         |  1 +
 assets/graphqls/metrics/SampledRecords.graphql     | 23 +++++++
 .../metrics/aggregation/{topn.go => metrics.go}    | 52 +++------------
 .../aggregation/{topn.go => sampled-record.go}     | 62 +++---------------
 .../metrics/aggregation/sorted-condition.go        | 73 ++++++++++++++++++++++
 internal/commands/metrics/aggregation/topn.go      | 42 +------------
 internal/commands/metrics/metrics.go               |  2 +
 pkg/display/display.go                             |  1 +
 pkg/graphql/metrics/metrics.go                     | 12 ++++
 9 files changed, 133 insertions(+), 135 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 31b9d69..cc0477a 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -20,6 +20,7 @@ Release Notes.
 - Add the sub-command `profiling ebpf create network` and `profiling ebpf keep 
network` to create and keep the network eBPF profiling task.(#158)
 - Add the sub-command `dependency process` to query the process relation.(#158)
 - Support query the metrics of process relation.(#158)
+- Add the sub-command `metrics sorted` and `metrics sampled-record` to query 
the sorted metrics/records.(#163)
 
 0.10.0
 ------------------
diff --git a/assets/graphqls/metrics/SampledRecords.graphql 
b/assets/graphqls/metrics/SampledRecords.graphql
new file mode 100644
index 0000000..9fc1a6c
--- /dev/null
+++ b/assets/graphqls/metrics/SampledRecords.graphql
@@ -0,0 +1,23 @@
+# Licensed to Apache Software Foundation (ASF) under one or more contributor
+# license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright
+# ownership. Apache Software Foundation (ASF) licenses this file to you 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.
+
+query ($condition:TopNCondition!, $duration: Duration!) {
+    result: readSampledRecords(condition: $condition, duration: $duration) {
+        name
+        value
+    }
+}
\ No newline at end of file
diff --git a/internal/commands/metrics/aggregation/topn.go 
b/internal/commands/metrics/aggregation/metrics.go
similarity index 65%
copy from internal/commands/metrics/aggregation/topn.go
copy to internal/commands/metrics/aggregation/metrics.go
index d2ba896..4e1e8d1 100644
--- a/internal/commands/metrics/aggregation/topn.go
+++ b/internal/commands/metrics/aggregation/metrics.go
@@ -18,9 +18,6 @@
 package aggregation
 
 import (
-       "fmt"
-       "strconv"
-
        api "skywalking.apache.org/repo/goapi/query"
 
        "github.com/urfave/cli/v2"
@@ -32,24 +29,23 @@ import (
        "github.com/apache/skywalking-cli/pkg/display"
        "github.com/apache/skywalking-cli/pkg/display/displayable"
        "github.com/apache/skywalking-cli/pkg/graphql/metrics"
-       "github.com/apache/skywalking-cli/pkg/graphql/utils"
 )
 
-var TopN = &cli.Command{
-       Name:      "top",
+var SortedMetrics = &cli.Command{
+       Name:      "sorted",
        Usage:     "query the top <n> entities sorted by the specified metrics",
        ArgsUsage: "<n>",
        UsageText: `Query the top <n> entities sorted by the specified metrics.
 
 Examples:
 1. Query the top 5 services whose sla are largest:
-$ swctl metrics top --name service_sla 5
+$ swctl metrics sorted --name service_sla 5
 
 2. Query the top 5 endpoints whose sla is largest:
-$ swctl metrics top --name endpoint_sla 5
+$ swctl metrics sorted --name endpoint_sla 5
 
 3. Query the top 5 instances of service "boutique::adservice" whose sla are 
largest:
-$ swctl metrics top --name service_instance_sla --service-name 
boutique::adservice 5
+$ swctl metrics sorted --name service_instance_sla --service-name 
boutique::adservice 5
 `,
        Flags: flags.Flags(
                flags.DurationFlags,
@@ -72,45 +68,13 @@ $ swctl metrics top --name service_instance_sla 
--service-name boutique::adservi
                interceptor.ParseService(false),
        ),
        Action: func(ctx *cli.Context) error {
-               start := ctx.String("start")
-               end := ctx.String("end")
-               step := ctx.Generic("step").(*model.StepEnumValue).Selected
-
-               metricsName := ctx.String("name")
-               scope := utils.ParseScopeInTop(metricsName)
-               order := ctx.Generic("order").(*model.OrderEnumValue).Selected
-               topN := 5
-               parentServiceID := ctx.String("service-id")
-               parentService, normal, err := 
interceptor.ParseServiceID(parentServiceID)
+               condition, duration, err := buildSortedCondition(ctx, true)
                if err != nil {
                        return err
                }
 
-               if ctx.NArg() > 0 {
-                       nn, err2 := strconv.Atoi(ctx.Args().First())
-                       if err2 != nil {
-                               return fmt.Errorf("the 1st argument must be a 
number: %v", err2)
-                       }
-                       topN = nn
-               }
-
-               duration := api.Duration{
-                       Start: start,
-                       End:   end,
-                       Step:  step,
-               }
-
-               logger.Log.Debugln(metricsName, scope, topN)
-
-               metricsValues, err := metrics.SortMetrics(ctx, 
api.TopNCondition{
-                       Name:          metricsName,
-                       ParentService: &parentService,
-                       Normal:        &normal,
-                       Scope:         &scope,
-                       TopN:          topN,
-                       Order:         order,
-               }, duration)
-
+               logger.Log.Debugln(condition.Name, condition.Scope, 
condition.TopN)
+               metricsValues, err := metrics.SortMetrics(ctx, *condition, 
*duration)
                if err != nil {
                        return err
                }
diff --git a/internal/commands/metrics/aggregation/topn.go 
b/internal/commands/metrics/aggregation/sampled-record.go
similarity index 57%
copy from internal/commands/metrics/aggregation/topn.go
copy to internal/commands/metrics/aggregation/sampled-record.go
index d2ba896..6b38463 100644
--- a/internal/commands/metrics/aggregation/topn.go
+++ b/internal/commands/metrics/aggregation/sampled-record.go
@@ -18,9 +18,6 @@
 package aggregation
 
 import (
-       "fmt"
-       "strconv"
-
        api "skywalking.apache.org/repo/goapi/query"
 
        "github.com/urfave/cli/v2"
@@ -32,24 +29,17 @@ import (
        "github.com/apache/skywalking-cli/pkg/display"
        "github.com/apache/skywalking-cli/pkg/display/displayable"
        "github.com/apache/skywalking-cli/pkg/graphql/metrics"
-       "github.com/apache/skywalking-cli/pkg/graphql/utils"
 )
 
-var TopN = &cli.Command{
-       Name:      "top",
-       Usage:     "query the top <n> entities sorted by the specified metrics",
+var SampledRecords = &cli.Command{
+       Name:      "sampled-record",
+       Usage:     "query the top <n> entities sorted by the specified records",
        ArgsUsage: "<n>",
-       UsageText: `Query the top <n> entities sorted by the specified metrics.
+       UsageText: `Query the top <n> entities sorted by the specified records.
 
 Examples:
-1. Query the top 5 services whose sla are largest:
-$ swctl metrics top --name service_sla 5
-
-2. Query the top 5 endpoints whose sla is largest:
-$ swctl metrics top --name endpoint_sla 5
-
-3. Query the top 5 instances of service "boutique::adservice" whose sla are 
largest:
-$ swctl metrics top --name service_instance_sla --service-name 
boutique::adservice 5
+1. Query the top 5 database statements whose execute duration are largest:
+$ swctl metrics sampled-record --name top_n_database_statement 5
 `,
        Flags: flags.Flags(
                flags.DurationFlags,
@@ -72,49 +62,17 @@ $ swctl metrics top --name service_instance_sla 
--service-name boutique::adservi
                interceptor.ParseService(false),
        ),
        Action: func(ctx *cli.Context) error {
-               start := ctx.String("start")
-               end := ctx.String("end")
-               step := ctx.Generic("step").(*model.StepEnumValue).Selected
-
-               metricsName := ctx.String("name")
-               scope := utils.ParseScopeInTop(metricsName)
-               order := ctx.Generic("order").(*model.OrderEnumValue).Selected
-               topN := 5
-               parentServiceID := ctx.String("service-id")
-               parentService, normal, err := 
interceptor.ParseServiceID(parentServiceID)
+               condition, duration, err := buildSortedCondition(ctx, false)
                if err != nil {
                        return err
                }
 
-               if ctx.NArg() > 0 {
-                       nn, err2 := strconv.Atoi(ctx.Args().First())
-                       if err2 != nil {
-                               return fmt.Errorf("the 1st argument must be a 
number: %v", err2)
-                       }
-                       topN = nn
-               }
-
-               duration := api.Duration{
-                       Start: start,
-                       End:   end,
-                       Step:  step,
-               }
-
-               logger.Log.Debugln(metricsName, scope, topN)
-
-               metricsValues, err := metrics.SortMetrics(ctx, 
api.TopNCondition{
-                       Name:          metricsName,
-                       ParentService: &parentService,
-                       Normal:        &normal,
-                       Scope:         &scope,
-                       TopN:          topN,
-                       Order:         order,
-               }, duration)
-
+               logger.Log.Debugln(condition.Name, condition.Scope, 
condition.TopN)
+               sampledRecords, err := metrics.SampledRecords(ctx, *condition, 
*duration)
                if err != nil {
                        return err
                }
 
-               return display.Display(ctx, &displayable.Displayable{Data: 
metricsValues})
+               return display.Display(ctx, &displayable.Displayable{Data: 
sampledRecords})
        },
 }
diff --git a/internal/commands/metrics/aggregation/sorted-condition.go 
b/internal/commands/metrics/aggregation/sorted-condition.go
new file mode 100644
index 0000000..9d50624
--- /dev/null
+++ b/internal/commands/metrics/aggregation/sorted-condition.go
@@ -0,0 +1,73 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you 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 aggregation
+
+import (
+       "fmt"
+       "strconv"
+
+       "github.com/apache/skywalking-cli/internal/commands/interceptor"
+       "github.com/apache/skywalking-cli/internal/model"
+       "github.com/apache/skywalking-cli/pkg/graphql/utils"
+
+       "github.com/urfave/cli/v2"
+
+       api "skywalking.apache.org/repo/goapi/query"
+)
+
+// buildSortedCondition from context of cli, the first argument must be the 
count of top N
+func buildSortedCondition(ctx *cli.Context, parseScope bool) 
(*api.TopNCondition, *api.Duration, error) {
+       start := ctx.String("start")
+       end := ctx.String("end")
+       step := ctx.Generic("step").(*model.StepEnumValue).Selected
+
+       metricsName := ctx.String("name")
+       var scope *api.Scope
+       if parseScope {
+               tmp := utils.ParseScopeInTop(metricsName)
+               scope = &tmp
+       }
+       order := ctx.Generic("order").(*model.OrderEnumValue).Selected
+       topN := 5
+       parentServiceID := ctx.String("service-id")
+       parentService, normal, err := 
interceptor.ParseServiceID(parentServiceID)
+       if err != nil {
+               return nil, nil, err
+       }
+
+       if ctx.NArg() > 0 {
+               nn, err2 := strconv.Atoi(ctx.Args().First())
+               if err2 != nil {
+                       return nil, nil, fmt.Errorf("the 1st argument must be a 
number: %v", err2)
+               }
+               topN = nn
+       }
+
+       return &api.TopNCondition{
+                       Name:          metricsName,
+                       ParentService: &parentService,
+                       Normal:        &normal,
+                       Scope:         scope,
+                       TopN:          topN,
+                       Order:         order,
+               }, &api.Duration{
+                       Start: start,
+                       End:   end,
+                       Step:  step,
+               }, nil
+}
diff --git a/internal/commands/metrics/aggregation/topn.go 
b/internal/commands/metrics/aggregation/topn.go
index d2ba896..7a537b7 100644
--- a/internal/commands/metrics/aggregation/topn.go
+++ b/internal/commands/metrics/aggregation/topn.go
@@ -18,9 +18,6 @@
 package aggregation
 
 import (
-       "fmt"
-       "strconv"
-
        api "skywalking.apache.org/repo/goapi/query"
 
        "github.com/urfave/cli/v2"
@@ -32,7 +29,6 @@ import (
        "github.com/apache/skywalking-cli/pkg/display"
        "github.com/apache/skywalking-cli/pkg/display/displayable"
        "github.com/apache/skywalking-cli/pkg/graphql/metrics"
-       "github.com/apache/skywalking-cli/pkg/graphql/utils"
 )
 
 var TopN = &cli.Command{
@@ -72,45 +68,13 @@ $ swctl metrics top --name service_instance_sla 
--service-name boutique::adservi
                interceptor.ParseService(false),
        ),
        Action: func(ctx *cli.Context) error {
-               start := ctx.String("start")
-               end := ctx.String("end")
-               step := ctx.Generic("step").(*model.StepEnumValue).Selected
-
-               metricsName := ctx.String("name")
-               scope := utils.ParseScopeInTop(metricsName)
-               order := ctx.Generic("order").(*model.OrderEnumValue).Selected
-               topN := 5
-               parentServiceID := ctx.String("service-id")
-               parentService, normal, err := 
interceptor.ParseServiceID(parentServiceID)
+               condition, duration, err := buildSortedCondition(ctx, true)
                if err != nil {
                        return err
                }
 
-               if ctx.NArg() > 0 {
-                       nn, err2 := strconv.Atoi(ctx.Args().First())
-                       if err2 != nil {
-                               return fmt.Errorf("the 1st argument must be a 
number: %v", err2)
-                       }
-                       topN = nn
-               }
-
-               duration := api.Duration{
-                       Start: start,
-                       End:   end,
-                       Step:  step,
-               }
-
-               logger.Log.Debugln(metricsName, scope, topN)
-
-               metricsValues, err := metrics.SortMetrics(ctx, 
api.TopNCondition{
-                       Name:          metricsName,
-                       ParentService: &parentService,
-                       Normal:        &normal,
-                       Scope:         &scope,
-                       TopN:          topN,
-                       Order:         order,
-               }, duration)
-
+               logger.Log.Debugln(condition.Name, condition.Scope, 
condition.TopN)
+               metricsValues, err := metrics.SortMetrics(ctx, *condition, 
*duration)
                if err != nil {
                        return err
                }
diff --git a/internal/commands/metrics/metrics.go 
b/internal/commands/metrics/metrics.go
index ad2fe37..5ae661b 100644
--- a/internal/commands/metrics/metrics.go
+++ b/internal/commands/metrics/metrics.go
@@ -38,6 +38,8 @@ var Command = &cli.Command{
                linear.Multiple,
                thermodynamic.Command,
                aggregation.TopN,
+               aggregation.SortedMetrics,
+               aggregation.SampledRecords,
                list.Command,
        },
 }
diff --git a/pkg/display/display.go b/pkg/display/display.go
index 2004e13..6e3f822 100644
--- a/pkg/display/display.go
+++ b/pkg/display/display.go
@@ -44,6 +44,7 @@ const (
 var style = map[string]string{"dashboard global": "graph",
        "dashboard global-metrics": "graph",
        "metrics top":              "table",
+       "metrics sorted":           "table",
        "metrics linear":           "graph",
        "metrics list":             "table",
        "service list":             "table",
diff --git a/pkg/graphql/metrics/metrics.go b/pkg/graphql/metrics/metrics.go
index 65cadcc..3939722 100644
--- a/pkg/graphql/metrics/metrics.go
+++ b/pkg/graphql/metrics/metrics.go
@@ -92,6 +92,18 @@ func SortMetrics(ctx *cli.Context, condition 
api.TopNCondition, duration api.Dur
        return response["result"], err
 }
 
+func SampledRecords(ctx *cli.Context, condition api.TopNCondition, duration 
api.Duration) ([]*api.SelectedRecord, error) {
+       var response map[string][]*api.SelectedRecord
+
+       request := 
graphql.NewRequest(assets.Read("graphqls/metrics/SampledRecords.graphql"))
+       request.Var("condition", condition)
+       request.Var("duration", duration)
+
+       err := client.ExecuteQuery(ctx, request, &response)
+
+       return response["result"], err
+}
+
 func ListMetrics(ctx *cli.Context, regex string) ([]*api.MetricDefinition, 
error) {
        var response map[string][]*api.MetricDefinition
        request := 
graphql.NewRequest(assets.Read("graphqls/metrics/ListMetrics.graphql"))

Reply via email to