You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2020/03/06 12:48:36 UTC
[skywalking-cli] branch master updated: [Feature] Support multiple
linear metrics and enhance Ascii Graph Display (#30)
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 6542344 [Feature] Support multiple linear metrics and enhance Ascii Graph Display (#30)
6542344 is described below
commit 6542344a89605f04fa32471da4bd5575df677bee
Author: kezhenxu94 <ke...@apache.org>
AuthorDate: Fri Mar 6 20:48:25 2020 +0800
[Feature] Support multiple linear metrics and enhance Ascii Graph Display (#30)
### Motivation
Adopt the new API of multiple linear metrics, https://github.com/apache/skywalking/pull/4214
### Modification
- Rewrite the pxx metrics with the new API
- Slightly refactor the GraphQL client into individual package, according to the query protocol
- Enhance the Ascii Graph display style
### Result
- CLI is compatible with the latest backend
- Ascii Graph can display multiple charts in one screen
---
.golangci.yml | 2 +-
Makefile | 5 +-
README.md | 101 ++++++++++++--
commands/endpoint/list.go | 5 +-
commands/instance/instance.go | 5 +-
commands/instance/list.go | 5 +-
commands/instance/search.go | 5 +-
commands/interceptor/duration.go | 12 +-
commands/metrics/linear/linear-metrics.go | 22 +--
...inear-metrics.go => multiple-linear-metrics.go} | 39 ++++--
.../graph/graph.go => commands/metrics/metrics.go | 24 ++--
commands/metrics/single/single-metrics.go | 9 +-
commands/service/list.go | 7 +-
display/display.go | 8 +-
display/graph/graph.go | 14 +-
display/graph/linear/linear.go | 82 +++++++----
graphql/client/client.go | 150 +--------------------
graphql/metadata/metadata.go | 93 ++++++++++++-
graphql/metrics/metrics.go | 82 +++++++++++
graphql/{metadata/metadata.go => utils/adapter.go} | 37 ++---
graphql/{schema => utils}/constants.go | 32 +++--
swctl/main.go | 12 +-
22 files changed, 468 insertions(+), 283 deletions(-)
diff --git a/.golangci.yml b/.golangci.yml
index cebf66b..26b94e2 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -38,7 +38,7 @@ linters-settings:
misspell:
locale: US
lll:
- line-length: 120
+ line-length: 150
goimports:
local-prefixes: github.com/apache/skywalking-cli
gocritic:
diff --git a/Makefile b/Makefile
index 8ddb4eb..885df84 100644
--- a/Makefile
+++ b/Makefile
@@ -57,7 +57,7 @@ $(PLATFORMS):
GOOS=$(os) GOARCH=$(ARCH) $(GO_BUILD) $(GO_BUILD_FLAGS) -ldflags "$(GO_BUILD_LDFLAGS)" -o $(OUT_DIR)/$(BINARY)-$(VERSION)-$(os)-$(ARCH) swctl/main.go
.PHONY: lint
-lint:
+lint: codegen
$(GO_LINT) version || curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GO_PATH)/bin v1.21.0
$(GO_LINT) run -v ./...
@@ -86,7 +86,7 @@ coverage: test
bash <(curl -s https://codecov.io/bash) -t a5af28a3-92a2-4b35-9a77-54ad99b1ae00
.PHONY: clean
-clean:
+clean: codegen
$(GO_CLEAN) ./...
-rm -rf bin
-rm -rf coverage.txt
@@ -94,6 +94,7 @@ clean:
-rm -rf *.tgz
-rm -rf *.asc
-rm -rf *.sha512
+ -rm -rf query-protocol/schema.graphqls
release-src: clean
-tar -zcvf $(RELEASE_SRC).tgz \
diff --git a/README.md b/README.md
index 00f225c..0467d09 100644
--- a/README.md
+++ b/README.md
@@ -149,11 +149,13 @@ This section covers all the available commands in SkyWalking CLI and their usage
</details>
-### `linear-metrics`
+### `metrics`
+
+#### `metrics linear`
<details>
-<summary>linear-metrics [--start=start-time] [--end=end-time] --name=metrics-name [--id=entity-id]</summary>
+<summary>metrics linear [--start=start-time] [--end=end-time] --name=metrics-name [--id=entity-id]</summary>
| option | description | default |
| :--- | :--- | :--- |
@@ -164,11 +166,27 @@ This section covers all the available commands in SkyWalking CLI and their usage
</details>
-### `single-metrics`
+#### `metrics multiple-linear`
<details>
-<summary>single-metrics [--start=start-time] [--end=end-time] --name=metrics-name [--ids=entity-ids]</summary>
+<summary>metrics multiple-linear [--start=start-time] [--end=end-time] --name=metrics-name [--id=entity-id] [--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/official_analysis.oal), such as `all_p99`, etc. |
+| `--id` | the related id if the metrics requires one, e.g. for metrics `service_p99`, the service `id` is required, use `--id` to specify the service id, the same for `instance`, `endpoint`, etc. |
+| `--start` | See [Common options](#common-options) | See [Common options](#common-options) |
+| `--end` | See [Common options](#common-options) | See [Common options](#common-options) |
+| `--num` | Number of the linear metrics to fetch | `5` |
+
+</details>
+
+#### `metrics single`
+
+<details>
+
+<summary>metrics single [--start=start-time] [--end=end-time] --name=metrics-name [--ids=entity-ids]</summary>
| option | description | default |
| :--- | :--- | :--- |
@@ -239,7 +257,7 @@ otherwise,
If you have already got the `id` of the instance:
```shell
-$ ./bin/swctl --display=graph linear-metrics --name=service_instance_resp_time --id 5
+$ ./bin/swctl --display=graph metrics linear --name=service_instance_resp_time --id 5
┌─────────────────────────────────────────────────────────────────────────────────Press q to quit──────────────────────────────────────────────────────────────────────────────────┐
│ │
│ │
@@ -263,7 +281,7 @@ $ ./bin/swctl --display=graph linear-metrics --name=service_instance_resp_time -
otherwise
```shell
-$ ./bin/swctl instance ls --service-name=projectC | jq '.[] | select(.name == "projectC-pid:7895@skywalking-server-0001").id' | xargs ./bin/swctl --display=graph linear-metrics --name=service_instance_resp_time --id
+$ ./bin/swctl instance ls --service-name=projectC | jq '.[] | select(.name == "projectC-pid:7895@skywalking-server-0001").id' | xargs ./bin/swctl --display=graph metrics linear --name=service_instance_resp_time --id
┌─────────────────────────────────────────────────────────────────────────────────Press q to quit──────────────────────────────────────────────────────────────────────────────────┐
│ │
│ │
@@ -291,7 +309,7 @@ $ ./bin/swctl instance ls --service-name=projectC | jq '.[] | select(.name == "p
<summary>Query a single metrics value for a specific endpoint</summary>
```shell
-$ ./bin/swctl service ls projectC | jq '.[0].id' | xargs ./bin/swctl endpoint ls --service-id | jq '.[] | [.id] | join(",")' | xargs ./bin/swctl single-metrics --name endpoint_cpm --ids
+$ ./bin/swctl service ls projectC | jq '.[0].id' | xargs ./bin/swctl endpoint ls --service-id | jq '.[] | [.id] | join(",")' | xargs ./bin/swctl metrics single --name endpoint_cpm --ids
[{"id":"22","value":116}]
```
@@ -302,7 +320,7 @@ $ ./bin/swctl service ls projectC | jq '.[0].id' | xargs ./bin/swctl endpoint ls
<summary>Query metrics single values for all endpoints of service of id 3</summary>
```shell
-$ ./bin/swctl service ls projectC | jq '.[0].id' | xargs ./bin/swctl endpoint ls --service-id | jq '.[] | [.id] | join(",")' | xargs ./bin/swctl single-metrics --name endpoint_cpm --end='2019-12-02 2137' --ids
+$ ./bin/swctl service ls projectC | jq '.[0].id' | xargs ./bin/swctl endpoint ls --service-id | jq '.[] | [.id] | join(",")' | xargs ./bin/swctl metrics single --name endpoint_cpm --end='2019-12-02 2137' --ids
[{"id":"3","value":116}]
```
@@ -310,6 +328,73 @@ $ ./bin/swctl service ls projectC | jq '.[0].id' | xargs ./bin/swctl endpoint ls
<details>
+<summary>Query multiple metrics values for all percentiles</summary>
+
+```shell
+$ ./bin/swctl-latest-darwin-amd64 --display=graph --debug metrics multiple-linear --name all_percentile
+
+┌PRESS Q TO QUIT───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
+│┌───────────────────────────────#0───────────────────────────────┐┌───────────────────────────────#1───────────────────────────────┐┌─────────────────────────────────#2─────────────────────────────────┐│
+││ │ ⡏⠉⠉⢹ ⢸⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⠉⡇ ⢸⠉⠉⠉⠉⠉⠉⠉⡇ ⢸⠉⠉⠉⠉⠉⠉⠉⡇ ⡏⠉⠉⠉ ││ │ ⢸⡀ ⢸ ⢸ ⡇ ││ │ ⡠⠔⡇ ││
+││960.80│ ⢀⠇ ⠘⡄ ⡜ ⢣ ⢸ ⢇ ⢸ ⡇ ⡇ ││1963.60│ ⡜⡇ ⢸ ⢸ ⢠⡇ ││ 2600.40│ ⡇ ⢣ ││
+││ │ ⢸ ⡇ ⡇ ⢸ ⢸ ⢸ ⡜ ⢸ ⢸ ││ │ ⡇⢸ ⡼⡀ ⣾ ⢸⢣ ││ │ ⢸ ⢸ ││
+││ │ ⢸ ⡇ ⡇ ⢸ ⡸ ⢸ ⡇ ⢸ ⢸ ││ │ ⡇⠈⡆ ⡇⡇ ⡇⡇ ⢸⢸ ││ │ ⢸ ⢸ ││
+││ │ ⢸ ⢣ ⢠⠃ ⠘⡄ ⡇ ⢸ ⡇ ⢸ ⢸ ││ │ ⢰⠁ ⡇ ⡇⡇ ⡤⢤ ⡇⡇ ⡇⢸ ││ │ ⡇ ⠘⡄ ││
+││824.64│ ⡇ ⢸ ⢸ ⡇ ⡇ ⠈⡆ ⡇ ⠘⡄ ⡜ ││1832.88│ ⢸ ⢣ ⡇⡇ ⡇⢸ ⡇⡇ ⡇⢸ ││ 2486.33│ ⡇ ⡇ ││
+││ │ ⡇ ⢸ ⢸ ⡇ ⡇ ⡇ ⡇ ⡇ ⡇ ││ │ ⢸ ⢸ ⡇⡇ ⢸ ⠈⡆ ⢀⠇⡇ ⢠⠃⢸ ││ │ ⢰⠁ ⡇ ││
+││ │ ⡇ ⠈⡆⡎ ⢣ ⡇ ⡇⢸ ⡇ ⡇ ││ │ ⡎ ⢸ ⢰⠁⡇ ⢸ ⡇ ⢸ ⡇ ⢸ ⠘⡄ ││ │ ⡀ ⢸⠉⠲⡀ ⢀ ⢸ ⢱ ││
+││ │⢰⠁ ⡇⡇ ⢸ ⡇ ⢇⢸ ⡇ ⡇ ││ │ ⡇ ⢸ ⢸ ⢱ ⢸ ⡇ ⢸ ⢣ ⢸ ⡇ ││ │⡀ ⢰⢱ ⢀⡄ ⡇ ⢱ ⢀⠎⡆ ⡎ ⢸ ⣀⠤ ││
+││688.48│⢸ ⡇⡇ ⢸ ⡇ ⢸⢸ ⢸⢸ ││1702.16│ ⡇ ⡇ ⢸ ⢸ ⡇ ⢣ ⢸ ⢸ ⡜ ⡇ ││ 2372.24│⠱⡀ ⡴⡀ ⢀ ⢠⠃⠈⡆ ⢀⠎⠸⡀⢠⠃ ⢣⠎ ⢸ ⣠ ⡠⠃ ⢸ ⢰⠁ ││
+││ │⢸ ⢱⠁ ⠘⡄ ⡇ ⢸⢸ ⢸⢸ ││ │ ⢸ ⡇ ⢸ ⢸ ⡇ ⢸ ⢸ ⢸ ⡇ ⡇ ││ │ ⢣ ⡜ ⠱⡀⡠⠋⡆ ⣀⠎ ⢱ ⡠⠊ ⢣⢸ ⢇⡔⠁⢣ ⣀⠔⠁ ⠈⣦⠃ ││
+││ │⡜ ⠸ ⡇ ⢸ ⢸⡜ ⢸⢸ ││ │ ⢸ ⡇ ⡆ ⢀⡆ ⢸ ⢸⢀⠇ ⢸ ⡎ ⢸ ⡇ ⡇ ││ │ ⡇ ⡔⠊ ⠑⠁ ⠸⡀ ⢠⠋ ⠈⠖⠁ ⠈⠇ ⠈ ⠉ ⠏ ││
+││ │⡇ ⢣ ⢸ ⠈⡇ ⠘⡜ ││ │ ⡜ ⢱ ⢠⢣ ⢰⢄ ⡜⢸ ⡇ ⢸⢸ ⢸ ⡇ ⢸ ⢠⠃ ⢱ ││ │ ⢇ ⡇ ⢣⡀ ⡎ ││
+││552.32│⠁ ⠸⡀ ⢸ ⡇ ⡇ ││1571.44│ ⡇ ⢸ ⢸⢸ ⡸ ⠙ ⠘⡄ ⡇ ⠘⣼ ⡇⡇ ⢸ ⢸ ⢸ ││ 2258.16│ ⢸ ⢸ ⠈⠙ ││
+││ │ ⢇ ⢸ ⠁ ││ │ ⢀⠇ ⢸ ⡜⢸ ⡇ ⢇ ⡇ ⡿ ⡇⡇ ⡇ ⢸ ⢸ ││ │ ⢸ ⢸ ││
+││ │ ⢸ ⢸ ││ │⢣ ⢸ ⠸⡀ ⡇ ⡇ ⡇ ⢸ ⡇ ⡇ ⣇⠇ ⡇ ⡜ ⢸ ││ │ ⠈⡆ ⡜ ││
+││ │ ⡇ ⢸ ││ │⠈⢆⡸ ⡇⢀ ⢠⠃ ⡇⢀⠇ ⠈⡦⠔⢇⢀⠇ ⠁ ⢹ ⡇ ⡇ ⢸ ││ │ ⡇ ⡇ ││
+││416.16│ ⢱ ⢸ ││1440.72│ ⠘⡇ ⠋⠙⡄ ⢸ ⢱⢸ ⠸⣸ ⢸ ⠱⡀ ⡇ ⠈⡆ ││2144.080│ ⡇ ⡇ ││
+││ │ ⠘⡄⡎ ││ │ ⢇ ⡎ ⢸⢸ ⢿ ⠱⡀⢠⠃ ⡇ ││ │ ⢸⢸ ││
+││ │ ⡇⡇ ││ │ ⢸ ⢰⠁ ⠸⡜ ⠈ ⠘⣼ ⠧⣀ ││ │ ⢸⢸ ││
+││ │ ⢸⡇ ││ │ ⡇⡎ ⡇ ⠈ ⠑⢄ ││ │ ⠘⡜ ││
+││ 280│ ⠈⡇ ││ 1310│ ⢱⠁ ││ 2030│ ⡇ ││
+││ └─────────────────────────────────────────────────────────││ └────────────────────────────────────────────────────────││ └───────────────────────────────────────────────────────────││
+││ 2020-03-07 0111 2020-03-07 0134 2020-03-07 0133 ││ 2020-03-07 0116 2020-03-07 0121 2020-03-07 0122 ││ 2020-03-07 0123 2020-03-07 0139 2020-03-07 0117 ││
+│└────────────────────────────────────────────────────────────────┘└────────────────────────────────────────────────────────────────┘└────────────────────────────────────────────────────────────────────┘│
+│┌────────────────────────────────────────────────#3─────────────────────────────────────────────────┐┌────────────────────────────────────────────────#4─────────────────────────────────────────────────┐│
+││ │ ⢀⢇ ││ │⠤⠤⠤⠤⠤⠤⡄ ⡤⠤⢤ ⢸⠑⠒⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠤⠒⠊⠉⠉⠉⠉⠉⠉⠉⠒⠢⡄ ⡤⠒⠊⡇ ⢠⠔⠒⢹ ⢠⠔⠒⠉⠑⠢⠄ ││
+││ │ ⡸⠸⡀ ⢀⡆ ││ │ ⡇ ⡇ ⢸ ⡸ ⡇ ⡇ ⢇ ⢸ ⢸ ⢸ ││
+││3559.60│ ⢀⠇ ⢇ ⢀⠎⢸ ││54073.20│ ⢱ ⢰⠁ ⠈⡆ ⡇ ⢱ ⢰⠁ ⢸ ⡜ ⡇ ⡎ ││
+││ │ ⢀⢄ ⡸ ⠸⡀ ⢀⠎ ⠘⡄ ││ │ ⢸ ⢸ ⡇ ⡇ ⢸ ⢸ ⢸ ⡇ ⡇ ⡇ ││
+││ │ ⢀⠎ ⠑⢄ ⢀⠇ ⢇ ⢀⠎ ⡇ ⣼ ││ │ ⢸ ⢸ ⡇ ⡇ ⢸ ⢸ ⢸ ⡇ ⡇ ⡇ ││
+││ │ ⢀⠎ ⠈⢆ ⣀ ⡸ ⠸⡀ ⣀⡀ ⡜ ⢸ ⡸⠸⡀ ││ │ ⠸⡀ ⡸ ⢇ ⢰⠁ ⠸⡀ ⡸ ⠈⡆ ⡇ ⢣ ⢀⠇ ││
+││3325.68│ ⣀⣀ ⣀⠤⠊ ⠘⡄ ⢀⣀⣀⣀⣀⡠⠤⡀ ⢀⣀⠔⠊ ⠉⠑⠃ ⠉⠉ ⠘⢄ ⡰⠁ ⠘⡄ ⢰⠁ ⡇ ⢀⣀⡠⠤⠤⠤⠄ ││43924.56│ ⡇ ⡇ ⢸ ⢸ ⡇ ⡇ ⡇ ⢰⠁ ⢸ ⢸ ││
+││ │ ⢠⠊ ⠉⠉ ⠸⡀ ⡔⠁ ⠑⢄ ⡠⠊⠉⠁ ⠣⣀ ⢠⠃ ⡇ ⢠⠃ ⡇ ⢀⠤⠊⠁ ││ │ ⡇ ⡇ ⢸ ⢸ ⡇ ⡇ ⡇ ⢸ ⢸ ⢸ ││
+││ │⠔⠁ ⠱⠊ ⠈⠢⠊ ⠉⠒⠎ ⠸⠤⠤⠤⠔⠊⠁ ⢇ ⢸ ││ │ ⡇ ⡇ ⢸ ⡸ ⡇ ⡇ ⢇ ⢸ ⢸ ⢸ ││
+││ │ ⢸ ⡎ ││ │ ⢱ ⢰⠁ ⠈⡆ ⡇ ⢸ ⢸ ⢸ ⢸ ⡇ ⡎ ││
+││3091.76│ ⢸ ⡇ ││33775.92│ ⢸ ⢸ ⡇ ⡇ ⢸ ⢸ ⢸ ⡇ ⡇ ⡇ ││
+││ │ ⢸ ⢀⠇ ││ │ ⢸ ⢸ ⡇ ⡇ ⢸ ⢸ ⢸ ⡇ ⡇ ⡇ ││
+││ │ ⡇ ⢸ ││ │ ⠸⡀ ⡸ ⢇ ⢰⠁ ⠘⡄ ⡜ ⠈⡆ ⡇ ⢣ ⢠⠃ ││
+││ │ ⡇ ⢸ ││ │ ⡇ ⡇ ⢸ ⢸ ⡇ ⡇ ⡇ ⢠⠃ ⢸ ⢸ ││
+││2857.84│ ⡇ ⡎ ││23627.28│ ⡇ ⡇ ⢸ ⢸ ⡇ ⡇ ⡇ ⢸ ⢸ ⢸ ││
+││ │ ⢸ ⡇ ││ │ ⡇ ⡇ ⢸ ⡸ ⢇⢀⠇ ⢇ ⢸ ⢸ ⢸ ││
+││ │ ⢸ ⢀⠇ ││ │ ⢱⢰⠁ ⠈⡆ ⡇ ⢸⢸ ⢸ ⢸ ⡇ ⡇ ││
+││ │ ⢸ ⢸ ││ │ ⢸⢸ ⡇ ⡇ ⢸⢸ ⢸ ⡎ ⡇ ⡇ ││
+││2623.92│ ⠈⡆⢸ ││13478.64│ ⢸⢸ ⡇ ⡇ ⢸⢸ ⢸ ⡇ ⡇ ⡇ ││
+││ │ ⡇⡎ ││ │ ⠸⡸ ⢇ ⢰⠁ ⠈⡎ ⠈⡆ ⡇ ⢣ ⢠⠃ ││
+││ │ ⡇⡇ ││ │ ⡇ ⢸ ⣸ ⡇ ⡇ ⡇ ⢸ ⢸ ││
+││ │ ⢱⠇ ││ │ ⠃ ⠘⠊⠉ ⠘⡄⢸ ⠘⠒⠊⠉⠉⠉⠉ ││
+││ 2390│ ⢸ ││ 3330│ ⠈⢾ ││
+││ └───────────────────────────────────────────────────────────────────────────────────────────││ └──────────────────────────────────────────────────────────────────────────────────────────││
+││ 2020-03-07 0115 2020-03-07 0139 2020-03-07 0134 2020-03-07 0136 2020-03-07 0132 ││ 2020-03-07 0115 2020-03-07 0126 2020-03-07 0112 2020-03-07 0134 2020-03-07 0124 ││
+│└───────────────────────────────────────────────────────────────────────────────────────────────────┘└───────────────────────────────────────────────────────────────────────────────────────────────────┘│
+└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
+
+```
+
+</details>
+
+<details>
+
<summary>Automatically convert to server side timezone</summary>
if your backend nodes are deployed in docker and the timezone is UTC, you may not want to convert your timezone to UTC every time you type a command, `--timezone` comes to your rescue.
diff --git a/commands/endpoint/list.go b/commands/endpoint/list.go
index 51ea320..034c6a5 100644
--- a/commands/endpoint/list.go
+++ b/commands/endpoint/list.go
@@ -20,8 +20,9 @@ package endpoint
import (
"github.com/urfave/cli"
+ "github.com/apache/skywalking-cli/graphql/metadata"
+
"github.com/apache/skywalking-cli/display"
- "github.com/apache/skywalking-cli/graphql/client"
)
var ListCommand = cli.Command{
@@ -53,7 +54,7 @@ var ListCommand = cli.Command{
limit := ctx.Int("limit")
keyword := ctx.String("keyword")
- endpoints := client.SearchEndpoints(ctx, serviceID, keyword, limit)
+ endpoints := metadata.SearchEndpoints(ctx, serviceID, keyword, limit)
return display.Display(ctx, endpoints)
},
diff --git a/commands/instance/instance.go b/commands/instance/instance.go
index da83c80..29c86a7 100644
--- a/commands/instance/instance.go
+++ b/commands/instance/instance.go
@@ -20,7 +20,8 @@ package instance
import (
"github.com/urfave/cli"
- "github.com/apache/skywalking-cli/graphql/client"
+ "github.com/apache/skywalking-cli/graphql/metadata"
+
"github.com/apache/skywalking-cli/logger"
)
@@ -43,7 +44,7 @@ func verifyAndSwitchServiceParameter(ctx *cli.Context) string {
}
if serviceID == "" && serviceName != "" {
- service, err := client.SearchService(ctx, serviceName)
+ service, err := metadata.SearchService(ctx, serviceName)
if err != nil {
logger.Log.Fatalln(err)
}
diff --git a/commands/instance/list.go b/commands/instance/list.go
index c20ccb4..eda72c1 100644
--- a/commands/instance/list.go
+++ b/commands/instance/list.go
@@ -20,11 +20,12 @@ package instance
import (
"github.com/urfave/cli"
+ "github.com/apache/skywalking-cli/graphql/metadata"
+
"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/client"
"github.com/apache/skywalking-cli/graphql/schema"
)
@@ -44,7 +45,7 @@ var ListCommand = cli.Command{
start := ctx.String("start")
step := ctx.Generic("step")
- instances := client.Instances(ctx, serviceID, schema.Duration{
+ instances := metadata.Instances(ctx, serviceID, schema.Duration{
Start: start,
End: end,
Step: step.(*model.StepEnumValue).Selected,
diff --git a/commands/instance/search.go b/commands/instance/search.go
index b9e2ac9..b97adae 100644
--- a/commands/instance/search.go
+++ b/commands/instance/search.go
@@ -20,13 +20,14 @@ package instance
import (
"regexp"
+ "github.com/apache/skywalking-cli/graphql/metadata"
+
"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/client"
"github.com/apache/skywalking-cli/graphql/schema"
)
@@ -47,7 +48,7 @@ var SearchCommand = cli.Command{
regex := ctx.String("regex")
- instances := client.Instances(ctx, serviceID, schema.Duration{
+ instances := metadata.Instances(ctx, serviceID, schema.Duration{
Start: start,
End: end,
Step: step.(*model.StepEnumValue).Selected,
diff --git a/commands/interceptor/duration.go b/commands/interceptor/duration.go
index 3eb355a..c52ae69 100644
--- a/commands/interceptor/duration.go
+++ b/commands/interceptor/duration.go
@@ -21,6 +21,8 @@ import (
"strconv"
"time"
+ "github.com/apache/skywalking-cli/graphql/utils"
+
"github.com/urfave/cli"
"github.com/apache/skywalking-cli/graphql/schema"
@@ -29,7 +31,7 @@ import (
func tryParseTime(unparsed string) (schema.Step, time.Time, error) {
var possibleError error = nil
- for step, layout := range schema.StepFormats {
+ for step, layout := range utils.StepFormats {
t, err := time.Parse(layout, unparsed)
if err == nil {
return step, t, nil
@@ -48,9 +50,9 @@ func DurationInterceptor(ctx *cli.Context) error {
startTime, endTime, step := ParseDuration(start, end, timezone)
- if err := ctx.Set("start", startTime.Format(schema.StepFormats[step])); err != nil {
+ if err := ctx.Set("start", startTime.Format(utils.StepFormats[step])); err != nil {
return err
- } else if err := ctx.Set("end", endTime.Format(schema.StepFormats[step])); err != nil {
+ } else if err := ctx.Set("end", endTime.Format(utils.StepFormats[step])); err != nil {
return err
} else if err := ctx.Set("step", step.String()); err != nil {
return err
@@ -103,12 +105,12 @@ func ParseDuration(start, end, timezone string) (startTime, endTime time.Time, s
if step, startTime, err = tryParseTime(start); err != nil {
logger.Log.Fatalln("Unsupported time format:", start, err)
}
- return startTime, startTime.Add(30 * schema.StepDuration[step]), step
+ return startTime, startTime.Add(30 * utils.StepDuration[step]), step
} else { // start is absent
if step, endTime, err = tryParseTime(end); err != nil {
logger.Log.Fatalln("Unsupported time format:", end, err)
}
- return endTime.Add(-30 * schema.StepDuration[step]), endTime, step
+ return endTime.Add(-30 * utils.StepDuration[step]), endTime, step
}
}
diff --git a/commands/metrics/linear/linear-metrics.go b/commands/metrics/linear/linear-metrics.go
index ceda447..d435063 100644
--- a/commands/metrics/linear/linear-metrics.go
+++ b/commands/metrics/linear/linear-metrics.go
@@ -20,16 +20,18 @@ package linear
import (
"github.com/urfave/cli"
+ "github.com/apache/skywalking-cli/graphql/metrics"
+ "github.com/apache/skywalking-cli/graphql/utils"
+
"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/client"
"github.com/apache/skywalking-cli/graphql/schema"
)
-var Command = cli.Command{
- Name: "linear-metrics",
+var Single = cli.Command{
+ Name: "linear",
Usage: "Query linear metrics defined in backend OAL",
Flags: flags.Flags(
flags.DurationFlags,
@@ -62,15 +64,17 @@ var Command = cli.Command{
id = &idString
}
- metricsValues := client.LinearIntValues(ctx, schema.MetricCondition{
- Name: metricsName,
- ID: id,
- }, schema.Duration{
+ duration := schema.Duration{
Start: start,
End: end,
Step: step.(*model.StepEnumValue).Selected,
- })
+ }
+
+ metricsValues := metrics.LinearIntValues(ctx, schema.MetricCondition{
+ Name: metricsName,
+ ID: id,
+ }, duration)
- return display.Display(ctx, metricsValues)
+ return display.Display(ctx, utils.MetricsToMap(duration, metricsValues))
},
}
diff --git a/commands/metrics/linear/linear-metrics.go b/commands/metrics/linear/multiple-linear-metrics.go
similarity index 70%
copy from commands/metrics/linear/linear-metrics.go
copy to commands/metrics/linear/multiple-linear-metrics.go
index ceda447..31db251 100644
--- a/commands/metrics/linear/linear-metrics.go
+++ b/commands/metrics/linear/multiple-linear-metrics.go
@@ -20,23 +20,25 @@ package linear
import (
"github.com/urfave/cli"
+ "github.com/apache/skywalking-cli/graphql/metrics"
+ "github.com/apache/skywalking-cli/graphql/utils"
+
"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/client"
"github.com/apache/skywalking-cli/graphql/schema"
)
-var Command = cli.Command{
- Name: "linear-metrics",
- Usage: "Query linear metrics defined in backend OAL",
+var Multiple = cli.Command{
+ Name: "multiple-linear",
+ Usage: "Query multiple linear metrics defined in backend OAL",
Flags: flags.Flags(
flags.DurationFlags,
[]cli.Flag{
cli.StringFlag{
Name: "name",
- Usage: "metrics `NAME`, such as `all_p99`",
+ Usage: "metrics `NAME`, such as `all_percentile`",
Required: true,
},
cli.StringFlag{
@@ -44,6 +46,12 @@ var Command = cli.Command{
Usage: "`ID`, the related id if the metrics requires one",
Required: false,
},
+ cli.IntFlag{
+ Name: "num",
+ Usage: "`num`, the number of linear metrics to query, (default: 5)",
+ Required: false,
+ Value: 5,
+ },
},
),
Before: interceptor.BeforeChain([]cli.BeforeFunc{
@@ -55,6 +63,7 @@ var Command = cli.Command{
start := ctx.String("start")
step := ctx.Generic("step")
metricsName := ctx.String("name")
+ numOfLinear := ctx.Int("num")
var id *string = nil
@@ -62,15 +71,23 @@ var Command = cli.Command{
id = &idString
}
- metricsValues := client.LinearIntValues(ctx, schema.MetricCondition{
- Name: metricsName,
- ID: id,
- }, schema.Duration{
+ duration := schema.Duration{
Start: start,
End: end,
Step: step.(*model.StepEnumValue).Selected,
- })
+ }
+
+ values := metrics.MultipleLinearIntValues(ctx, schema.MetricCondition{
+ Name: metricsName,
+ ID: id,
+ }, numOfLinear, duration)
+
+ reshaped := make([]map[string]float64, len(values))
+
+ for index, value := range values {
+ reshaped[index] = utils.MetricsToMap(duration, value)
+ }
- return display.Display(ctx, metricsValues)
+ return display.Display(ctx, reshaped)
},
}
diff --git a/display/graph/graph.go b/commands/metrics/metrics.go
similarity index 69%
copy from display/graph/graph.go
copy to commands/metrics/metrics.go
index 7184360..8f941b9 100644
--- a/display/graph/graph.go
+++ b/commands/metrics/metrics.go
@@ -15,21 +15,21 @@
// specific language governing permissions and limitations
// under the License.
-package graph
+package metrics
import (
- "fmt"
- "reflect"
+ "github.com/urfave/cli"
- "github.com/apache/skywalking-cli/display/graph/linear"
+ "github.com/apache/skywalking-cli/commands/metrics/linear"
+ "github.com/apache/skywalking-cli/commands/metrics/single"
)
-func Display(object interface{}) error {
- if reflect.TypeOf(object) != reflect.TypeOf(map[string]float64{}) {
- return fmt.Errorf("type of %T is not supported to be displayed as ascii graph", reflect.TypeOf(object))
- }
-
- kvs := object.(map[string]float64)
-
- return linear.Display(kvs)
+var Command = cli.Command{
+ Name: "metrics",
+ Usage: "Query metrics defined in backend OAL",
+ Subcommands: cli.Commands{
+ single.Command,
+ linear.Single,
+ linear.Multiple,
+ },
}
diff --git a/commands/metrics/single/single-metrics.go b/commands/metrics/single/single-metrics.go
index 99817da..69405ea 100644
--- a/commands/metrics/single/single-metrics.go
+++ b/commands/metrics/single/single-metrics.go
@@ -20,18 +20,19 @@ package single
import (
"strings"
+ "github.com/apache/skywalking-cli/graphql/metrics"
+
"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/client"
"github.com/apache/skywalking-cli/graphql/schema"
)
var Command = cli.Command{
- Name: "single-metrics",
+ Name: "single",
Usage: "Query single metrics defined in backend OAL",
Flags: flags.Flags(
flags.DurationFlags,
@@ -65,7 +66,7 @@ var Command = cli.Command{
ids = append(ids, strings.Split(id, ",")...)
}
- metricsValues := client.IntValues(ctx, schema.BatchMetricConditions{
+ metricsValues := metrics.IntValues(ctx, schema.BatchMetricConditions{
Name: metricsName,
Ids: ids,
}, schema.Duration{
@@ -74,6 +75,6 @@ var Command = cli.Command{
Step: step.(*model.StepEnumValue).Selected,
})
- return display.Display(ctx, metricsValues)
+ return display.Display(ctx, metricsValues.Values)
},
}
diff --git a/commands/service/list.go b/commands/service/list.go
index 8400a47..2604a6f 100644
--- a/commands/service/list.go
+++ b/commands/service/list.go
@@ -20,11 +20,12 @@ package service
import (
"github.com/urfave/cli"
+ "github.com/apache/skywalking-cli/graphql/metadata"
+
"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/client"
"github.com/apache/skywalking-cli/graphql/schema"
)
@@ -47,13 +48,13 @@ var ListCommand = cli.Command{
var services []schema.Service
if args := ctx.Args(); len(args) == 0 {
- services = client.Services(ctx, schema.Duration{
+ services = metadata.AllServices(ctx, schema.Duration{
Start: start,
End: end,
Step: step.(*model.StepEnumValue).Selected,
})
} else {
- service, _ := client.SearchService(ctx, args.First())
+ service, _ := metadata.SearchService(ctx, args.First())
services = []schema.Service{service}
}
diff --git a/display/display.go b/display/display.go
index 48be6ab..e620673 100644
--- a/display/display.go
+++ b/display/display.go
@@ -31,10 +31,10 @@ import (
)
const (
- JSON string = "json"
- YAML string = "yaml"
- TABLE string = "table"
- GRAPH string = "graph"
+ JSON = "json"
+ YAML = "yaml"
+ TABLE = "table"
+ GRAPH = "graph"
)
// Display the object in the style specified in flag --display
diff --git a/display/graph/graph.go b/display/graph/graph.go
index 7184360..c27f835 100644
--- a/display/graph/graph.go
+++ b/display/graph/graph.go
@@ -25,11 +25,17 @@ import (
)
func Display(object interface{}) error {
- if reflect.TypeOf(object) != reflect.TypeOf(map[string]float64{}) {
- return fmt.Errorf("type of %T is not supported to be displayed as ascii graph", reflect.TypeOf(object))
+ if reflect.TypeOf(object) == reflect.TypeOf(map[string]float64{}) {
+ kvs := []map[string]float64{object.(map[string]float64)}
+
+ return linear.Display(kvs)
}
- kvs := object.(map[string]float64)
+ if reflect.TypeOf(object) == reflect.TypeOf([]map[string]float64{}) {
+ kvs := object.([]map[string]float64)
+
+ return linear.Display(kvs)
+ }
- return linear.Display(kvs)
+ return fmt.Errorf("type of %T is not supported to be displayed as ascii graph", reflect.TypeOf(object))
}
diff --git a/display/graph/linear/linear.go b/display/graph/linear/linear.go
index b6e6d07..c632112 100644
--- a/display/graph/linear/linear.go
+++ b/display/graph/linear/linear.go
@@ -19,14 +19,15 @@ package linear
import (
"context"
+ "fmt"
+ "math"
"strings"
- "github.com/mum4k/termdash/widgetapi"
+ "github.com/mum4k/termdash/linestyle"
"github.com/mum4k/termdash"
"github.com/mum4k/termdash/container"
"github.com/mum4k/termdash/container/grid"
- "github.com/mum4k/termdash/linestyle"
"github.com/mum4k/termdash/terminal/termbox"
"github.com/mum4k/termdash/terminal/terminalapi"
"github.com/mum4k/termdash/widgets/linechart"
@@ -34,20 +35,19 @@ import (
const RootID = "root"
-func newWidgets(inputs map[string]float64) (lineChart *linechart.LineChart, err error) {
+func newLineChart(inputs map[string]float64) (lineChart *linechart.LineChart, err error) {
index := 0
xLabels := map[int]string{}
- var yValues []float64
+ yValues := make([]float64, len(inputs))
+
for xLabel, yValue := range inputs {
xLabels[index] = xLabel
+ yValues[index] = yValue
index++
- yValues = append(yValues, yValue)
}
- if lineChart, err = linechart.New(
- linechart.YAxisAdaptive(),
- ); err != nil {
+ if lineChart, err = linechart.New(linechart.YAxisAdaptive()); err != nil {
return
}
@@ -56,21 +56,42 @@ func newWidgets(inputs map[string]float64) (lineChart *linechart.LineChart, err
return lineChart, err
}
-func gridLayout(lineChart widgetapi.Widget) ([]container.Option, error) {
- widget := grid.Widget(
- lineChart,
- container.Border(linestyle.Light),
- container.BorderTitleAlignCenter(),
- container.BorderTitle("Press q to quit"),
- )
+func layout(lineCharts ...*linechart.LineChart) ([]container.Option, error) {
+ cols := maxSqrt(len(lineCharts))
+
+ rows := make([][]grid.Element, int(math.Ceil(float64(len(lineCharts))/float64(cols))))
+
+ for r := 0; r < len(rows); r++ {
+ var row []grid.Element
+ for c := 0; c < cols && r*cols+c < len(lineCharts); c++ {
+ percentage := int(math.Floor(float64(100) / float64(cols)))
+ if r == len(rows)-1 {
+ percentage = int(math.Floor(float64(100) / float64(len(lineCharts)-r*cols)))
+ }
+ row = append(row, grid.ColWidthPerc(
+ int(math.Min(99, float64(percentage))),
+ grid.Widget(
+ lineCharts[r*cols+c],
+ container.Border(linestyle.Light),
+ container.BorderTitleAlignCenter(),
+ container.BorderTitle(fmt.Sprintf("#%v", r*cols+c)),
+ ),
+ ))
+ }
+ rows[r] = row
+ }
builder := grid.New()
- builder.Add(widget)
+
+ for _, row := range rows {
+ percentage := int(math.Min(99, float64(100/len(rows))))
+ builder.Add(grid.RowHeightPerc(percentage, row...))
+ }
return builder.Build()
}
-func Display(inputs map[string]float64) error {
+func Display(inputs []map[string]float64) error {
t, err := termbox.New()
if err != nil {
return err
@@ -80,26 +101,31 @@ func Display(inputs map[string]float64) error {
c, err := container.New(
t,
container.ID(RootID),
- container.PaddingTop(2),
- container.PaddingRight(2),
- container.PaddingBottom(2),
- container.PaddingLeft(2),
)
if err != nil {
return err
}
- w, err := newWidgets(inputs)
- if err != nil {
- return err
+ var elements []*linechart.LineChart
+
+ for _, input := range inputs {
+ w, e := newLineChart(input)
+ if e != nil {
+ return e
+ }
+ elements = append(elements, w)
}
- gridOpts, err := gridLayout(w)
+ gridOpts, err := layout(elements...)
if err != nil {
return err
}
- err = c.Update(RootID, gridOpts...)
+ err = c.Update(RootID, append(
+ gridOpts,
+ container.Border(linestyle.Light),
+ container.BorderTitle("PRESS Q TO QUIT"))...,
+ )
if err != nil {
return err
@@ -116,3 +142,7 @@ func Display(inputs map[string]float64) error {
return err
}
+
+func maxSqrt(num int) int {
+ return int(math.Ceil(math.Sqrt(float64(num))))
+}
diff --git a/graphql/client/client.go b/graphql/client/client.go
index a0766ef..a14f2f8 100644
--- a/graphql/client/client.go
+++ b/graphql/client/client.go
@@ -19,13 +19,10 @@ package client
import (
"context"
- "fmt"
- "time"
"github.com/machinebox/graphql"
"github.com/urfave/cli"
- "github.com/apache/skywalking-cli/graphql/schema"
"github.com/apache/skywalking-cli/logger"
)
@@ -37,6 +34,7 @@ func newClient(cliCtx *cli.Context) (client *graphql.Client) {
return
}
+// ExecuteQuery executes the `request` and parse to the `response`, returning `error` if there is any.
func ExecuteQuery(cliCtx *cli.Context, request *graphql.Request, response interface{}) error {
client := newClient(cliCtx)
ctx := context.Background()
@@ -44,151 +42,9 @@ func ExecuteQuery(cliCtx *cli.Context, request *graphql.Request, response interf
return err
}
+// ExecuteQuery executes the `request` and parse to the `response`, panic if there is any `error`.
func ExecuteQueryOrFail(cliCtx *cli.Context, request *graphql.Request, response interface{}) {
- client := newClient(cliCtx)
- ctx := context.Background()
- if err := client.Run(ctx, request, response); err != nil {
- logger.Log.Fatalln(err)
- }
-}
-
-func Services(cliCtx *cli.Context, duration schema.Duration) []schema.Service {
- var response map[string][]schema.Service
- request := graphql.NewRequest(`
- query ($duration: Duration!) {
- services: getAllServices(duration: $duration) {
- id name
- }
- }
- `)
- request.Var("duration", duration)
-
- ExecuteQueryOrFail(cliCtx, request, &response)
- return response["services"]
-}
-
-func SearchEndpoints(cliCtx *cli.Context, serviceID, keyword string, limit int) []schema.Endpoint {
- var response map[string][]schema.Endpoint
- request := graphql.NewRequest(`
- query ($keyword: String!, $serviceId: ID!, $limit: Int!) {
- endpoints: searchEndpoint(keyword: $keyword, serviceId: $serviceId, limit: $limit) {
- id name
- }
- }
- `)
- request.Var("serviceId", serviceID)
- request.Var("keyword", keyword)
- request.Var("limit", limit)
-
- ExecuteQueryOrFail(cliCtx, request, &response)
- return response["endpoints"]
-}
-
-func GetEndpointInfo(cliCtx *cli.Context, endpointID string) schema.Endpoint {
- var response map[string]schema.Endpoint
- request := graphql.NewRequest(`
- query ($endpointId: ID!) {
- endpoint: getEndpointInfo(endpointId: $endpointId) {
- id name
- }
- }
- `)
- request.Var("endpointId", endpointID)
-
- ExecuteQueryOrFail(cliCtx, request, &response)
- return response["endpoint"]
-}
-
-func Instances(cliCtx *cli.Context, serviceID string, duration schema.Duration) []schema.ServiceInstance {
- var response map[string][]schema.ServiceInstance
- request := graphql.NewRequest(`
- query ($serviceId: ID!, $duration: Duration!) {
- instances: getServiceInstances(duration: $duration, serviceId: $serviceId) {
- id
- name
- language
- instanceUUID
- attributes {
- name
- value
- }
- }
- }
- `)
- request.Var("serviceId", serviceID)
- request.Var("duration", duration)
-
- ExecuteQueryOrFail(cliCtx, request, &response)
- return response["instances"]
-}
-
-func SearchService(cliCtx *cli.Context, serviceCode string) (service schema.Service, err error) {
- var response map[string]schema.Service
- request := graphql.NewRequest(`
- query searchService($serviceCode: String!) {
- service: searchService(serviceCode: $serviceCode) {
- id name
- }
- }
- `)
- request.Var("serviceCode", serviceCode)
-
- ExecuteQueryOrFail(cliCtx, request, &response)
- service = response["service"]
- if service.ID == "" {
- return service, fmt.Errorf("no such service [%s]", serviceCode)
- }
- return service, nil
-}
-
-func LinearIntValues(ctx *cli.Context, condition schema.MetricCondition, duration schema.Duration) map[string]float64 {
- var response map[string]schema.IntValues
-
- request := graphql.NewRequest(`
- query ($metric: MetricCondition!, $duration: Duration!) {
- metrics: getLinearIntValues(metric: $metric, duration: $duration) {
- values { value }
- }
- }
- `)
- request.Var("metric", condition)
- request.Var("duration", duration)
-
- ExecuteQueryOrFail(ctx, request, &response)
-
- values := metricsToMap(duration, response["metrics"].Values)
-
- return values
-}
-
-func IntValues(ctx *cli.Context, condition schema.BatchMetricConditions, duration schema.Duration) []*schema.KVInt {
- var response map[string]schema.IntValues
-
- request := graphql.NewRequest(`
- query ($metric: BatchMetricConditions!, $duration: Duration!) {
- metrics: getValues(metric: $metric, duration: $duration) {
- values { id value }
- }
- }
- `)
- request.Var("metric", condition)
- request.Var("duration", duration)
-
- ExecuteQueryOrFail(ctx, request, &response)
-
- return response["metrics"].Values
-}
-
-func metricsToMap(duration schema.Duration, kvInts []*schema.KVInt) map[string]float64 {
- values := map[string]float64{}
- format := schema.StepFormats[duration.Step]
- startTime, err := time.Parse(format, duration.Start)
- if err != nil {
+ if err := ExecuteQuery(cliCtx, request, response); err != nil {
logger.Log.Fatalln(err)
}
- step := schema.StepDuration[duration.Step]
- for idx, value := range kvInts {
- values[startTime.Add(time.Duration(idx)*step).Format(format)] = float64(value.Value)
- }
- return values
}
diff --git a/graphql/metadata/metadata.go b/graphql/metadata/metadata.go
index 55a1bc7..93b6875 100644
--- a/graphql/metadata/metadata.go
+++ b/graphql/metadata/metadata.go
@@ -18,6 +18,8 @@
package metadata
import (
+ "fmt"
+
"github.com/machinebox/graphql"
"github.com/urfave/cli"
@@ -25,7 +27,97 @@ import (
"github.com/apache/skywalking-cli/graphql/schema"
)
+func AllServices(cliCtx *cli.Context, duration schema.Duration) []schema.Service {
+ var response map[string][]schema.Service
+ request := graphql.NewRequest(`
+ query ($duration: Duration!) {
+ services: getAllServices(duration: $duration) {
+ id name
+ }
+ }
+ `)
+ request.Var("duration", duration)
+
+ client.ExecuteQueryOrFail(cliCtx, request, &response)
+ return response["services"]
+}
+
+func SearchService(cliCtx *cli.Context, serviceCode string) (service schema.Service, err error) {
+ var response map[string]schema.Service
+ request := graphql.NewRequest(`
+ query searchService($serviceCode: String!) {
+ service: searchService(serviceCode: $serviceCode) {
+ id name
+ }
+ }
+ `)
+ request.Var("serviceCode", serviceCode)
+
+ client.ExecuteQueryOrFail(cliCtx, request, &response)
+ service = response["service"]
+ if service.ID == "" {
+ return service, fmt.Errorf("no such service [%s]", serviceCode)
+ }
+ return service, nil
+}
+
+func SearchEndpoints(cliCtx *cli.Context, serviceID, keyword string, limit int) []schema.Endpoint {
+ var response map[string][]schema.Endpoint
+ request := graphql.NewRequest(`
+ query ($keyword: String!, $serviceId: ID!, $limit: Int!) {
+ endpoints: searchEndpoint(keyword: $keyword, serviceId: $serviceId, limit: $limit) {
+ id name
+ }
+ }
+ `)
+ request.Var("serviceId", serviceID)
+ request.Var("keyword", keyword)
+ request.Var("limit", limit)
+
+ client.ExecuteQueryOrFail(cliCtx, request, &response)
+ return response["endpoints"]
+}
+
+func EndpointInfo(cliCtx *cli.Context, endpointID string) schema.Endpoint {
+ var response map[string]schema.Endpoint
+ request := graphql.NewRequest(`
+ query ($endpointId: ID!) {
+ endpoint: getEndpointInfo(endpointId: $endpointId) {
+ id name
+ }
+ }
+ `)
+ request.Var("endpointId", endpointID)
+
+ client.ExecuteQueryOrFail(cliCtx, request, &response)
+ return response["endpoint"]
+}
+
+func Instances(cliCtx *cli.Context, serviceID string, duration schema.Duration) []schema.ServiceInstance {
+ var response map[string][]schema.ServiceInstance
+ request := graphql.NewRequest(`
+ query ($serviceId: ID!, $duration: Duration!) {
+ instances: getServiceInstances(duration: $duration, serviceId: $serviceId) {
+ id
+ name
+ language
+ instanceUUID
+ attributes {
+ name
+ value
+ }
+ }
+ }
+ `)
+ request.Var("serviceId", serviceID)
+ request.Var("duration", duration)
+
+ client.ExecuteQueryOrFail(cliCtx, request, &response)
+ return response["instances"]
+}
+
func ServerTimeInfo(cliCtx *cli.Context) (schema.TimeInfo, error) {
+ var response map[string]schema.TimeInfo
request := graphql.NewRequest(`
query {
timeInfo: getTimeInfo {
@@ -34,7 +126,6 @@ func ServerTimeInfo(cliCtx *cli.Context) (schema.TimeInfo, error) {
}
`)
- var response map[string]schema.TimeInfo
if err := client.ExecuteQuery(cliCtx, request, &response); err != nil {
return schema.TimeInfo{}, err
}
diff --git a/graphql/metrics/metrics.go b/graphql/metrics/metrics.go
new file mode 100644
index 0000000..c086e51
--- /dev/null
+++ b/graphql/metrics/metrics.go
@@ -0,0 +1,82 @@
+// 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 metrics
+
+import (
+ "github.com/machinebox/graphql"
+ "github.com/urfave/cli"
+
+ "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
+
+ request := graphql.NewRequest(`
+ query ($metric: BatchMetricConditions!, $duration: Duration!) {
+ metrics: getValues(metric: $metric, duration: $duration) {
+ values { id value }
+ }
+ }
+ `)
+ request.Var("metric", condition)
+ request.Var("duration", duration)
+
+ client.ExecuteQueryOrFail(ctx, request, &response)
+
+ return response["metrics"]
+}
+
+func LinearIntValues(ctx *cli.Context, condition schema.MetricCondition, duration schema.Duration) schema.IntValues {
+ var response map[string]schema.IntValues
+
+ request := graphql.NewRequest(`
+ query ($metric: MetricCondition!, $duration: Duration!) {
+ metrics: getLinearIntValues(metric: $metric, duration: $duration) {
+ values { value }
+ }
+ }
+ `)
+ request.Var("metric", condition)
+ request.Var("duration", duration)
+
+ client.ExecuteQueryOrFail(ctx, request, &response)
+
+ return response["metrics"]
+}
+
+func MultipleLinearIntValues(ctx *cli.Context, condition schema.MetricCondition, numOfLinear int, duration schema.Duration) []schema.IntValues {
+ request := graphql.NewRequest(`
+ query ($metric: MetricCondition!, $numOfLinear: Int!, $duration: Duration!) {
+ metrics: getMultipleLinearIntValues(metric: $metric, numOfLinear: $numOfLinear, duration: $duration) {
+ values { value }
+ }
+ }
+ `)
+ request.Var("metric", condition)
+ request.Var("numOfLinear", numOfLinear)
+ request.Var("duration", duration)
+
+ var response map[string][]schema.IntValues
+
+ client.ExecuteQueryOrFail(ctx, request, &response)
+
+ return response["metrics"]
+}
diff --git a/graphql/metadata/metadata.go b/graphql/utils/adapter.go
similarity index 61%
copy from graphql/metadata/metadata.go
copy to graphql/utils/adapter.go
index 55a1bc7..baec147 100644
--- a/graphql/metadata/metadata.go
+++ b/graphql/utils/adapter.go
@@ -15,28 +15,31 @@
// specific language governing permissions and limitations
// under the License.
-package metadata
+package utils
import (
- "github.com/machinebox/graphql"
- "github.com/urfave/cli"
+ "time"
- "github.com/apache/skywalking-cli/graphql/client"
"github.com/apache/skywalking-cli/graphql/schema"
+ "github.com/apache/skywalking-cli/logger"
)
-func ServerTimeInfo(cliCtx *cli.Context) (schema.TimeInfo, error) {
- request := graphql.NewRequest(`
- query {
- timeInfo: getTimeInfo {
- timezone, currentTimestamp
- }
- }
- `)
-
- var response map[string]schema.TimeInfo
- if err := client.ExecuteQuery(cliCtx, request, &response); err != nil {
- return schema.TimeInfo{}, err
+type IntValues schema.IntValues
+
+func MetricsToMap(duration schema.Duration, intValues schema.IntValues) map[string]float64 {
+ kvInts := intValues.Values
+ values := map[string]float64{}
+ format := StepFormats[duration.Step]
+ startTime, err := time.Parse(format, duration.Start)
+
+ if err != nil {
+ logger.Log.Fatalln(err)
}
- return response["timeInfo"], nil
+
+ step := StepDuration[duration.Step]
+ for idx, value := range kvInts {
+ values[startTime.Add(time.Duration(idx)*step).Format(format)] = float64(value.Value)
+ }
+
+ return values
}
diff --git a/graphql/schema/constants.go b/graphql/utils/constants.go
similarity index 64%
rename from graphql/schema/constants.go
rename to graphql/utils/constants.go
index f146338..b4f0f3d 100644
--- a/graphql/schema/constants.go
+++ b/graphql/utils/constants.go
@@ -15,24 +15,28 @@
// specific language governing permissions and limitations
// under the License.
-package schema
+package utils
-import "time"
+import (
+ "time"
+
+ "github.com/apache/skywalking-cli/graphql/schema"
+)
// StepFormats is a mapping from schema.Step to its time format
-var StepFormats = map[Step]string{
- StepSecond: "2006-01-02 150400",
- StepMinute: "2006-01-02 1504",
- StepHour: "2006-01-02 15",
- StepDay: "2006-01-02",
- StepMonth: "2006-01",
+var StepFormats = map[schema.Step]string{
+ schema.StepSecond: "2006-01-02 150400",
+ schema.StepMinute: "2006-01-02 1504",
+ schema.StepHour: "2006-01-02 15",
+ schema.StepDay: "2006-01-02",
+ schema.StepMonth: "2006-01",
}
// StepDuration is a mapping from schema.Step to its time.Duration
-var StepDuration = map[Step]time.Duration{
- StepSecond: time.Second,
- StepMinute: time.Minute,
- StepHour: time.Hour,
- StepDay: time.Hour * 24,
- StepMonth: time.Hour * 24 * 30,
+var StepDuration = map[schema.Step]time.Duration{
+ schema.StepSecond: time.Second,
+ schema.StepMinute: time.Minute,
+ schema.StepHour: time.Hour,
+ schema.StepDay: time.Hour * 24,
+ schema.StepMonth: time.Hour * 24 * 30,
}
diff --git a/swctl/main.go b/swctl/main.go
index 2efdee7..6c39a23 100644
--- a/swctl/main.go
+++ b/swctl/main.go
@@ -21,10 +21,9 @@ import (
"io/ioutil"
"os"
- "github.com/apache/skywalking-cli/commands/endpoint"
- linearMetrics "github.com/apache/skywalking-cli/commands/metrics/linear"
- singleMetrics "github.com/apache/skywalking-cli/commands/metrics/single"
+ "github.com/apache/skywalking-cli/commands/metrics"
+ "github.com/apache/skywalking-cli/commands/endpoint"
"github.com/apache/skywalking-cli/commands/instance"
"github.com/sirupsen/logrus"
@@ -81,11 +80,10 @@ func main() {
}
app.Commands = []cli.Command{
- service.Command,
- instance.Command,
- linearMetrics.Command,
- singleMetrics.Command,
endpoint.Command,
+ instance.Command,
+ service.Command,
+ metrics.Command,
}
app.Before = interceptor.BeforeChain([]cli.BeforeFunc{