Refactor `metrics` to adopt metrics-v2 protocol (#70)
### Enhancements
- Refactor `metrics single` and `metrics top` to adopt metrics-v2 protocol
- Add error checks for `metrics linear` and `metrics multiple-linear`
- Set the name of `metrics thermodynamic` to default
Closes apache/skywalking#4923
diff --git a/README.md b/README.md
index 4f1623a..62df566 100644
--- a/README.md
+++ b/README.md
@@ -160,12 +160,12 @@
<details>
-<summary>metrics linear [--start=start-time] [--end=end-time] --name=metrics-name [--scope=scope-of-metrics]</summary>
+<summary>metrics linear [--start=start-time] [--end=end-time] --name=metrics-name --service=service-name</summary>
| option | description | default |
| :--- | :--- | :--- |
-| `--name` | Metrics name, defined in [OAL](https://github.com/apache/skywalking/blob/master/oap-server/server-bootstrap/src/main/resources/oal/core.oal), such as `all_p99`, etc. |
-| `--scope` | The scope of metrics, which is consistent with `--name`, such as `All`, `Service`, `ServiceInstance`, `Endpoint`, `ServiceRelation`, `ServiceInstanceRelation` and `EndpointRelation`. |`All`|
+| `--name` | Metrics name, defined in [OAL](https://github.com/apache/skywalking/blob/master/oap-server/server-bootstrap/src/main/resources/oal/core.oal). |
+| `--service` | The name of the service. | "" |
| `--start` | See [Common options](#common-options) | See [Common options](#common-options) |
| `--end` | See [Common options](#common-options) | See [Common options](#common-options) |
@@ -175,11 +175,12 @@
<details>
-<summary>metrics multiple-linear [--start=start-time] [--end=end-time] --name=metrics-name [--num=number-of-linear-metrics]</summary>
+<summary>metrics multiple-linear [--start=start-time] [--end=end-time] --name=metrics-name [--service=service-name] [--num=number-of-linear-metrics]</summary>
| option | description | default |
| :--- | :--- | :--- |
-| `--name` | Metrics name, defined in [OAL](https://github.com/apache/skywalking/blob/master/oap-server/server-bootstrap/src/main/resources/oal/core.oal), such as `all_p99`, etc. |
+| `--name` | Metrics name that ends with `_percentile`, defined in [OAL](https://github.com/apache/skywalking/blob/master/oap-server/server-bootstrap/src/main/resources/oal/core.oal), such as `all_percentile`, etc. |
+| `--service` | The name of the service, when scope is `All`, no name is required. | "" |
| `--num` | Number of the linear metrics to fetch | `5` |
| `--start` | See [Common options](#common-options) | See [Common options](#common-options) |
| `--end` | See [Common options](#common-options) | See [Common options](#common-options) |
@@ -190,12 +191,12 @@
<details>
-<summary>metrics single [--start=start-time] [--end=end-time] --name=metrics-name [--ids=entity-ids]</summary>
+<summary>metrics single [--start=start-time] [--end=end-time] --name=metrics-name --service=service-name</summary>
| option | description | default |
| :--- | :--- | :--- |
| `--name` | Metrics name, defined in [OAL](https://github.com/apache/skywalking/blob/master/oap-server/server-bootstrap/src/main/resources/oal/core.oal), such as `service_sla`, etc. |
-| `--ids` | IDs that are required by the metric type, such as service IDs for `service_sla` |
+| `--service` | The name of the service. | "" |
| `--start` | See [Common options](#common-options) | See [Common options](#common-options) |
| `--end` | See [Common options](#common-options) | See [Common options](#common-options) |
@@ -205,15 +206,16 @@
<details>
-<summary>metrics top 3 [--start=start-time] [--end=end-time] --name endpoint_sla [--service-id 3]</summary>
+<summary>metrics top 5 [--start=start-time] [--end=end-time] --name=metrics-name [--service=parent-service] [--order=DES]</summary>
| option | description | default |
| :--- | :--- | :--- |
+| arguments | The first argument is the number of top entities | `5` |
| `--name` | Metrics name, defined in [OAL](https://github.com/apache/skywalking/blob/master/oap-server/server-bootstrap/src/main/resources/oal/core.oal), such as `service_sla`, etc. |
-| `--service-id` | service ID that are required by the metric type, such as service IDs for `service_sla` |
+| `--service` | The name of the parent service, could be null if query the global top N. | "" |
+| `--order` | The order of metrics, `DES` or `ASC`. |`DES`|
| `--start` | See [Common options](#common-options) | See [Common options](#common-options) |
| `--end` | See [Common options](#common-options) | See [Common options](#common-options) |
-| arguments | the first argument is the number of top entities | `3` |
</details>
@@ -221,12 +223,11 @@
<details>
-<summary>metrics thermodynamic --name=thermodynamic name [--scope=scope-of-metrics]</summary>
+<summary>metrics thermodynamic [--name=metrics-name]</summary>
| option | description | default |
| :--- | :--- | :--- |
-| `--name` | Metrics name, defined in [OAL](https://github.com/apache/skywalking/blob/master/oap-server/server-bootstrap/src/main/resources/oal/core.oal), such as `service_sla`, etc. |
-| `--scope` | The scope of metrics, which is consistent with `--name`, such as `All`, `Service`, `ServiceInstance`, `Endpoint`, `ServiceRelation`, `ServiceInstanceRelation` and `EndpointRelation`. |`All`|
+| `--name` | Metrics name that ends with `_heatmap`, defined in [OAL](https://github.com/apache/skywalking/blob/master/oap-server/server-bootstrap/src/main/resources/oal/core.oal), such as `all_heatmap`, etc. | `all_heatmap` |
| `--start` | See [Common options](#common-options) | See [Common options](#common-options) |
| `--end` | See [Common options](#common-options) | See [Common options](#common-options) |
@@ -376,7 +377,7 @@
<summary>Query a linear metrics graph for an instance</summary>
```shell
-$ ./bin/swctl --display=graph metrics linear --name=service_instance_resp_time --scope ServiceInstance
+$ ./bin/swctl --display=graph metrics linear --name=service_instance_resp_time --service "load balancer1.system"
┌─────────────────────────────────────────────────────────────────────────────────Press q to quit──────────────────────────────────────────────────────────────────────────────────┐
│ │
│ │
@@ -517,30 +518,30 @@
<summary>Query the top 5 services whose sla is largest</summary>
```shell
-$ ./bin/swctl metrics top 5 --name service_sla
-[{"name":"projectB","id":"2","value":10000},{"name":"projectC","id":"3","value":10000},{"name":"projectA","id":"4","value":10000},{"name":"projectD","id":"5","value":10000}]
+$ ./bin/swctl metrics top 5 --name service_sla
+[{"name":"load balancer1.system","id":"","value":"10000","refId":null},{"name":"load balancer2.system","id":"","value":"10000","refId":null},{"name":"projectB.business-zone","id":"","value":"10000","refId":null},{"name":"projectC.business-zone","id":"","value":"10000","refId":null},{"name":"projectD.business-zone","id":"","value":"10000","refId":null}]
```
</details>
<details>
-<summary>Query the top 5 instances whose sla is largest, of service (id = 3)</summary>
+<summary>Query the top 5 instances whose sla is largest</summary>
```shell
-$ ./bin/swctl metrics top 5 --name service_instance_sla --service-id 3
-[{"name":"projectC-pid:30335@skywalking-server-0002","id":"13","value":10000},{"name":"projectC-pid:22037@skywalking-server-0001","id":"2","value":10000}]
+$ ./bin/swctl metrics top 5 --name service_instance_sla
+[{"name":"load balancer1.system - load balancer1.system","id":"","value":"10000","refId":null},{"name":"load balancer2.system - load balancer2.system","id":"","value":"10000","refId":null},{"name":"projectA.business-zone - eb38c5efeb874734a7b17de780685c55@192.168.252.12","id":"","value":"10000","refId":null},{"name":"projectB.business-zone - 4e72bad0f2c14381a5657eaaca7f33ba@192.168.252.12","id":"","value":"10000","refId":null},{"name":"projectB.business-zone - 6e0e2e1cc63145859a21fc7bf7f18d2e@192.168.252.13","id":"","value":"10000","refId":null}]
```
</details>
<details>
-<summary>Query the top 5 endpoints whose sla is largest, of service (id = 3)</summary>
+<summary>Query the top 5 endpoints whose sla is largest</summary>
```shell
-$ ./bin/swctl metrics top 5 --name endpoint_sla --service-id 3
-[{"name":"/projectC/{value}","id":"4","value":10000}]
+$ ./bin/swctl metrics top 5 --name endpoint_sla
+[{"name":"load balancer1.system - /projectA/test","id":"","value":"10000","refId":null},{"name":"load balancer1.system - /","id":"","value":"10000","refId":null},{"name":"load balancer2.system - /projectA/test","id":"","value":"10000","refId":null},{"name":"load balancer2.system - /","id":"","value":"10000","refId":null},{"name":"projectA.business-zone - /projectA/{name}","id":"","value":"10000","refId":null}]
```
</details>
@@ -550,12 +551,12 @@
<summary>Query the overall heat map</summary>
```shell
-$ ./bin/swctl metrics thermodynamic --name all_heatmap
+$ ./bin/swctl metrics thermodynamic
{"values":[{"id":"202008290939","values":[473,3,0,0,0,0,0,0,0,0,323,0,4,0,0,0,0,0,0,0,436]},{"id":"202008290940","values":[434,0,0,0,0,0,0,0,0,0,367,0,4,0,0,0,0,0,0,0,427]},{"id":"202008290941","values":[504,0,0,0,0,0,0,0,0,0,410,0,5,0,1,0,0,0,0,0,377]},{"id":"202008290942","values":[445,0,4,0,0,0,0,0,0,0,350,0,0,0,0,0,0,0,0,0,420]},{"id":"202008290943","values":[436,0,1,0,0,0,0,0,0,0,367,0,3,0,0,0,0,0,0,0,404]},{"id":"202008290944","values":[463,0,0,0,0,0,0,0,0,0,353,0,0,0,0,0,0,0,0,0,416]},{"id":"202008290945","values":[496,0,2,3,0,0,0,0,0,0,372,0,4,0,0,0,0,0,0,0,393]},{"id":"202008290946","values":[460,0,4,0,0,0,0,0,0,0,396,0,0,0,0,0,0,0,0,0,408]},{"id":"202008290947","values":[533,0,0,0,0,0,0,0,0,0,400,0,0,0,0,0,0,0,0,0,379]},{"id":"202008290948","values":[539,0,0,0,0,0,0,0,0,0,346,0,1,0,0,0,0,0,0,0,424]},{"id":"202008290949","values":[476,0,0,0,1,0,0,0,0,0,353,0,0,0,3,0,0,0,0,0,435]},{"id":"202008290950","values":[509,0,0,0,0,0,0,0,0,0,371,0,0,0,0,0,0,0,0,0,398]},{"id":"202008290951","values":[478,0,2,0,0,0,0,0,0,0,367,0,10,0,4,0,0,0,0,0,413]},{"id":"202008290952","values":[564,0,4,0,0,0,0,0,0,0,342,0,4,0,0,0,0,0,0,0,414]},{"id":"202008290953","values":[476,0,4,0,0,0,0,0,0,0,448,0,4,0,0,0,0,0,0,0,372]},{"id":"202008290954","values":[502,0,1,0,0,0,0,0,0,0,394,0,7,0,0,0,0,0,0,0,392]},{"id":"202008290955","values":[490,0,2,0,0,0,0,0,0,0,383,0,7,0,0,0,0,0,0,0,407]},{"id":"202008290956","values":[474,0,5,0,0,0,0,0,0,0,397,0,3,0,0,0,0,0,0,0,393]},{"id":"202008290957","values":[484,0,4,0,0,0,0,0,0,0,383,0,0,0,0,0,0,0,0,0,402]},{"id":"202008290958","values":[494,0,8,0,0,0,0,0,0,0,361,0,0,0,0,0,0,0,0,0,416]},{"id":"202008290959","values":[434,0,0,0,0,0,0,0,0,0,354,0,0,0,0,0,0,0,0,0,457]},{"id":"202008291000","values":[507,0,1,0,0,0,0,0,0,0,384,0,7,0,0,0,0,0,0,0,405]},{"id":"202008291001","values":[456,0,2,0,0,0,0,0,0,0,388,0,7,0,1,0,0,0,0,0,412]},{"id":"202008291002","values":[506,0,1,0,0,0,0,0,0,0,385,0,0,0,0,0,0,0,0,0,399]},{"id":"202008291003","values":[494,0,8,0,0,0,0,0,0,0,367,0,0,0,0,0,0,0,0,0,415]},{"id":"202008291004","values":[459,0,1,0,0,0,0,0,0,0,263,0,4,0,0,0,0,0,0,0,474]},{"id":"202008291005","values":[513,0,1,0,0,0,0,0,0,0,371,0,3,0,0,0,0,0,0,0,426]},{"id":"202008291006","values":[462,0,1,0,0,0,0,0,0,0,332,0,0,0,0,0,0,0,0,0,435]},{"id":"202008291007","values":[524,0,4,0,1,0,0,0,0,0,365,0,0,0,3,0,0,0,0,0,427]},{"id":"202008291008","values":[442,0,0,0,0,0,0,0,0,0,304,0,0,0,0,0,0,0,0,0,438]},{"id":"202008291009","values":[584,0,0,0,0,0,0,0,0,0,446,0,0,0,0,0,0,0,0,0,343]}],"buckets":[{"min":"0","max":"100"},{"min":"100","max":"200"},{"min":"200","max":"300"},{"min":"300","max":"400"},{"min":"400","max":"500"},{"min":"500","max":"600"},{"min":"600","max":"700"},{"min":"700","max":"800"},{"min":"800","max":"900"},{"min":"900","max":"1000"},{"min":"1000","max":"1100"},{"min":"1100","max":"1200"},{"min":"1200","max":"1300"},{"min":"1300","max":"1400"},{"min":"1400","max":"1500"},{"min":"1500","max":"1600"},{"min":"1600","max":"1700"},{"min":"1700","max":"1800"},{"min":"1800","max":"1900"},{"min":"1900","max":"2000"},{"min":"2000","max":"infinite+"}]}
```
```shell
-$ ./bin/swctl --display=graph metrics thermodynamic --name all_heatmap
+$ ./bin/swctl --display=graph metrics thermodynamic
```
</details>
diff --git a/assets/graphqls/aggregation/AllEndpointTopN.graphql b/assets/graphqls/aggregation/AllEndpointTopN.graphql
deleted file mode 100644
index a054b10..0000000
--- a/assets/graphqls/aggregation/AllEndpointTopN.graphql
+++ /dev/null
@@ -1,27 +0,0 @@
-# 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 ($name: String!, $topN: Int!, $duration: Duration!, $order: Order!) {
- result: getAllEndpointTopN(
- duration: $duration,
- name: $name,
- topN: $topN,
- order: $order
- ) {
- id name value
- }
-}
diff --git a/assets/graphqls/aggregation/AllServiceInstanceTopN.graphql b/assets/graphqls/aggregation/AllServiceInstanceTopN.graphql
deleted file mode 100644
index 0268c60..0000000
--- a/assets/graphqls/aggregation/AllServiceInstanceTopN.graphql
+++ /dev/null
@@ -1,27 +0,0 @@
-# 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 ($name: String!, $topN: Int!, $duration: Duration!, $order: Order!) {
- result: getAllServiceInstanceTopN(
- duration: $duration,
- name: $name,
- topN: $topN,
- order: $order
- ) {
- id name value
- }
-}
diff --git a/assets/graphqls/aggregation/EndpointTopN.graphql b/assets/graphqls/aggregation/EndpointTopN.graphql
deleted file mode 100644
index b6e05f6..0000000
--- a/assets/graphqls/aggregation/EndpointTopN.graphql
+++ /dev/null
@@ -1,28 +0,0 @@
-# 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 ($serviceId: ID!, $name: String!, $topN: Int!, $duration: Duration!, $order: Order!) {
- result: getEndpointTopN(
- serviceId: $serviceId,
- duration: $duration,
- name: $name,
- topN: $topN,
- order: $order
- ) {
- id name value
- }
-}
diff --git a/assets/graphqls/aggregation/ServiceInstanceTopN.graphql b/assets/graphqls/aggregation/ServiceInstanceTopN.graphql
deleted file mode 100644
index f643170..0000000
--- a/assets/graphqls/aggregation/ServiceInstanceTopN.graphql
+++ /dev/null
@@ -1,28 +0,0 @@
-# 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 ($serviceId: ID!, $name: String!, $topN: Int!, $duration: Duration!, $order: Order!) {
- result: getServiceInstanceTopN(
- serviceId: $serviceId,
- duration: $duration,
- name: $name,
- topN: $topN,
- order: $order
- ) {
- id name value
- }
-}
diff --git a/assets/graphqls/aggregation/ServiceTopN.graphql b/assets/graphqls/aggregation/ServiceTopN.graphql
deleted file mode 100644
index 754e827..0000000
--- a/assets/graphqls/aggregation/ServiceTopN.graphql
+++ /dev/null
@@ -1,27 +0,0 @@
-# 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 ($name: String!, $topN: Int!, $duration: Duration!, $order: Order!) {
- result: getServiceTopN(
- duration: $duration,
- name: $name,
- topN: $topN,
- order: $order
- ) {
- id name value
- }
-}
diff --git a/assets/graphqls/metrics/LinearIntValues.graphql b/assets/graphqls/metrics/LinearIntValues.graphql
deleted file mode 100644
index 6249db2..0000000
--- a/assets/graphqls/metrics/LinearIntValues.graphql
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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 ($metric: MetricCondition!, $duration: Duration!) {
- result: getLinearIntValues(metric: $metric, duration: $duration) {
- values { value }
- }
-}
diff --git a/assets/graphqls/metrics/IntValues.graphql b/assets/graphqls/metrics/MetricsValue.graphql
similarity index 83%
rename from assets/graphqls/metrics/IntValues.graphql
rename to assets/graphqls/metrics/MetricsValue.graphql
index 1138172..9458b04 100644
--- a/assets/graphqls/metrics/IntValues.graphql
+++ b/assets/graphqls/metrics/MetricsValue.graphql
@@ -15,8 +15,6 @@
# specific language governing permissions and limitations
# under the License.
-query ($metric: BatchMetricConditions!, $duration: Duration!) {
- result: getValues(metric: $metric, duration: $duration) {
- values { id value }
- }
+query ($condition: MetricsCondition!, $duration: Duration!) {
+ result: readMetricsValue(condition: $condition, duration: $duration)
}
diff --git a/assets/graphqls/dashboard/SortMetrics.graphql b/assets/graphqls/metrics/SortMetrics.graphql
similarity index 100%
rename from assets/graphqls/dashboard/SortMetrics.graphql
rename to assets/graphqls/metrics/SortMetrics.graphql
diff --git a/commands/flags/metrics.go b/commands/flags/metrics.go
new file mode 100644
index 0000000..b1bcfb2
--- /dev/null
+++ b/commands/flags/metrics.go
@@ -0,0 +1,37 @@
+// 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 flags
+
+import (
+ "github.com/urfave/cli"
+)
+
+// MetricsFlags can be reused in several metrics commands.
+var MetricsFlags = []cli.Flag{
+ cli.StringFlag{
+ Name: "name",
+ Usage: "metrics `name`, which should be defined in OAL script",
+ Required: true,
+ },
+ cli.StringFlag{
+ Name: "service",
+ Usage: "the name of the service",
+ Value: "",
+ Required: false,
+ },
+}
diff --git a/commands/interceptor/scope.go b/commands/interceptor/scope.go
new file mode 100644
index 0000000..d7c84e8
--- /dev/null
+++ b/commands/interceptor/scope.go
@@ -0,0 +1,45 @@
+// 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 interceptor
+
+import (
+ "strings"
+
+ "github.com/apache/skywalking-cli/graphql/schema"
+)
+
+// ParseScope defines the scope according to name's prefix.
+func ParseScope(name string) schema.Scope {
+ ret := schema.ScopeAll
+
+ if strings.HasPrefix(name, "service_relation") {
+ ret = schema.ScopeServiceRelation
+ } else if strings.HasPrefix(name, "service_instance_relation") {
+ ret = schema.ScopeServiceInstanceRelation
+ } else if strings.HasPrefix(name, "service_instance") {
+ ret = schema.ScopeServiceInstance
+ } else if strings.HasPrefix(name, "service_") {
+ ret = schema.ScopeService
+ } else if strings.HasPrefix(name, "endpoint_relation") {
+ ret = schema.ScopeEndpointRelation
+ } else if strings.HasPrefix(name, "endpoint_") {
+ ret = schema.ScopeEndpoint
+ }
+
+ return ret
+}
diff --git a/commands/interceptor/scope_test.go b/commands/interceptor/scope_test.go
new file mode 100644
index 0000000..8a1d87f
--- /dev/null
+++ b/commands/interceptor/scope_test.go
@@ -0,0 +1,80 @@
+// 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 interceptor
+
+import (
+ "testing"
+
+ "github.com/apache/skywalking-cli/graphql/schema"
+)
+
+func TestParseScope(t *testing.T) {
+ tests := []struct {
+ name string
+ wantedScope schema.Scope
+ }{
+ {
+ name: "",
+ wantedScope: schema.ScopeAll,
+ },
+ {
+ name: "all_percentile",
+ wantedScope: schema.ScopeAll,
+ },
+ {
+ name: "all_heatmap",
+ wantedScope: schema.ScopeAll,
+ },
+ {
+ name: "service_resp_time",
+ wantedScope: schema.ScopeService,
+ },
+ {
+ name: "service_percentile",
+ wantedScope: schema.ScopeService,
+ },
+ {
+ name: "service_relation_server_percentile ",
+ wantedScope: schema.ScopeServiceRelation,
+ },
+ {
+ name: "service_instance_relation_client_cpm",
+ wantedScope: schema.ScopeServiceInstanceRelation,
+ },
+ {
+ name: "service_instance_resp_time",
+ wantedScope: schema.ScopeServiceInstance,
+ },
+ {
+ name: "endpoint_cpm",
+ wantedScope: schema.ScopeEndpoint,
+ },
+ {
+ name: "endpoint_relation_resp_time",
+ wantedScope: schema.ScopeEndpointRelation,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ gotScope := ParseScope(tt.name)
+ if gotScope != tt.wantedScope {
+ t.Errorf("ParseScope() got scope = %v, wanted scope %v", gotScope, tt.wantedScope)
+ }
+ })
+ }
+}
diff --git a/commands/metrics/aggregation/topn.go b/commands/metrics/aggregation/topn.go
index ce6c63d..183ec05 100644
--- a/commands/metrics/aggregation/topn.go
+++ b/commands/metrics/aggregation/topn.go
@@ -20,19 +20,16 @@
import (
"fmt"
"strconv"
- "strings"
-
- "github.com/apache/skywalking-cli/display/displayable"
-
- "github.com/apache/skywalking-cli/commands/interceptor"
-
- "github.com/urfave/cli"
"github.com/apache/skywalking-cli/commands/flags"
+ "github.com/apache/skywalking-cli/commands/interceptor"
"github.com/apache/skywalking-cli/commands/model"
"github.com/apache/skywalking-cli/display"
- "github.com/apache/skywalking-cli/graphql/aggregation"
+ "github.com/apache/skywalking-cli/display/displayable"
+ "github.com/apache/skywalking-cli/graphql/metrics"
"github.com/apache/skywalking-cli/graphql/schema"
+
+ "github.com/urfave/cli"
)
var TopN = cli.Command{
@@ -41,12 +38,8 @@
ArgsUsage: "<n>",
Flags: flags.Flags(
flags.DurationFlags,
+ flags.MetricsFlags,
[]cli.Flag{
- cli.StringFlag{
- Name: "name",
- Usage: "`metrics name`, which should be defined in OAL script",
- Required: true,
- },
cli.GenericFlag{
Name: "order",
Usage: "the `order` by which the top entities are sorted",
@@ -56,11 +49,6 @@
Selected: schema.OrderDes,
},
},
- cli.StringFlag{
- Name: "service-id",
- Usage: "the `service id` whose instances/endpoints are to be fetch, if applicable",
- Required: false,
- },
},
),
Before: interceptor.BeforeChain([]cli.BeforeFunc{
@@ -68,14 +56,16 @@
interceptor.DurationInterceptor,
}),
Action: func(ctx *cli.Context) error {
- name := ctx.String("name")
start := ctx.String("start")
end := ctx.String("end")
step := ctx.Generic("step").(*model.StepEnumValue).Selected
- order := ctx.Generic("order").(*model.OrderEnumValue).Selected
- serviceID := ctx.String("service-id")
+ metricsName := ctx.String("name")
+ normal := true
+ scope := interceptor.ParseScope(metricsName)
+ order := ctx.Generic("order").(*model.OrderEnumValue).Selected
topN := 5
+ parentService := ctx.String("service")
if ctx.NArg() > 0 {
nn, err := strconv.Atoi(ctx.Args().First())
@@ -91,23 +81,14 @@
Step: step,
}
- var metricsValues []schema.TopNEntity
-
- if strings.HasPrefix(name, "service_instance") {
- if serviceID == "" {
- metricsValues = aggregation.AllServiceInstanceTopN(ctx, name, topN, duration, order)
- } else {
- metricsValues = aggregation.ServiceInstanceTopN(ctx, serviceID, name, topN, duration, order)
- }
- } else if strings.HasPrefix(name, "endpoint_") {
- if serviceID == "" {
- metricsValues = aggregation.AllEndpointTopN(ctx, name, topN, duration, order)
- } else {
- metricsValues = aggregation.EndpointTopN(ctx, serviceID, name, topN, duration, order)
- }
- } else if strings.HasPrefix(name, "service_") {
- metricsValues = aggregation.ServiceTopN(ctx, name, topN, duration, order)
- }
+ metricsValues := metrics.SortMetrics(ctx, schema.TopNCondition{
+ Name: metricsName,
+ ParentService: &parentService,
+ Normal: &normal,
+ Scope: &scope,
+ TopN: topN,
+ Order: order,
+ }, duration)
return display.Display(ctx, &displayable.Displayable{Data: metricsValues})
},
diff --git a/commands/metrics/linear/linear-metrics.go b/commands/metrics/linear/linear-metrics.go
index 48cc830..a684781 100644
--- a/commands/metrics/linear/linear-metrics.go
+++ b/commands/metrics/linear/linear-metrics.go
@@ -18,6 +18,8 @@
package linear
import (
+ "fmt"
+
"github.com/apache/skywalking-cli/commands/flags"
"github.com/apache/skywalking-cli/commands/interceptor"
"github.com/apache/skywalking-cli/commands/model"
@@ -35,23 +37,7 @@
Usage: "Query linear metrics defined in backend OAL",
Flags: flags.Flags(
flags.DurationFlags,
- []cli.Flag{
- cli.StringFlag{
- Name: "name",
- Usage: "metrics `NAME`, such as `all_p99`",
- Required: true,
- },
- cli.GenericFlag{
- Name: "scope",
- Usage: "the scope of the query, which follows the metrics `name`",
- Value: &model.ScopeEnumValue{
- Enum: schema.AllScope,
- Default: schema.ScopeAll,
- Selected: schema.ScopeAll,
- },
- Required: false,
- },
- },
+ flags.MetricsFlags,
),
Before: interceptor.BeforeChain([]cli.BeforeFunc{
interceptor.TimezoneInterceptor,
@@ -61,8 +47,18 @@
end := ctx.String("end")
start := ctx.String("start")
step := ctx.Generic("step")
+
metricsName := ctx.String("name")
- scope := ctx.Generic("scope").(*model.ScopeEnumValue).Selected
+ serviceName := ctx.String("service")
+ normal := true
+ scope := interceptor.ParseScope(metricsName)
+
+ if serviceName == "" {
+ return fmt.Errorf("the name of service should be specified")
+ }
+ if scope == schema.ScopeAll {
+ return fmt.Errorf("this command cannot be used to query `All` scope metrics")
+ }
duration := schema.Duration{
Start: start,
@@ -73,7 +69,10 @@
metricsValues := metrics.LinearIntValues(ctx, schema.MetricsCondition{
Name: metricsName,
Entity: &schema.Entity{
- Scope: scope,
+ Scope: scope,
+ ServiceName: &serviceName,
+ Normal: &normal,
+ ServiceInstanceName: &serviceName,
},
}, duration)
diff --git a/commands/metrics/linear/multiple-linear-metrics.go b/commands/metrics/linear/multiple-linear-metrics.go
index 4036435..9c8bd3b 100644
--- a/commands/metrics/linear/multiple-linear-metrics.go
+++ b/commands/metrics/linear/multiple-linear-metrics.go
@@ -37,12 +37,8 @@
Usage: "Query multiple linear metrics defined in backend OAL",
Flags: flags.Flags(
flags.DurationFlags,
+ flags.MetricsFlags,
[]cli.Flag{
- cli.StringFlag{
- Name: "name",
- Usage: "metrics `NAME`, such as `all_percentile`",
- Required: true,
- },
cli.IntFlag{
Name: "num",
Usage: "`num`, the number of linear metrics to query, (default: 5)",
@@ -59,8 +55,16 @@
end := ctx.String("end")
start := ctx.String("start")
step := ctx.Generic("step")
+
metricsName := ctx.String("name")
+ serviceName := ctx.String("service")
+ normal := true
numOfLinear := ctx.Int("num")
+ scope := interceptor.ParseScope(metricsName)
+
+ if serviceName == "" && scope != schema.ScopeAll {
+ return fmt.Errorf("the name of service should be specified when metrics' scope is not `All`")
+ }
if numOfLinear > 5 || numOfLinear < 1 {
numOfLinear = 5
@@ -80,7 +84,9 @@
metricsValuesArray := metrics.MultipleLinearIntValues(ctx, schema.MetricsCondition{
Name: metricsName,
Entity: &schema.Entity{
- Scope: schema.ScopeAll,
+ Scope: scope,
+ ServiceName: &serviceName,
+ Normal: &normal,
},
}, labels, duration)
diff --git a/commands/metrics/single/single-metrics.go b/commands/metrics/single/single-metrics.go
index 1f710c0..2d92cca 100644
--- a/commands/metrics/single/single-metrics.go
+++ b/commands/metrics/single/single-metrics.go
@@ -18,19 +18,17 @@
package single
import (
- "strings"
-
- "github.com/apache/skywalking-cli/display/displayable"
-
- "github.com/apache/skywalking-cli/graphql/metrics"
-
- "github.com/urfave/cli"
+ "fmt"
"github.com/apache/skywalking-cli/commands/flags"
"github.com/apache/skywalking-cli/commands/interceptor"
"github.com/apache/skywalking-cli/commands/model"
"github.com/apache/skywalking-cli/display"
+ "github.com/apache/skywalking-cli/display/displayable"
+ "github.com/apache/skywalking-cli/graphql/metrics"
"github.com/apache/skywalking-cli/graphql/schema"
+
+ "github.com/urfave/cli"
)
var Command = cli.Command{
@@ -38,18 +36,7 @@
Usage: "Query single metrics defined in backend OAL",
Flags: flags.Flags(
flags.DurationFlags,
- []cli.Flag{
- cli.StringFlag{
- Name: "name",
- Usage: "metrics `NAME`, which should be defined in OAL script",
- Required: true,
- },
- cli.StringSliceFlag{
- Name: "ids",
- Usage: "`IDs`, IDs that are required by the given metric type",
- Required: false,
- },
- },
+ flags.MetricsFlags,
),
Before: interceptor.BeforeChain([]cli.BeforeFunc{
interceptor.TimezoneInterceptor,
@@ -59,24 +46,34 @@
end := ctx.String("end")
start := ctx.String("start")
step := ctx.Generic("step")
+
metricsName := ctx.String("name")
- idsString := ctx.StringSlice("ids")
+ serviceName := ctx.String("service")
+ normal := true
+ scope := interceptor.ParseScope(metricsName)
- var ids []string
-
- for _, id := range idsString {
- ids = append(ids, strings.Split(id, ",")...)
+ if serviceName == "" {
+ return fmt.Errorf("the name of service should be specified")
+ }
+ if scope == schema.ScopeAll {
+ return fmt.Errorf("this command cannot be used to query `All` scope metrics")
}
- metricsValues := metrics.IntValues(ctx, schema.BatchMetricConditions{
- Name: metricsName,
- Ids: ids,
- }, schema.Duration{
+ duration := schema.Duration{
Start: start,
End: end,
Step: step.(*model.StepEnumValue).Selected,
- })
+ }
- return display.Display(ctx, &displayable.Displayable{Data: metricsValues.Values})
+ metricsValue := metrics.IntValues(ctx, schema.MetricsCondition{
+ Name: metricsName,
+ Entity: &schema.Entity{
+ Scope: scope,
+ ServiceName: &serviceName,
+ Normal: &normal,
+ },
+ }, duration)
+
+ return display.Display(ctx, &displayable.Displayable{Data: metricsValue})
},
}
diff --git a/commands/metrics/thermodynamic/thermodynamic.go b/commands/metrics/thermodynamic/thermodynamic.go
index 62268e1..d865422 100644
--- a/commands/metrics/thermodynamic/thermodynamic.go
+++ b/commands/metrics/thermodynamic/thermodynamic.go
@@ -18,16 +18,15 @@
package thermodynamic
import (
- "github.com/urfave/cli"
-
- "github.com/apache/skywalking-cli/display/displayable"
-
"github.com/apache/skywalking-cli/commands/flags"
"github.com/apache/skywalking-cli/commands/interceptor"
"github.com/apache/skywalking-cli/commands/model"
"github.com/apache/skywalking-cli/display"
+ "github.com/apache/skywalking-cli/display/displayable"
"github.com/apache/skywalking-cli/graphql/metrics"
"github.com/apache/skywalking-cli/graphql/schema"
+
+ "github.com/urfave/cli"
)
var Command = cli.Command{
@@ -40,16 +39,8 @@
cli.StringFlag{
Name: "name",
Usage: "metrics `name`, which should be defined in OAL script",
- Required: true,
- },
- cli.GenericFlag{
- Name: "scope",
- Usage: "the scope of the query, which follows the metrics `name`",
- Value: &model.ScopeEnumValue{
- Enum: schema.AllScope,
- Default: schema.ScopeAll,
- Selected: schema.ScopeAll,
- },
+ Value: "all_heatmap",
+ Required: false,
},
},
),
@@ -61,8 +52,9 @@
end := ctx.String("end")
start := ctx.String("start")
step := ctx.Generic("step")
+
metricsName := ctx.String("name")
- scope := ctx.Generic("scope").(*model.ScopeEnumValue).Selected
+ scope := interceptor.ParseScope(metricsName)
duration := schema.Duration{
Start: start,
diff --git a/graphql/aggregation/aggregation.go b/graphql/aggregation/aggregation.go
deleted file mode 100644
index 6effe5e..0000000
--- a/graphql/aggregation/aggregation.go
+++ /dev/null
@@ -1,100 +0,0 @@
-// 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 (
- "github.com/machinebox/graphql"
- "github.com/urfave/cli"
-
- "github.com/apache/skywalking-cli/assets"
-
- "github.com/apache/skywalking-cli/graphql/client"
- "github.com/apache/skywalking-cli/graphql/schema"
-)
-
-func ServiceTopN(ctx *cli.Context, name string, topN int, duration schema.Duration, order schema.Order) []schema.TopNEntity {
- var response map[string][]schema.TopNEntity
-
- request := graphql.NewRequest(assets.Read("graphqls/aggregation/ServiceTopN.graphql"))
- request.Var("name", name)
- request.Var("topN", topN)
- request.Var("duration", duration)
- request.Var("order", order)
-
- client.ExecuteQueryOrFail(ctx, request, &response)
-
- return response["result"]
-}
-
-func AllServiceInstanceTopN(ctx *cli.Context, name string, topN int, duration schema.Duration, order schema.Order) []schema.TopNEntity {
- var response map[string][]schema.TopNEntity
-
- request := graphql.NewRequest(assets.Read("graphqls/aggregation/AllServiceInstanceTopN.graphql"))
- request.Var("name", name)
- request.Var("topN", topN)
- request.Var("duration", duration)
- request.Var("order", order)
-
- client.ExecuteQueryOrFail(ctx, request, &response)
-
- return response["result"]
-}
-
-func ServiceInstanceTopN(ctx *cli.Context, serviceID, name string, topN int, duration schema.Duration, order schema.Order) []schema.TopNEntity {
- var response map[string][]schema.TopNEntity
-
- request := graphql.NewRequest(assets.Read("graphqls/aggregation/ServiceInstanceTopN.graphql"))
- request.Var("serviceId", serviceID)
- request.Var("name", name)
- request.Var("topN", topN)
- request.Var("duration", duration)
- request.Var("order", order)
-
- client.ExecuteQueryOrFail(ctx, request, &response)
-
- return response["result"]
-}
-
-func AllEndpointTopN(ctx *cli.Context, name string, topN int, duration schema.Duration, order schema.Order) []schema.TopNEntity {
- var response map[string][]schema.TopNEntity
-
- request := graphql.NewRequest(assets.Read("graphqls/aggregation/AllEndpointTopN.graphql"))
- request.Var("name", name)
- request.Var("topN", topN)
- request.Var("duration", duration)
- request.Var("order", order)
-
- client.ExecuteQueryOrFail(ctx, request, &response)
-
- return response["result"]
-}
-
-func EndpointTopN(ctx *cli.Context, serviceID, name string, topN int, duration schema.Duration, order schema.Order) []schema.TopNEntity {
- var response map[string][]schema.TopNEntity
-
- request := graphql.NewRequest(assets.Read("graphqls/aggregation/EndpointTopN.graphql"))
- request.Var("serviceId", serviceID)
- request.Var("name", name)
- request.Var("topN", topN)
- request.Var("duration", duration)
- request.Var("order", order)
-
- client.ExecuteQueryOrFail(ctx, request, &response)
-
- return response["result"]
-}
diff --git a/graphql/dashboard/global.go b/graphql/dashboard/global.go
index 2ea0872..3dbf31a 100644
--- a/graphql/dashboard/global.go
+++ b/graphql/dashboard/global.go
@@ -22,14 +22,12 @@
"io/ioutil"
"strings"
- "github.com/machinebox/graphql"
"github.com/spf13/viper"
"github.com/urfave/cli"
"gopkg.in/yaml.v2"
"github.com/apache/skywalking-cli/assets"
- "github.com/apache/skywalking-cli/graphql/client"
"github.com/apache/skywalking-cli/graphql/metrics"
"github.com/apache/skywalking-cli/graphql/schema"
"github.com/apache/skywalking-cli/graphql/utils"
@@ -153,13 +151,7 @@
}
for _, m := range template.Metrics {
- var response map[string][]*schema.SelectedRecord
- request := graphql.NewRequest(assets.Read("graphqls/dashboard/SortMetrics.graphql"))
- request.Var("condition", m.Condition)
- request.Var("duration", duration)
-
- client.ExecuteQueryOrFail(ctx, request, &response)
- ret = append(ret, response["result"])
+ ret = append(ret, metrics.SortMetrics(ctx, m.Condition, duration))
}
return ret
diff --git a/graphql/metrics/metrics.go b/graphql/metrics/metrics.go
index 022779d..174105a 100644
--- a/graphql/metrics/metrics.go
+++ b/graphql/metrics/metrics.go
@@ -18,22 +18,20 @@
package metrics
import (
+ "github.com/apache/skywalking-cli/assets"
+ "github.com/apache/skywalking-cli/graphql/client"
+ "github.com/apache/skywalking-cli/graphql/schema"
+
"github.com/machinebox/graphql"
"github.com/urfave/cli"
-
- "github.com/apache/skywalking-cli/assets"
-
- "github.com/apache/skywalking-cli/graphql/client"
-
- "github.com/apache/skywalking-cli/graphql/schema"
)
-func IntValues(ctx *cli.Context, condition schema.BatchMetricConditions, duration schema.Duration) schema.IntValues {
- var response map[string]schema.IntValues
+func IntValues(ctx *cli.Context, condition schema.MetricsCondition, duration schema.Duration) int {
+ var response map[string]int
- request := graphql.NewRequest(assets.Read("graphqls/metrics/IntValues.graphql"))
+ request := graphql.NewRequest(assets.Read("graphqls/metrics/MetricsValue.graphql"))
- request.Var("metric", condition)
+ request.Var("condition", condition)
request.Var("duration", duration)
client.ExecuteQueryOrFail(ctx, request, &response)
@@ -80,3 +78,15 @@
return response["result"]
}
+
+func SortMetrics(ctx *cli.Context, condition schema.TopNCondition, duration schema.Duration) []*schema.SelectedRecord {
+ var response map[string][]*schema.SelectedRecord
+
+ request := graphql.NewRequest(assets.Read("graphqls/metrics/SortMetrics.graphql"))
+ request.Var("condition", condition)
+ request.Var("duration", duration)
+
+ client.ExecuteQueryOrFail(ctx, request, &response)
+
+ return response["result"]
+}