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 f6aad1f [Feature] Add endpoint command, refactor Makefile to cross
build target (#17)
f6aad1f is described below
commit f6aad1fde8b945e6f4c17a9c6ade6e9f3728c8a8
Author: kezhenxu94 <[email protected]>
AuthorDate: Mon Dec 2 23:30:46 2019 +0800
[Feature] Add endpoint command, refactor Makefile to cross build target
(#17)
* [Feature] Add endpoint command, refactor Makefile to cross build target
* Add missing documentation and polish
* Fix bug
* Polish
* Re-organize documentations and collapse details for simplicity
* Add some common use cases
* Polish
* Add ascii graph
---
.github/workflows/go.yml | 31 ++-
CONTRIBUTING.md | 84 +++++++
Makefile | 68 +++++-
README.md | 243 ++++++++++++++++-----
.../table.go => commands/endpoint/endpoint.go | 46 +---
.../linear-metrics.go => endpoint/list.go} | 61 +++---
commands/metrics/{ => linear}/linear-metrics.go | 14 +-
.../single-metrics.go} | 25 ++-
display/table/table.go | 14 +-
go.sum | 1 +
graphql/client/client.go | 50 +++++
scripts/build | 28 ---
swctl/main.go | 8 +-
13 files changed, 490 insertions(+), 183 deletions(-)
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index f9485ab..0b6646e 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -15,7 +15,13 @@
# limitations under the License.
name: Build
-on: [push, pull_request]
+
+on:
+ pull_request:
+ push:
+ branches:
+ - master
+
jobs:
build:
@@ -33,27 +39,16 @@ jobs:
uses: actions/checkout@v1
- name: Check License
- run: |
- GO111MODULE=off go get -u github.com/elastic/go-licenser
- $(go env GOPATH)/bin/go-licenser -d -licensor='Apache Software
Foundation (ASF)' .
+ run: make license
- name: Get dependencies
- run: |
- go get -v -t -d ./...
- if [ -f Gopkg.toml ]; then
- curl
https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
- dep ensure
- fi
+ run: make deps
- name: Lint
- run: |
- curl -sfL
https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh
-s -- -b $(go env GOPATH)/bin v1.21.0
- $(go env GOPATH)/bin/golangci-lint run -v ./...
+ run: make lint
- - name: Test
- run: |
- go test ./... -coverprofile=coverage.txt -covermode=atomic
- CODECOV_TOKEN="a5af28a3-92a2-4b35-9a77-54ad99b1ae00" bash <(curl -s
https://codecov.io/bash)
+ - name: Test and report coverage
+ run: make coverage
- name: Build
- run: make clean && make
+ run: make build -j3
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..bf0f7a0
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,84 @@
+# Contributing to Apache SkyWalking CLI
+
+Firstly, thanks for your interest in contributing! We hope that this will be a
+pleasant first experience for you, and that you will return to continue
+contributing.
+
+## Code of Conduct
+
+This project and everyone participating in it is governed by the Apache
+software Foundation's [Code of
Conduct](http://www.apache.org/foundation/policies/conduct.html).
+By participating, you are expected to adhere to this code. If you are aware of
unacceptable behavior, please visit the
+[Reporting Guidelines
page](http://www.apache.org/foundation/policies/conduct.html#reporting-guidelines)
+and follow the instructions there.
+
+## How to contribute?
+
+Most of the contributions that we receive are code contributions, but you can
+also contribute to the documentation or simply report solid bugs
+for us to fix.
+
+## How to report a bug?
+
+* **Ensure the bug was not already reported** by searching on GitHub under
[Issues](https://github.com/apache/skywalking/issues).
+
+* If you're unable to find an open issue addressing the problem, [open a new
one](https://github.com/apache/skywalking/issues/new).
+Be sure to include a **title and clear description**, as much relevant
information as possible,
+and a **code sample** or an **executable test case** demonstrating the
expected behavior that is not occurring.
+
+## How to add a new feature or change an existing one
+
+_Before making any significant changes, please [open an
issue](https://github.com/apache/skywalking/issues)._
+Discussing your proposed changes ahead of time will make the contribution
process smooth for everyone.
+
+Once we've discussed your changes and you've got your code ready, make sure
that tests are passing and open your pull request. Your PR is most likely to be
accepted if it:
+
+* Update the README.md with details of changes to the interface.
+* Includes tests for new functionality.
+* References the original issue in description, e.g. "Resolves #123".
+* Has a [good commit
message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html).
+
+## Compiling and building
+Clone the source code and simply run `make` in the source directory,
+this will download all necessary dependencies and run tests, lint, and build
three binary files in `./bin/`, for Windows, Linux, MacOS respectively.
+
+```shell
+make
+```
+
+## Writing a new command
+All commands files locate in directory [`commands`](commands), and an
individual directory for each second-level command,
+an individual `go` file for each third-level command, for example, there is a
directory [`service`](commands/service) for command `swctl service`,
+and a [`list.go`](commands/service/list.go) file for `swctl service list`
command.
+
+Determine what entity your command will operate on, and put your command `go`
file into that directory, or create one if it doesn't exist,
+for example, if you want to create a command to `list` all the `instance`s of
a service, create a directory `commands/instance`,
+and a `go` file `commands/instance/list.go`.
+
+## Reusing common options
+There're some [common options](#common-options) that can be shared by multiple
commands, check [`commands/flags`](commands/flags)
+to get all the shared options, and reuse them when possible, an example shares
the options is [`commands/service/list.go`](commands/service/list.go#L35)
+
+## Linting your codes
+We have some rules for the code style and please lint your codes locally
before opening a pull request
+
+```shell
+make lint
+```
+
+if you found some errors in the output of the above command, try `make fix` to
fix some obvious style issues, as for the complicated errors, please fix them
manually.
+
+## Checking license
+The Apache Software Foundation requires every source file to contain a license
header, run `make license` to check that there is license header in every
source file.
+
+```shell
+make license
+```
+
+## Running tests
+Before submitting a pull request, add some test code to test the
added/modified codes,
+and run the tests locally, make sure all tests passed.
+
+```shell
+make test
+```
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 3273175..a8ad5c4 100644
--- a/Makefile
+++ b/Makefile
@@ -15,11 +15,69 @@
# limitations under the License.
#
-.PHONY: build install
+VERSION ?= latest
+OUT_DIR = bin
+BINARY = swctl
-build:
- GO_BUILD_FLAGS="-v" ./scripts/build
- ./bin/swctl --version
+OS = $(shell uname)
+GO = go
+GO_PATH = $$($(GO) env GOPATH)
+GO_BUILD = $(GO) build
+GO_GET = $(GO) get
+GO_CLEAN = $(GO) clean
+GO_TEST = $(GO) test
+GO_LINT = $(GO_PATH)/bin/golangci-lint
+GO_LICENSER = $(GO_PATH)/bin/go-licenser
+GO_BUILD_FLAGS = -v
+
+PLATFORMS := windows linux darwin
+os = $(word 1, $@)
+ARCH = amd64
+
+SHELL = /bin/bash
+
+all: clean deps lint test license build
+
+deps:
+ $(GO_GET) -v -t -d ./...
+
+.PHONY: $(PLATFORMS)
+$(PLATFORMS):
+ mkdir -p $(OUT_DIR)
+ GOOS=$(os) GOARCH=$(ARCH) $(GO_BUILD) $(GO_BUILD_FLAGS) -o
$(OUT_DIR)/$(BINARY)-$(VERSION)-$(os)-$(ARCH) swctl/main.go
+
+.PHONY: lint
+lint:
+ $(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 ./...
+
+.PHONE: test
+test: clean lint
+ $(GO_TEST) ./... -coverprofile=coverage.txt -covermode=atomic
+
+.PHONY: build
+build: deps windows linux darwin
+
+.PHONY: license
+license: clean
+ $(GO_LICENSER) -version || GO111MODULE=off $(GO_GET) -u
github.com/elastic/go-licenser
+ $(GO_LICENSER) -d -licensor='Apache Software Foundation (ASF)' .
+
+.PHONY: verify
+verify: clean lint test license
+
+.PHONY: fix
+fix:
+ $(GO_LINT) run -v --fix ./...
+ $(GO_LICENSER) -licensor='Apache Software Foundation (ASF)' .
+
+.PHONY: coverage
+coverage: test
+ bash <(curl -s https://codecov.io/bash) -t
a5af28a3-92a2-4b35-9a77-54ad99b1ae00
+
+.PHONY: clean
clean:
- -rm -rf ./bin
\ No newline at end of file
+ $(GO_CLEAN) ./...
+ -rm -rf ./bin
+ -rm -rf coverage.txt
diff --git a/README.md b/README.md
index 8d8ff70..ad81bed 100644
--- a/README.md
+++ b/README.md
@@ -17,11 +17,12 @@ As SkyWalking CLI is using `Makefile`, compiling the
project is as easy as execu
```shell
git clone https://github.com/apache/skywalking-cli
cd skywalking-cli
-make clean && make
+make
```
-and copy the `./bin/swctl` to your `PATH` directory, usually `/usr/bin/` or
`/usr/local/bin`, or you can copy it to any directory you like,
-and add that directory to `PATH`.
+and copy the `./bin/swctl-latest-(darwin|linux|windows)-amd64` to your `PATH`
directory according to your OS,
+usually `/usr/bin/` or `/usr/local/bin`, or you can copy it to any directory
you like,
+and add that directory to `PATH`, we recommend you to rename the
`swctl-latest-(darwin|linux|windows)-amd64` to `swctl`.
# Commands
Commands in SkyWalking CLI are organized into two levels, in the form of
`swctl --option <level1> --option <level2> --option`,
@@ -41,7 +42,10 @@ will list all the `service`s, `service instance`s, etc.
## Common options
There're some common options that are shared by multiple commands, and they
follow the same rules in different commands,
-### `--start`, `--end`
+<details>
+
+<summary>--start, --end</summary>
+
`--start` and `--end` specify a time range during which the query is preformed,
they are both optional and their default values follow the rules below:
@@ -56,18 +60,12 @@ and if `end = 2019-11-09 12`, the precision is `HOUR`, so
`start = end - 30HOUR
e.g. `start = 2019-11-09 1204`, the precision is `MINUTE`, so `end = start +
30 minutes = 2019-11-09 1234`,
and if `start = 2019-11-08 06`, the precision is `HOUR`, so `end = start +
30HOUR = 2019-11-09 12`;
+</details>
## All available commands
This section covers all the available commands in SkyWalking CLI and their
usages.
-- [`swctl`](#swctl-top-level-command)
-- [`service`](#service-second-level-command) (second level command)
- - [`list`, `ls`](#service-list---startstart-time---endend-time)
-- [`instance`](#instance-second-level-command) (second level command)
- - [`list`,
`ls`](#instance-list---service-idservice-id---service-nameservice-name---startstart-time---endend-time)
- -
[`search`](#instance-search---regexinstance-name-regex---service-idservice-id---service-nameservice-name---startstart-time---endend-time)
-
-### `swctl` top-level command
+### `swctl`
`swctl` is the top-level command, which has some options that will take
effects globally.
| option | description | default |
@@ -77,83 +75,228 @@ This section covers all the available commands in
SkyWalking CLI and their usage
| `--base-url` | base url of GraphQL backend |
`http://127.0.0.1:12800/graphql` |
| `--display` | display style when printing the query result, supported styles
are: `json`, `yaml`, `table` | `json` |
-### `service` second-level command
-`service` second-level command is an entry for all operations related to
services,
-and it also has some options and third-level commands.
+### `service`
+
+<details>
+
+<summary>service list [--start=start-time] [--end=end-time]</summary>
-#### `service list [--start=<start time>] [--end=<end time>]`
-`service list` lists all the services in the time range of \[`start`, `end`\].
+`service list` lists all the services in the time range of `[start, end]`.
| option | description | default |
| :--- | :--- | :--- |
| `--start` | See [Common options](#common-options) | See [Common
options](#common-options) |
| `--end` | See [Common options](#common-options) | See [Common
options](#common-options) |
-### `instance` second-level command
-`instance` second-level command is an entry for all operations related to
instances,
-and it also has some options and third-level commands.
+</details>
-#### `instance list [--service-id=<service id>] [--service-name=<service
name>] [--start=<start time>] [--end=<end time>]`
-`instance list` lists all the instances in the time range of \[`start`,
`end`\] and given --service-id or --service-name.
+### `instance`
+
+<details>
+
+<summary>instance list [--start=start-time] [--end=end-time]
[--service-id=service-id] [--service-name=service-name]</summary>
+
+`instance list` lists all the instances in the time range of `[start, end]`
and given `--service-id` or `--service-name`.
| option | description | default |
| :--- | :--- | :--- |
-| `--service-id` | Query service id (priority over --service-name)| |
-| `--service-name` | Query service name | |
+| `--service-id` | Query by service id (priority over `--service-name`)| |
+| `--service-name` | Query by service name if `--service-id` is absent | |
| `--start` | See [Common options](#common-options) | See [Common
options](#common-options) |
| `--end` | See [Common options](#common-options) | See [Common
options](#common-options) |
-#### `instance search [--regex=<instance name regex>] [--service-id=<service
id>] [--service-name=<service name>] [--start=<start time>] [--end=<end time>]`
-`instance search` filter the instance in the time range of \[`start`, `end`\]
and given --regex --service-id or --service-name.
+</details>
+
+<details>
+
+<summary>instance search [--start=start-time] [--end=end-time]
[--regex=instance-name-regex] [--service-id=service-id]
[--service-name=service-name]</summary>
+
+`instance search` filter the instance in the time range of `[start, end]` and
given --regex --service-id or --service-name.
| option | description | default |
| :--- | :--- | :--- |
| `--regex` | Query regex of instance name| |
-| `--service-id` | Query service id (priority over --service-name)| |
-| `--service-name` | Query service name | |
+| `--service-id` | Query by service id (priority over `--service-name`)| |
+| `--service-name` | Query by service name if `service-id` is absent | |
| `--start` | See [Common options](#common-options) | See [Common
options](#common-options) |
| `--end` | See [Common options](#common-options) | See [Common
options](#common-options) |
-### `linear-metrics` second-level command
-`linear-metrics` second-level command is an entrance for all operations
related to linear metrics,
-and it also has some options.
+</details>
+
+### `endpoint`
+
+<details>
+
+<summary>endpoint list [--start=start-time] [--end=end-time]
--service-id=service-id [--limit=count] [--keyword=search-keyword]</summary>
+
+`endpoint list` lists all the endpoints of the given service id in the time
range of `[start, end]`.
+
+| option | description | default |
+| :--- | :--- | :--- |
+| `--service-id` | <service id> whose endpoints are to be searched | |
+| `--limit` | returns at most <limit> endpoints (default: 100) | 100 |
+| `--keyword` | <keyword> of the endpoint name to search for, empty to search
all | "" |
+
+</details>
+
+### `linear-metrics`
+
+<details>
+
+<summary>linear-metrics [--start=start-time] [--end=end-time]
--name=metrics-name [--id=entity-id]</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) |
+
+</details>
+
+### `single-metrics`
+
+<details>
+
+<summary>single-metrics [--start=start-time] [--end=end-time]
--name=metrics-name [--ids=entity-ids]</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 `service_sla`, etc. |
+| `--ids` | IDs that are required by the metric type, such as service IDs for
`service_sla` |
| `--start` | See [Common options](#common-options) | See [Common
options](#common-options) |
| `--end` | See [Common options](#common-options) | See [Common
options](#common-options) |
-# Developer guide
+</details>
+
+# Use Cases
+
+<details>
+
+<summary>Query a specific service by name</summary>
+
+```shell
+# query the service named projectC
+$ ./bin/swctl service ls projectC
+[{"id":"4","name":"projectC"}]
+```
+
+</details>
+
+<details>
+
+<summary>Query instances of a specific service</summary>
+
+If you have already got the `id` of the service:
+
+```shell
+$ ./bin/swctl instance ls --service-id=3
+[{"id":"3","name":"projectD-pid:7909@skywalking-server-0001","attributes":[{"name":"os_name","value":"Linux"},{"name":"host_name","value":"skywalking-server-0001"},{"name":"process_no","value":"7909"},{"name":"ipv4s","value":"192.168.252.12"}],"language":"JAVA","instanceUUID":"ec8a79d7cb58447c978ee85846f6699a"}]
+```
+
+otherwise,
+
+```shell
+$ ./bin/swctl instance ls --service-name=projectC
+[{"id":"3","name":"projectD-pid:7909@skywalking-server-0001","attributes":[{"name":"os_name","value":"Linux"},{"name":"host_name","value":"skywalking-server-0001"},{"name":"process_no","value":"7909"},{"name":"ipv4s","value":"192.168.252.12"}],"language":"JAVA","instanceUUID":"ec8a79d7cb58447c978ee85846f6699a"}]
+```
+
+</details>
+
+<details>
+
+<summary>Query endpoints of a specific service</summary>
+
+If you have already got the `id` of the service:
+
+```shell
+$ ./bin/swctl endpoint ls --service-id=3
+```
+
+otherwise,
+
+```shell
+./bin/swctl service ls projectC | jq '.[].id' | xargs
./bin/swctl-latest-darwin-amd64 endpoint ls --service-id
+[{"id":"22","name":"/projectC/{value}"}]
+```
+
+</details>
+
+<details>
+
+<summary>Query a linear metrics graph for an instance</summary>
+
+If you have already got the `id` of the instance:
-## Compiling and building
-Clone the source code and simply run `make clean && make` in the source
directory,
-this will download all necessary dependencies and build a binary file in
`./bin/swctl`.
+```shell
+$ ./bin/swctl --display=graph linear-metrics --name=service_instance_resp_time
--id 5
+┌─────────────────────────────────────────────────────────────────────────────────Press
q to
quit──────────────────────────────────────────────────────────────────────────────────┐
+│
│
+│
│
+│ │
⡜⠢⡀ │
+│ 1181.80│ ⡰⡀
⢀⡠⢢ ⡰⢣
⡰⠁ ⠈⠢⡀ │
+│ │ ⢠⠃⠱⡀ ⡀
⢀⠔⠁ ⠱⡀ ⢀⠜ ⢣ ⢀⠞⡄
⢠⠃ ⠈⠢⡀ │
+│ │ ⡎ ⠱⡀ ⢀⠔⠊⠱⡀
⢀⣀⣀⣀ ⢀⡠⠊⠁ ⠘⢄ ⢀⠎ ⢣ ⡠⠃ ⠘⡄ ⡎
⠈⠑⠢⢄⡀ ⢀⡠⠔⠊⠁ │
+│ │ ⢀⠤⣀⡀ ⢀⡀ ⡸ ⢣ ⡠⠔⠁ ⠱⡀
⡠⠊⠉⠉⠁ ⠉⠉⠒⠒⠤⠤⣀⣀⣀ ⢀⡠⠔⠊⠁ ⠣⡀⡠⠃ ⢣ ⢀⠔⠤⡀ ⡰⠁ ⠘⡄ ⡜
⠈⠑⠊⠁ │
+│ 1043.41│⡀ ⢀⠔⠁ ⠈⠑⠒⠤⠔⠒⠊⠉⠁⠈⠒⢄ ⢀⠇ ⢣ ⢀⠤⠊ ⠱⡀
⢀⠔⠁ ⠉⠁ ⠑⠁ ⢣ ⡠⠃ ⠈⠒⢄ ⢀⠜ ⠘⡄ ⢰⠁
│
+│ │⠈⠑⠤⣀ ⡠⠊ ⠑⠤⡀ ⡜ ⢣ ⣀⠔⠁ ⠱⡀
⡰⠁ ⠣⢄⣀ ⢠⠊ ⠉⠊ ⠘⡄⢠⠃
│
+│ │ ⠑⠢⠊ ⠈⠢⡀ ⢰⠁ ⠋ ⠱⡀ ⣀⠤⠔⠊
⠉⠒⠢⠔⠁ ⠘⠎
│
+│ │ ⠈⠢⡀ ⢀⠇ ⠑⠊⠉
│
+│ 905│ ⠈⠢⡜
│
+│
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│
+│ 2019-12-02 2121 2019-12-02 2107 2019-12-02 2115 2019-12-02
2119 2019-12-02 2137 2019-12-02 2126 2019-12-02 2118 2019-12-02 2128
2019-12-02 2136 │
+│
│
+│
│
+└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
+```
+
+otherwise
```shell
-make clean && make
+$ ./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
+┌─────────────────────────────────────────────────────────────────────────────────Press
q to
quit──────────────────────────────────────────────────────────────────────────────────┐
+│
│
+│
│
+│ │
⡠⠒⢣
│
+│ 1181.80│ ⡠⠊⢢
⣀⠔⠉ ⢣ ⡔⡄ ⡔⡄
│
+│ │ ⣀ ⡠⠊ ⠑⡄
⣀⡠⠔⠒⠉ ⢣ ⡜ ⠈⢆ ⢀⠎ ⠈⢢ ⡀
│
+│ │ ⡜ ⠉⠒⠤⣀ ⢀⣀⣀⡠⠊ ⠈⠢⡀ ⢀⡠⢄⣀⡀ ⡰⠉
⢣ ⡜ ⢣ ⡠⠃ ⠑⡄ ⢀⡠⠔⠉⠘⢄
│
+│ │ ⢀⠜ ⠉⠉⠉⠁ ⠑⢄ ⢀⡠⠔⠊⠁ ⠈⠉⠑⢢ ⡰⠁
⢣ ⢀⠎ ⠱⡀ ⢀⠦⡀ ⢀⠜ ⠈⢢ ⢀⣀⣀⡠⠤⠒⠁ ⠣⡀
⡀ │
+│ 1043.41│ ⢀⠎ ⠑⢄ ⢀⠔⠁ ⠱⡀ ⡰⠁
⢣⣀ ⢀⠎ ⠘⢄ ⢀⠎ ⠈⢢ ⢀⠤⠊ ⠉⠁
⠘⢄ ⡠⠊ │
+│ │ ⢠⠃ ⠈⠢⡀ ⡠⠒⠁ ⠘⢄ ⡰⠁
⠉⠉⠉⠒⠊ ⠈⢢ ⢀⠎ ⠑⢄ ⡠⠒⠁
⠣⠤⣀⣀⣀ ⢀⠔⠉ │
+│ │⠤⠤⠤⠤⠤⠤⠃ ⠈⠢⠊ ⠣⡀⡰⠁
⠱⡀ ⢀⠎ ⠑⠉
⠉⠉⠉⠉⠒⠒⠒⠁ │
+│ │ ⠑⠁
⠑⡄ ⢀⠎
│
+│ 905│
⠈⢆⠎
│
+│
└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│
+│ 2019-12-02 2122 2019-12-02 2137 2019-12-02 2136 2019-12-02
2128 2019-12-02 2108 2019-12-02 2130 2019-12-02 2129 2019-12-02 2115
2019-12-02 2119 │
+│
│
+│
│
+└──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
```
-## Writing a new command
-All commands files locate in directory [`commands`](commands), and an
individual directory for each second-level command,
-an individual `go` file for each third-level command, for example, there is a
directory [`service`](commands/service) for command `swctl service`,
-and a [`list.go`](commands/service/list.go) file for `swctl service list`
command.
+</details>
-Determine what entity your command will operate on, and put your command `go`
file into that directory, or create one if it doesn't exist,
-for example, if you want to create a command to `list` all the `instance`s of
a service, create a directory `commands/instance`,
-and a `go` file `commands/instance/list.go`.
+<details>
-## Reusing common options
-There're some [common options](#common-options) that can be shared by multiple
commands, check [`commands/flags`](commands/flags)
-to get all the shared options, and reuse them when possible, an example shares
the options is [`commands/service/list.go`](commands/service/list.go#L35)
+<summary>Query a single metrics value for a specific endpoint</summary>
-## Running tests
-Before submitting a pull request, add some test code to test the
added/modified codes,
-and run the tests locally, make sure all tests passed.
+```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
+[{"id":"22","value":116}]
+```
+
+</details>
+
+<details>
+
+<summary>Query metrics single values for all endpoints of service of id
3</summary>
```shell
-go test -v ./...
+$ ./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
+[{"id":"3","value":116}]
```
+</details>
+
# License
[Apache 2.0 License.](/LICENSE)
diff --git a/display/table/table.go b/commands/endpoint/endpoint.go
similarity index 56%
copy from display/table/table.go
copy to commands/endpoint/endpoint.go
index d79f917..d357224 100644
--- a/display/table/table.go
+++ b/commands/endpoint/endpoint.go
@@ -15,45 +15,17 @@
// specific language governing permissions and limitations
// under the License.
-package table
+package endpoint
import (
- "encoding/json"
- "os"
-
- "github.com/olekukonko/tablewriter"
+ "github.com/urfave/cli"
)
-func Display(object interface{}) error {
- var objMaps []map[string]string
-
- bytes, _ := json.Marshal(object)
- _ = json.Unmarshal(bytes, &objMaps)
-
- if len(objMaps) < 1 {
- return nil
- }
-
- var header []string
-
- for k := range objMaps[0] {
- header = append(header, k)
- }
-
- var data [][]string
-
- for _, objMap := range objMaps {
- var datum []string
- for _, key := range header {
- datum = append(datum, objMap[key])
- }
- data = append(data, datum)
- }
-
- table := tablewriter.NewWriter(os.Stdout)
- table.SetHeader(header)
- table.AppendBulk(data)
- table.Render()
-
- return nil
+var Command = cli.Command{
+ Name: "endpoint",
+ ShortName: "e",
+ Usage: "Endpoint related sub-command",
+ Subcommands: cli.Commands{
+ ListCommand,
+ },
}
diff --git a/commands/metrics/linear-metrics.go b/commands/endpoint/list.go
similarity index 50%
copy from commands/metrics/linear-metrics.go
copy to commands/endpoint/list.go
index e3148fe..51ea320 100644
--- a/commands/metrics/linear-metrics.go
+++ b/commands/endpoint/list.go
@@ -15,49 +15,46 @@
// specific language governing permissions and limitations
// under the License.
-package metrics
+package endpoint
import (
"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: "linear-metrics",
- 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,
- },
+var ListCommand = cli.Command{
+ Name: "list",
+ ShortName: "ls",
+ Usage: "List endpoints",
+ Description: "list all endpoints if no <endpoint id> is given,
otherwise, only list the given endpoint",
+ Flags: []cli.Flag{
+ cli.StringFlag{
+ Name: "service-id",
+ Usage: "`<service id>` whose endpoints are to be
searched",
+ Required: true,
},
- ),
- Before: interceptor.BeforeChain([]cli.BeforeFunc{
- interceptor.DurationInterceptor,
- }),
+ cli.IntFlag{
+ Name: "limit",
+ Usage: "returns at most `<limit>` endpoints",
+ Required: false,
+ Value: 100,
+ },
+ cli.StringFlag{
+ Name: "keyword",
+ Usage: "`<keyword>` of the endpoint name to search
for, empty to search all",
+ Required: false,
+ Value: "",
+ },
+ },
Action: func(ctx *cli.Context) error {
- end := ctx.String("end")
- start := ctx.String("start")
- step := ctx.Generic("step")
- metricsName := ctx.String("name")
+ serviceID := ctx.String("service-id")
+ limit := ctx.Int("limit")
+ keyword := ctx.String("keyword")
- metricsValues := client.LinearIntValues(ctx,
schema.MetricCondition{
- Name: metricsName,
- }, schema.Duration{
- Start: start,
- End: end,
- Step: step.(*model.StepEnumValue).Selected,
- })
+ endpoints := client.SearchEndpoints(ctx, serviceID, keyword,
limit)
- return display.Display(ctx, metricsValues)
+ return display.Display(ctx, endpoints)
},
}
diff --git a/commands/metrics/linear-metrics.go
b/commands/metrics/linear/linear-metrics.go
similarity index 88%
copy from commands/metrics/linear-metrics.go
copy to commands/metrics/linear/linear-metrics.go
index e3148fe..f34289a 100644
--- a/commands/metrics/linear-metrics.go
+++ b/commands/metrics/linear/linear-metrics.go
@@ -15,7 +15,7 @@
// specific language governing permissions and limitations
// under the License.
-package metrics
+package linear
import (
"github.com/urfave/cli"
@@ -39,6 +39,11 @@ var Command = cli.Command{
Usage: "metrics `NAME`, such as `all_p99`",
Required: true,
},
+ cli.StringFlag{
+ Name: "id",
+ Usage: "`ID`, the related id if the metrics
requires one",
+ Required: false,
+ },
},
),
Before: interceptor.BeforeChain([]cli.BeforeFunc{
@@ -50,8 +55,15 @@ var Command = cli.Command{
step := ctx.Generic("step")
metricsName := ctx.String("name")
+ var id *string = nil
+
+ if idString := ctx.String("id"); idString != "" {
+ id = &idString
+ }
+
metricsValues := client.LinearIntValues(ctx,
schema.MetricCondition{
Name: metricsName,
+ ID: id,
}, schema.Duration{
Start: start,
End: end,
diff --git a/commands/metrics/linear-metrics.go
b/commands/metrics/single/single-metrics.go
similarity index 76%
rename from commands/metrics/linear-metrics.go
rename to commands/metrics/single/single-metrics.go
index e3148fe..ded58ac 100644
--- a/commands/metrics/linear-metrics.go
+++ b/commands/metrics/single/single-metrics.go
@@ -15,9 +15,11 @@
// specific language governing permissions and limitations
// under the License.
-package metrics
+package single
import (
+ "strings"
+
"github.com/urfave/cli"
"github.com/apache/skywalking-cli/commands/flags"
@@ -29,16 +31,21 @@ import (
)
var Command = cli.Command{
- Name: "linear-metrics",
- Usage: "Query linear metrics defined in backend OAL",
+ Name: "single-metrics",
+ Usage: "Query single 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`, 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,
+ },
},
),
Before: interceptor.BeforeChain([]cli.BeforeFunc{
@@ -49,9 +56,17 @@ var Command = cli.Command{
start := ctx.String("start")
step := ctx.Generic("step")
metricsName := ctx.String("name")
+ idsString := ctx.StringSlice("ids")
+
+ var ids []string
+
+ for _, id := range idsString {
+ ids = append(ids, strings.Split(id, ",")...)
+ }
- metricsValues := client.LinearIntValues(ctx,
schema.MetricCondition{
+ metricsValues := client.IntValues(ctx,
schema.BatchMetricConditions{
Name: metricsName,
+ Ids: ids,
}, schema.Duration{
Start: start,
End: end,
diff --git a/display/table/table.go b/display/table/table.go
index d79f917..ce2a5ea 100644
--- a/display/table/table.go
+++ b/display/table/table.go
@@ -21,28 +21,32 @@ import (
"encoding/json"
"os"
+ "github.com/apache/skywalking-cli/logger"
+
"github.com/olekukonko/tablewriter"
)
func Display(object interface{}) error {
- var objMaps []map[string]string
+ var stringMapArrays []map[string]string
bytes, _ := json.Marshal(object)
- _ = json.Unmarshal(bytes, &objMaps)
+ _ = json.Unmarshal(bytes, &stringMapArrays)
- if len(objMaps) < 1 {
+ if len(stringMapArrays) < 1 {
return nil
}
var header []string
- for k := range objMaps[0] {
+ for k := range stringMapArrays[0] {
header = append(header, k)
}
+ logger.Log.Debugln("stringMapArrays = ", stringMapArrays, " Headers =
", header)
+
var data [][]string
- for _, objMap := range objMaps {
+ for _, objMap := range stringMapArrays {
var datum []string
for _, key := range header {
datum = append(datum, objMap[key])
diff --git a/go.sum b/go.sum
index 0203faf..3d6e7a9 100644
--- a/go.sum
+++ b/go.sum
@@ -3,6 +3,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod
h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d
h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod
h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.1/go.mod
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1
h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod
h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/lytics/logrus v0.0.0-20170528191427-4389a17ed024
h1:QaKVrqyQRNPbdBNCpiU0Ei3iDQko3qoiUUXMiTWhzZM=
github.com/lytics/logrus v0.0.0-20170528191427-4389a17ed024/go.mod
h1:SkQviJ2s7rFyzyuxdVp6osZceHOabU91ZhKsEXF0RWg=
diff --git a/graphql/client/client.go b/graphql/client/client.go
index 1f87a55..d33df92 100644
--- a/graphql/client/client.go
+++ b/graphql/client/client.go
@@ -60,6 +60,38 @@ func Services(cliCtx *cli.Context, duration schema.Duration)
[]schema.Service {
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)
+
+ executeQuery(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)
+
+ executeQuery(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(`
@@ -122,6 +154,24 @@ func LinearIntValues(ctx *cli.Context, condition
schema.MetricCondition, duratio
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)
+
+ executeQuery(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]
diff --git a/scripts/build b/scripts/build
deleted file mode 100755
index 7a20563..0000000
--- a/scripts/build
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/usr/bin/env bash
-#
-# Licensed to the 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.
-# The 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.
-#
-#
-
-cli_build() {
- out="bin"
- CGO_ENABLED=0 go build $GO_BUILD_FLAGS \
- -o "${out}/swctl" swctl/* || return
-}
-
-if echo "$0" | grep "build$" > /dev/null; then
- cli_build
-fi
\ No newline at end of file
diff --git a/swctl/main.go b/swctl/main.go
index f260fc2..20efced 100644
--- a/swctl/main.go
+++ b/swctl/main.go
@@ -21,7 +21,9 @@ import (
"io/ioutil"
"os"
- "github.com/apache/skywalking-cli/commands/metrics"
+ "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/instance"
@@ -73,7 +75,9 @@ func main() {
app.Commands = []cli.Command{
service.Command,
instance.Command,
- metrics.Command,
+ linearMetrics.Command,
+ singleMetrics.Command,
+ endpoint.Command,
}
app.Before = interceptor.BeforeChain([]cli.BeforeFunc{