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/29 10:50:47 UTC
[skywalking-cli] branch master updated: Add command `trace` (#39)
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 f2712a7 Add command `trace` (#39)
f2712a7 is described below
commit f2712a7b90433f2fd80f73a7bcc300ffbf11c0a3
Author: kezhenxu94 <ke...@apache.org>
AuthorDate: Sun Mar 29 18:50:40 2020 +0800
Add command `trace` (#39)
### Motivation
Add command `trace` to query trace by trace ID and visualize the traces
### Modification
- Add command `trace` to query and visualize traces.
- Move `main.go` to `cmd`, as per the recommendation of GO CLI package structure.
- Move GraphQL query to individual `*.graphql` file, for more friendly development, with IDE plugin.
### Result
- Traces can be queried and visualized by `swctl trace <trace id>`
- GraphQL queries can be debugged in IDE, with some plugins
---
.github/workflows/go.yml | 6 +
.gitignore | 3 +
.graphqlconfig | 11 +
Makefile | 24 ++-
README.md | 40 ++++
assets/assets.go | 33 +++
.../graphqls/aggregation/AllEndpointTopN.graphql | 27 +++
.../aggregation/AllServiceInstanceTopN.graphql | 27 +++
assets/graphqls/aggregation/EndpointTopN.graphql | 28 +++
.../aggregation/ServiceInstanceTopN.graphql | 28 +++
assets/graphqls/aggregation/ServiceTopN.graphql | 27 +++
assets/graphqls/metadata/AllServices.graphql | 22 ++
assets/graphqls/metadata/Instances.graphql | 30 +++
assets/graphqls/metadata/SearchEndpoints.graphql | 22 ++
assets/graphqls/metadata/SearchService.graphql | 22 ++
assets/graphqls/metadata/ServerTimeInfo.graphql | 22 ++
assets/graphqls/metrics/IntValues.graphql | 22 ++
assets/graphqls/metrics/LinearIntValues.graphql | 22 ++
.../metrics/MultipleLinearIntValues.graphql | 22 ++
assets/graphqls/metrics/Thermodynamic.graphql | 22 ++
assets/graphqls/trace/Trace.graphql | 50 +++++
{swctl => cmd}/main.go | 3 +
commands/trace/list.go | 29 +++
display/graph/graph.go => commands/trace/trace.go | 48 ++---
display/graph/graph.go | 37 +++-
display/graph/tree/adapter.go | 128 ++++++++++++
display/graph/tree/tree.go | 224 +++++++++++++++++++++
dist/LICENSE | 1 +
go.mod | 1 +
go.sum | 142 +++++++++++++
graphql/aggregation/aggregation.go | 69 +------
graphql/metadata/metadata.go | 83 ++------
graphql/metrics/metrics.go | 54 ++---
display/graph/graph.go => graphql/trace/trace.go | 35 +---
util/lang.go | 26 +++
35 files changed, 1161 insertions(+), 229 deletions(-)
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index 936d076..d343adf 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -35,6 +35,12 @@ jobs:
go-version: 1.13
id: go
+ - name: Set up Packr
+ run: go get -u github.com/gobuffalo/packr/v2/...
+
+ - name: Set up GQLGen
+ run: go get -u github.com/99designs/gqlgen
+
- name: Check out code into the Go module directory
uses: actions/checkout@v2
diff --git a/.gitignore b/.gitignore
index e6e7bf9..0e27e55 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,6 @@
bin
coverage.txt
graphql/schema/schema.go
+.DS_Store
+*-packr.go
+packrd
diff --git a/.graphqlconfig b/.graphqlconfig
new file mode 100644
index 0000000..0f3b668
--- /dev/null
+++ b/.graphqlconfig
@@ -0,0 +1,11 @@
+{
+ "name": "SkyWalking GraphQL Schema",
+ "extensions": {
+ "endpoints": {
+ "SkyWalking GraphQL Endpoint": {
+ "url": "http://127.0.0.1:8080/graphql",
+ "introspect": false
+ }
+ }
+ }
+}
diff --git a/Makefile b/Makefile
index 885df84..f932f3a 100644
--- a/Makefile
+++ b/Makefile
@@ -28,12 +28,13 @@ 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_PACKR = $(GO_PATH)/bin/packr2
GO_BUILD_FLAGS = -v
GO_BUILD_LDFLAGS = -X main.version=$(VERSION)
+GQL_GEN = $(GO_PATH)/bin/gqlgen
PLATFORMS := windows linux darwin
os = $(word 1, $@)
@@ -41,20 +42,21 @@ ARCH = amd64
SHELL = /bin/bash
-all: clean deps codegen lint test license build
+all: clean license deps codegen lint test build
deps:
$(GO_GET) -v -t -d ./...
-codegen:
+codegen: clean
echo 'scalar Long' > query-protocol/schema.graphqls
- $(GO) run github.com/99designs/gqlgen generate
+ $(GQL_GEN) generate
-rm -rf generated.go
+ cd assets && GO111MODULE=on $(GO_PACKR) -v && cd ..
.PHONY: $(PLATFORMS)
$(PLATFORMS):
mkdir -p $(OUT_DIR)
- GOOS=$(os) GOARCH=$(ARCH) $(GO_BUILD) $(GO_BUILD_FLAGS) -ldflags "$(GO_BUILD_LDFLAGS)" -o $(OUT_DIR)/$(BINARY)-$(VERSION)-$(os)-$(ARCH) swctl/main.go
+ GOOS=$(os) GOARCH=$(ARCH) $(GO_BUILD) $(GO_BUILD_FLAGS) -ldflags "$(GO_BUILD_LDFLAGS)" -o $(OUT_DIR)/$(BINARY)-$(VERSION)-$(os)-$(ARCH) cmd/main.go
.PHONY: lint
lint: codegen
@@ -71,7 +73,7 @@ build: deps windows linux darwin
.PHONY: license
license: clean
$(GO_LICENSER) -version || GO111MODULE=off $(GO_GET) -u github.com/elastic/go-licenser
- $(GO_LICENSER) -exclude graphql/schema/ -d -licensor='Apache Software Foundation (ASF)' .
+ $(GO_LICENSER) -d -licensor='Apache Software Foundation (ASF)' .
.PHONY: verify
verify: clean lint test license
@@ -86,15 +88,16 @@ coverage: test
bash <(curl -s https://codecov.io/bash) -t a5af28a3-92a2-4b35-9a77-54ad99b1ae00
.PHONY: clean
-clean: codegen
- $(GO_CLEAN) ./...
+clean:
-rm -rf bin
-rm -rf coverage.txt
+ -rm -rf query-protocol/schema.graphqls
+ -rm -rf graphql/schema/schema.go
-rm -rf *.tgz
-rm -rf *.tgz
-rm -rf *.asc
-rm -rf *.sha512
- -rm -rf query-protocol/schema.graphqls
+ cd assets && $(GO_PACKR) clean
release-src: clean
-tar -zcvf $(RELEASE_SRC).tgz \
@@ -105,6 +108,9 @@ release-src: clean
--exclude .github \
--exclude $(RELEASE_SRC).tgz \
--exclude graphql/schema/schema.go \
+ --exclude query-protocol/schema.graphqls \
+ --exclude assets/packrd \
+ --exclude assets/*-packr.go \
.
release-bin: build
diff --git a/README.md b/README.md
index f5e4268..52951a9 100644
--- a/README.md
+++ b/README.md
@@ -231,6 +231,36 @@ Ascii Graph, like coloring in terminal, so please use `json` or `yaml` instead.
</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 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) |
+
+</details>
+
+### `trace`
+
+<details>
+
+<summary>trace [trace id]</summary>
+
+`trace` displays the spans of a given trace.
+
+| argument | description | default |
+| :--- | :--- | :--- |
+| `trace id` | the trace id whose spans are to displayed | |
+
+</details>
+
# Use Cases
<details>
@@ -477,6 +507,16 @@ $ ./bin/swctl --display=graph metrics thermodynamic --name all_heatmap
<details>
+<summary>Display the spans of a trace</summary>
+
+```shell
+$ ./bin/swctl --display graph trace 1585375544413.464998031.46647
+```
+
+</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/assets/assets.go b/assets/assets.go
new file mode 100644
index 0000000..d5964f9
--- /dev/null
+++ b/assets/assets.go
@@ -0,0 +1,33 @@
+// 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 assets
+
+import (
+ "github.com/gobuffalo/packr/v2"
+
+ "github.com/apache/skywalking-cli/logger"
+)
+
+// Read reads all content from a file under assets, which is packed in to the binary
+func Read(filename string) string {
+ content, err := packr.New("assets", ".").FindString(filename)
+ if err != nil {
+ logger.Log.Fatalln("failed to read asset: ", filename, err)
+ }
+ return content
+}
diff --git a/assets/graphqls/aggregation/AllEndpointTopN.graphql b/assets/graphqls/aggregation/AllEndpointTopN.graphql
new file mode 100644
index 0000000..a054b10
--- /dev/null
+++ b/assets/graphqls/aggregation/AllEndpointTopN.graphql
@@ -0,0 +1,27 @@
+# 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
new file mode 100644
index 0000000..0268c60
--- /dev/null
+++ b/assets/graphqls/aggregation/AllServiceInstanceTopN.graphql
@@ -0,0 +1,27 @@
+# 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
new file mode 100644
index 0000000..b6e05f6
--- /dev/null
+++ b/assets/graphqls/aggregation/EndpointTopN.graphql
@@ -0,0 +1,28 @@
+# 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
new file mode 100644
index 0000000..f643170
--- /dev/null
+++ b/assets/graphqls/aggregation/ServiceInstanceTopN.graphql
@@ -0,0 +1,28 @@
+# 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
new file mode 100644
index 0000000..754e827
--- /dev/null
+++ b/assets/graphqls/aggregation/ServiceTopN.graphql
@@ -0,0 +1,27 @@
+# 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/metadata/AllServices.graphql b/assets/graphqls/metadata/AllServices.graphql
new file mode 100644
index 0000000..d3a3f86
--- /dev/null
+++ b/assets/graphqls/metadata/AllServices.graphql
@@ -0,0 +1,22 @@
+# 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 ($duration: Duration!) {
+ result: getAllServices(duration: $duration) {
+ id name
+ }
+}
diff --git a/assets/graphqls/metadata/Instances.graphql b/assets/graphqls/metadata/Instances.graphql
new file mode 100644
index 0000000..4bb4cbc
--- /dev/null
+++ b/assets/graphqls/metadata/Instances.graphql
@@ -0,0 +1,30 @@
+# 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!, $duration: Duration!) {
+ result: getServiceInstances(duration: $duration, serviceId: $serviceId) {
+ id
+ name
+ language
+ instanceUUID
+ attributes {
+ name
+ value
+ }
+ }
+}
diff --git a/assets/graphqls/metadata/SearchEndpoints.graphql b/assets/graphqls/metadata/SearchEndpoints.graphql
new file mode 100644
index 0000000..2c21f47
--- /dev/null
+++ b/assets/graphqls/metadata/SearchEndpoints.graphql
@@ -0,0 +1,22 @@
+# 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 ($keyword: String!, $serviceId: ID!, $limit: Int!) {
+ result: searchEndpoint(keyword: $keyword, serviceId: $serviceId, limit: $limit) {
+ id name
+ }
+}
diff --git a/assets/graphqls/metadata/SearchService.graphql b/assets/graphqls/metadata/SearchService.graphql
new file mode 100644
index 0000000..525446e
--- /dev/null
+++ b/assets/graphqls/metadata/SearchService.graphql
@@ -0,0 +1,22 @@
+# 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 searchService($serviceCode: String!) {
+ result: searchService(serviceCode: $serviceCode) {
+ id name
+ }
+}
diff --git a/assets/graphqls/metadata/ServerTimeInfo.graphql b/assets/graphqls/metadata/ServerTimeInfo.graphql
new file mode 100644
index 0000000..d00d8a9
--- /dev/null
+++ b/assets/graphqls/metadata/ServerTimeInfo.graphql
@@ -0,0 +1,22 @@
+# 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 {
+ result: getTimeInfo {
+ timezone, currentTimestamp
+ }
+}
diff --git a/assets/graphqls/metrics/IntValues.graphql b/assets/graphqls/metrics/IntValues.graphql
new file mode 100644
index 0000000..1138172
--- /dev/null
+++ b/assets/graphqls/metrics/IntValues.graphql
@@ -0,0 +1,22 @@
+# 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: BatchMetricConditions!, $duration: Duration!) {
+ result: getValues(metric: $metric, duration: $duration) {
+ values { id value }
+ }
+}
diff --git a/assets/graphqls/metrics/LinearIntValues.graphql b/assets/graphqls/metrics/LinearIntValues.graphql
new file mode 100644
index 0000000..6249db2
--- /dev/null
+++ b/assets/graphqls/metrics/LinearIntValues.graphql
@@ -0,0 +1,22 @@
+# 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/MultipleLinearIntValues.graphql b/assets/graphqls/metrics/MultipleLinearIntValues.graphql
new file mode 100644
index 0000000..2450068
--- /dev/null
+++ b/assets/graphqls/metrics/MultipleLinearIntValues.graphql
@@ -0,0 +1,22 @@
+# 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!, $numOfLinear: Int!, $duration: Duration!) {
+ result: getMultipleLinearIntValues(metric: $metric, numOfLinear: $numOfLinear, duration: $duration) {
+ values { value }
+ }
+}
diff --git a/assets/graphqls/metrics/Thermodynamic.graphql b/assets/graphqls/metrics/Thermodynamic.graphql
new file mode 100644
index 0000000..9ff50bd
--- /dev/null
+++ b/assets/graphqls/metrics/Thermodynamic.graphql
@@ -0,0 +1,22 @@
+# 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: getThermodynamic(metric: $metric, duration: $duration) {
+ nodes axisYStep
+ }
+}
diff --git a/assets/graphqls/trace/Trace.graphql b/assets/graphqls/trace/Trace.graphql
new file mode 100644
index 0000000..233fc9f
--- /dev/null
+++ b/assets/graphqls/trace/Trace.graphql
@@ -0,0 +1,50 @@
+# 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 ($traceId: ID!) {
+ result: queryTrace(traceId: $traceId) {
+ spans {
+ traceId
+ segmentId
+ spanId
+ parentSpanId
+ refs {
+ traceId
+ parentSegmentId
+ parentSpanId
+ type
+ }
+ serviceCode
+ startTime
+ endTime
+ endpointName
+ type
+ peer
+ component
+ isError
+ layer
+ tags {
+ key value
+ }
+ logs {
+ time data {
+ key value
+ }
+ }
+ }
+ }
+}
diff --git a/swctl/main.go b/cmd/main.go
similarity index 98%
rename from swctl/main.go
rename to cmd/main.go
index 6c39a23..6577b67 100644
--- a/swctl/main.go
+++ b/cmd/main.go
@@ -21,6 +21,8 @@ import (
"io/ioutil"
"os"
+ "github.com/apache/skywalking-cli/commands/trace"
+
"github.com/apache/skywalking-cli/commands/metrics"
"github.com/apache/skywalking-cli/commands/endpoint"
@@ -84,6 +86,7 @@ func main() {
instance.Command,
service.Command,
metrics.Command,
+ trace.Command,
}
app.Before = interceptor.BeforeChain([]cli.BeforeFunc{
diff --git a/commands/trace/list.go b/commands/trace/list.go
new file mode 100644
index 0000000..f23845e
--- /dev/null
+++ b/commands/trace/list.go
@@ -0,0 +1,29 @@
+// 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 trace
+
+import "github.com/urfave/cli"
+
+var ListCommand = cli.Command{
+ Name: "list",
+ ShortName: "ls",
+ Usage: "query traces",
+ Action: func(ctx *cli.Context) error {
+ return nil
+ },
+}
diff --git a/display/graph/graph.go b/commands/trace/trace.go
similarity index 50%
copy from display/graph/graph.go
copy to commands/trace/trace.go
index e8fc072..a6dd408 100644
--- a/display/graph/graph.go
+++ b/commands/trace/trace.go
@@ -15,37 +15,33 @@
// specific language governing permissions and limitations
// under the License.
-package graph
+package trace
import (
"fmt"
- "reflect"
- "github.com/apache/skywalking-cli/display/graph/heatmap"
- "github.com/apache/skywalking-cli/graphql/schema"
+ "github.com/urfave/cli"
- d "github.com/apache/skywalking-cli/display/displayable"
- "github.com/apache/skywalking-cli/display/graph/linear"
+ "github.com/apache/skywalking-cli/display"
+ "github.com/apache/skywalking-cli/display/displayable"
+ "github.com/apache/skywalking-cli/graphql/trace"
)
-func Display(displayable *d.Displayable) error {
- data := displayable.Data
-
- if reflect.TypeOf(data) == reflect.TypeOf(schema.Thermodynamic{}) {
- return heatmap.Display(displayable)
- }
-
- if reflect.TypeOf(data) == reflect.TypeOf(map[string]float64{}) {
- kvs := []map[string]float64{data.(map[string]float64)}
-
- return linear.Display(kvs)
- }
-
- if reflect.TypeOf(data) == reflect.TypeOf([]map[string]float64{}) {
- kvs := data.([]map[string]float64)
-
- return linear.Display(kvs)
- }
-
- return fmt.Errorf("type of %T is not supported to be displayed as ascii graph", reflect.TypeOf(data))
+var Command = cli.Command{
+ Name: "trace",
+ ShortName: "t",
+ Usage: "trace related sub-command",
+ ArgsUsage: "trace id",
+ Action: func(ctx *cli.Context) error {
+ if ctx.NArg() == 0 {
+ return fmt.Errorf("command trace without sub command requires 1 trace id as argument")
+ }
+
+ trace := trace.Trace(ctx, ctx.Args().First())
+
+ return display.Display(ctx, &displayable.Displayable{Data: trace})
+ },
+ Subcommands: cli.Commands{
+ ListCommand,
+ },
}
diff --git a/display/graph/graph.go b/display/graph/graph.go
index e8fc072..f951b51 100644
--- a/display/graph/graph.go
+++ b/display/graph/graph.go
@@ -21,6 +21,8 @@ import (
"fmt"
"reflect"
+ "github.com/apache/skywalking-cli/display/graph/tree"
+
"github.com/apache/skywalking-cli/display/graph/heatmap"
"github.com/apache/skywalking-cli/graphql/schema"
@@ -28,24 +30,37 @@ import (
"github.com/apache/skywalking-cli/display/graph/linear"
)
+type (
+ Thermodynamic = schema.Thermodynamic
+ LinearMetrics = map[string]float64
+ MultiLinearMetrics = []LinearMetrics
+ Trace = schema.Trace
+)
+
+var (
+ ThermodynamicType = reflect.TypeOf(Thermodynamic{})
+ LinearMetricsType = reflect.TypeOf(LinearMetrics{})
+ MultiLinearMetricsType = reflect.TypeOf(MultiLinearMetrics{})
+ TraceType = reflect.TypeOf(Trace{})
+)
+
func Display(displayable *d.Displayable) error {
data := displayable.Data
- if reflect.TypeOf(data) == reflect.TypeOf(schema.Thermodynamic{}) {
+ switch reflect.TypeOf(data) {
+ case ThermodynamicType:
return heatmap.Display(displayable)
- }
- if reflect.TypeOf(data) == reflect.TypeOf(map[string]float64{}) {
- kvs := []map[string]float64{data.(map[string]float64)}
+ case LinearMetricsType:
+ return linear.Display([]LinearMetrics{data.(LinearMetrics)})
- return linear.Display(kvs)
- }
+ case MultiLinearMetricsType:
+ return linear.Display(data.(MultiLinearMetrics))
- if reflect.TypeOf(data) == reflect.TypeOf([]map[string]float64{}) {
- kvs := data.([]map[string]float64)
+ case TraceType:
+ return tree.Display(tree.Adapt(data.(Trace)))
- return linear.Display(kvs)
+ default:
+ return fmt.Errorf("type of %T is not supported to be displayed as ascii graph", reflect.TypeOf(data))
}
-
- return fmt.Errorf("type of %T is not supported to be displayed as ascii graph", reflect.TypeOf(data))
}
diff --git a/display/graph/tree/adapter.go b/display/graph/tree/adapter.go
new file mode 100644
index 0000000..9c33c32
--- /dev/null
+++ b/display/graph/tree/adapter.go
@@ -0,0 +1,128 @@
+// 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 tree
+
+import (
+ "fmt"
+ "strings"
+
+ "github.com/apache/skywalking-cli/graphql/schema"
+ "github.com/apache/skywalking-cli/util"
+)
+
+func Adapt(trace schema.Trace) []*Node {
+ all := make(map[string]*Node)
+
+ for _, span := range trace.Spans {
+ all[id(span)] = node(span)
+ }
+
+ seen := make(map[string]bool)
+
+ var roots []*Node
+
+ for _, span := range trace.Spans {
+ if isRoot(span) {
+ roots = append(roots, all[id(span)])
+ seen[id(span)] = true
+ }
+ }
+
+ for len(seen) < len(trace.Spans) {
+ for _, span := range trace.Spans {
+ if seen[id(span)] {
+ continue
+ }
+
+ if all[pid(span)] != nil {
+ all[pid(span)].Children = append(all[pid(span)].Children, all[id(span)])
+ seen[id(span)] = true
+ }
+
+ for _, ref := range span.Refs {
+ if all[id0(ref)] != nil {
+ all[id0(ref)].Children = append(all[id0(ref)].Children, all[id(span)])
+ seen[id(span)] = true
+ }
+ }
+ }
+ }
+
+ return roots
+}
+
+func isRoot(span *schema.Span) bool {
+ return span.SpanID == 0 && span.ParentSpanID == -1 && len(span.Refs) == 0
+}
+
+func id(span *schema.Span) string {
+ return fmt.Sprintf("%s:%s:%d", span.TraceID, span.SegmentID, span.SpanID)
+}
+
+func pid(span *schema.Span) string {
+ return fmt.Sprintf("%s:%s:%d", span.TraceID, span.SegmentID, span.ParentSpanID)
+}
+
+func id0(ref *schema.Ref) string {
+ return fmt.Sprintf("%s:%s:%d", ref.TraceID, ref.ParentSegmentID, ref.ParentSpanID)
+}
+
+func node(span *schema.Span) *Node {
+ return &Node{
+ Children: []*Node{},
+ Value: util.Stringify{Str: value(span)},
+ Detail: detail(span),
+ }
+}
+
+func value(span *schema.Span) string {
+ if *span.IsError {
+ return fmt.Sprintf(
+ "[|%s| %s [%s/%s]](mod:bold,fg:white,bg:red)",
+ span.Type, *span.EndpointName, *span.Component, *span.Layer,
+ )
+ }
+
+ return fmt.Sprintf("[|%s|](fg:bold,fg:green) %s [[%s/%s]](mod:bold,fg:green)",
+ span.Type, *span.EndpointName, *span.Component, *span.Layer,
+ )
+}
+
+func detail(span *schema.Span) string {
+ var lines []string
+
+ lines = append(lines,
+ fmt.Sprintf("[Endpoint :](mod:bold,fg:red) %s", *span.EndpointName),
+ fmt.Sprintf("[Span Type :](mod:bold,fg:red) %s", span.Type),
+ fmt.Sprintf("[Component :](mod:bold,fg:red) %s", *span.Component),
+ fmt.Sprintf("[Peer :](mod:bold,fg:red) %s", *span.Peer),
+ fmt.Sprintf("[Error :](mod:bold,fg:red) %t", *span.IsError),
+ )
+
+ for _, tag := range span.Tags {
+ lines = append(lines, fmt.Sprintf("[%-12s:](mod:bold,fg:red) %s", tag.Key, *tag.Value))
+ }
+
+ for _, log := range span.Logs {
+ for _, datum := range log.Data {
+ lines = append(lines, fmt.Sprintf("%-12s: %s", datum.Key, *datum.Value))
+ }
+ }
+
+ return strings.Join(lines, "\n")
+}
diff --git a/display/graph/tree/tree.go b/display/graph/tree/tree.go
new file mode 100644
index 0000000..5df89ef
--- /dev/null
+++ b/display/graph/tree/tree.go
@@ -0,0 +1,224 @@
+// 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 tree
+
+import (
+ "fmt"
+
+ ui "github.com/gizak/termui/v3"
+ "github.com/gizak/termui/v3/widgets"
+
+ "github.com/apache/skywalking-cli/logger"
+)
+
+type Node struct {
+ Children []*Node
+ Detail string
+ Value fmt.Stringer
+}
+
+var extra = make(map[*widgets.TreeNode]*Node)
+
+func Display(roots []*Node) error {
+ if err := ui.Init(); err != nil {
+ logger.Log.Fatalf("failed to initialize termui: %v", err)
+ }
+ defer ui.Close()
+
+ nodes := make([]*widgets.TreeNode, len(roots))
+ for i := range nodes {
+ nodes[i] = &widgets.TreeNode{}
+ }
+
+ for i, root := range roots {
+ adapt(root, nodes[i])
+ }
+
+ tree := widgets.NewTree()
+ tree.TextStyle = ui.Style{
+ Fg: ui.ColorWhite,
+ Bg: ui.ColorClear,
+ Modifier: 0,
+ }
+ tree.SelectedRowStyle = ui.Style{
+ Fg: ui.ColorBlack,
+ Bg: ui.ColorWhite,
+ Modifier: ui.ModifierBold,
+ }
+ tree.WrapText = false
+ tree.SetNodes(nodes)
+ tree.Title = " Press ? to show help "
+ tree.TitleStyle.Modifier = ui.ModifierBold
+ tree.TitleStyle.Fg = ui.ColorRed
+
+ x, y := ui.TerminalDimensions()
+
+ tree.SetRect(0, 0, x, y)
+
+ detail := widgets.NewParagraph()
+ detail.Title = " Detail "
+ detail.WrapText = false
+ detail.SetRect(x, 0, x, y)
+
+ help := widgets.NewParagraph()
+ help.WrapText = false
+ help.SetRect(x, 0, x, y)
+ help.Title = " Keymap "
+ help.Text = `
+ [? ](fg:red,mod:bold) Toggle this help
+ [k ](fg:red,mod:bold) Scroll Up
+ [<Up> ](fg:red,mod:bold) Scroll Up
+ [j ](fg:red,mod:bold) Scroll Down
+ [<Down> ](fg:red,mod:bold) Scroll Down
+ [<Ctr-b> ](fg:red,mod:bold) Scroll Page Up
+ [<Ctr-u> ](fg:red,mod:bold) Scroll Half Page Up
+ [<Ctr-f> ](fg:red,mod:bold) Scroll Page Down
+ [<Ctr-d> ](fg:red,mod:bold) Scroll Half Page Down
+ [<Home> ](fg:red,mod:bold) Scroll to Top
+ [gg ](fg:red,mod:bold) Scroll to Top
+ [<Enter> ](fg:red,mod:bold) Show Trace Detail
+ [<Space> ](fg:red,mod:bold) Show Trace Detail
+ [o ](fg:red,mod:bold) Toggle Expand
+ [G ](fg:red,mod:bold) Scroll to Bottom
+ [<End> ](fg:red,mod:bold) Scroll to Bottom
+ [E ](fg:red,mod:bold) Expand All
+ [C ](fg:red,mod:bold) Collapse All
+ [q ](fg:red,mod:bold) Quit
+ [<Ctr-c> ](fg:red,mod:bold) Quit
+ `
+
+ ui.Render(tree, detail, help)
+
+ listenKeyboard(tree, detail, help)
+
+ return nil
+}
+
+func adapt(n1 *Node, n2 *widgets.TreeNode) {
+ if n1 == nil || n2 == nil {
+ return
+ }
+
+ n2.Expanded = true
+ n2.Value = n1.Value
+ n2.Nodes = []*widgets.TreeNode{}
+ extra[n2] = n1
+
+ for _, child := range n1.Children {
+ node := &widgets.TreeNode{}
+ n2.Nodes = append(n2.Nodes, node)
+ adapt(child, node)
+ }
+}
+
+func actions(key string, tree *widgets.Tree) func() {
+ // mostly vim style
+ actions := map[string]func(){
+ "k": tree.ScrollUp,
+ "<Up>": tree.ScrollUp,
+ "j": tree.ScrollDown,
+ "<Down>": tree.ScrollDown,
+ "<C-b>": tree.ScrollPageUp,
+ "<C-u>": tree.ScrollHalfPageUp,
+ "<C-f>": tree.ScrollPageDown,
+ "<C-d>": tree.ScrollHalfPageDown,
+ "<Home>": tree.ScrollTop,
+ "o": tree.ToggleExpand,
+ "G": tree.ScrollBottom,
+ "<End>": tree.ScrollBottom,
+ "E": tree.ExpandAll,
+ "C": tree.CollapseAll,
+ "<Resize>": func() {
+ x, y := ui.TerminalDimensions()
+ tree.SetRect(0, 0, x, y)
+ },
+ }
+
+ return actions[key]
+}
+
+func listenKeyboard(tree *widgets.Tree, detail, help *widgets.Paragraph) {
+ var previousKey string
+ var previousSelected *Node
+
+ visibilities := make(map[interface{}]bool)
+
+ uiEvents := ui.PollEvents()
+
+ for {
+ e := <-uiEvents
+
+ switch e.ID {
+ case "q", "<C-c>":
+ return
+ case "g":
+ if previousKey == "g" {
+ tree.ScrollTop()
+ }
+ case "<Enter>", "<Space>":
+ selected := extra[tree.SelectedNode()]
+ detail.Text = selected.Detail
+
+ selectionChanged := previousSelected != selected
+ visibilities[detail] = selectionChanged || !visibilities[detail]
+
+ previousSelected = selected
+ case "?":
+ visibilities[help] = !visibilities[help]
+ default:
+ if action := actions(e.ID, tree); action != nil {
+ action()
+ }
+ }
+
+ if previousKey == "g" {
+ previousKey = ""
+ } else {
+ previousKey = e.ID
+ }
+
+ redraw(visibilities, tree, detail, help)
+ }
+}
+
+func redraw(shouldShow map[interface{}]bool, tree *widgets.Tree, detail, help *widgets.Paragraph) {
+ x, y := ui.TerminalDimensions()
+
+ shouldDisplaySideBar := shouldShow[detail] || shouldShow[help]
+ if shouldDisplaySideBar {
+ tree.SetRect(0, 0, x*2/3, y)
+ } else {
+ tree.SetRect(0, 0, x, y)
+ }
+
+ if shouldShow[detail] && shouldShow[help] {
+ detail.SetRect(x*2/3, 0, x, y/2)
+ help.SetRect(x*2/3, y/2+1, x, y)
+ } else if shouldShow[help] {
+ detail.SetRect(0, 0, 0, 0)
+ help.SetRect(x*2/3, 0, x, y)
+ } else if shouldShow[detail] {
+ detail.SetRect(x*2/3, 0, x, y)
+ help.SetRect(0, 0, 0, 0)
+ } else {
+ help.SetRect(0, 0, 0, 0)
+ detail.SetRect(0, 0, 0, 0)
+ }
+
+ ui.Render(tree, detail, help)
+}
diff --git a/dist/LICENSE b/dist/LICENSE
index 4dfc4c4..2cbc4ea 100644
--- a/dist/LICENSE
+++ b/dist/LICENSE
@@ -224,6 +224,7 @@ The text of each license is also included at licenses/LICENSE-[project].txt.
nsf (termbox-go) 0.0.0-20190817171036-93860e161317: https://github.com/nsf/termbox-go MIT
gizak (termui) v3: https://github.com/gizak/termui MIT
mattn (go-runewidth) v3: https://github.com/mattn/go-runewidth MIT
+ gobuffalo (packr) v2: https://github.com/gobuffalo/packr MIT
========================================================================
BSD licenses
diff --git a/go.mod b/go.mod
index 7586d33..b979715 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.13
require (
github.com/99designs/gqlgen v0.11.1 // indirect
github.com/gizak/termui/v3 v3.1.0
+ github.com/gobuffalo/packr/v2 v2.8.0
github.com/machinebox/graphql v0.2.2
github.com/mattn/go-runewidth v0.0.4
github.com/mum4k/termdash v0.10.0
diff --git a/go.sum b/go.sum
index 932479d..019c53d 100644
--- a/go.sum
+++ b/go.sum
@@ -1,30 +1,85 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/99designs/gqlgen v0.11.1 h1:QoSL8/AAJ2T3UOeQbdnBR32JcG4pO08+P/g5jdbFkUg=
github.com/99designs/gqlgen v0.11.1/go.mod h1:vjFOyBZ7NwDl+GdSD4PFn7BQn5Fy7ohJwXn7Vk8zz+c=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/agnivade/levenshtein v1.0.1/go.mod h1:CURSv5d9Uaml+FovSIICkLbAUZ9S4RqaHDIsdSBg7lM=
github.com/agnivade/levenshtein v1.0.3 h1:M5ZnqLOoZR8ygVq0FfkXsNOKzMCk0xRiow0R5+5VkQ0=
github.com/agnivade/levenshtein v1.0.3/go.mod h1:4SFRZbbXWLF4MU1T9Qg0pGgH3Pjs+t6ie5efyrwRJXs=
+github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
+github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
+github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
+github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
+github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
+github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
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/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
+github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
+github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dgryski/trifles v0.0.0-20190318185328-a8d75aae118c/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/gizak/termui v3.1.0+incompatible h1:N3CFm+j087lanTxPpHOmQs0uS3s5I9TxoAFy6DqPqv8=
github.com/gizak/termui/v3 v3.1.0 h1:ZZmVDgwHl7gR7elfKf1xc4IudXZ5qqfDh4wExk4Iajc=
github.com/gizak/termui/v3 v3.1.0/go.mod h1:bXQEBkJpzxUAKf0+xq9MSWAvWZlE7c+aidmyFlkYTrY=
github.com/go-chi/chi v3.3.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
+github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
+github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
+github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
+github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/gobuffalo/logger v1.0.3 h1:YaXOTHNPCvkqqA7w05A4v0k2tCdpr+sgFlgINbQ6gqc=
+github.com/gobuffalo/logger v1.0.3/go.mod h1:SoeejUwldiS7ZsyCBphOGURmWdwUFXs0J7TCjEhjKxM=
+github.com/gobuffalo/packd v1.0.0 h1:6ERZvJHfe24rfFmA9OaoKBdC7+c9sydrytMg8SdFGBM=
+github.com/gobuffalo/packd v1.0.0/go.mod h1:6VTc4htmJRFB7u1m/4LeMTWjFoYrUiBkU9Fdec9hrhI=
+github.com/gobuffalo/packr/v2 v2.8.0 h1:IULGd15bQL59ijXLxEvA5wlMxsmx/ZkQv9T282zNVIY=
+github.com/gobuffalo/packr/v2 v2.8.0/go.mod h1:PDk2k3vGevNE3SwVyVRgQCCXETC9SaONCNSXT1Q8M1g=
github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/mux v1.6.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
github.com/gorilla/websocket v1.2.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
+github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
+github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
+github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
+github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/karrick/godirwalk v1.15.3 h1:0a2pXOgtB16CqIqXTiT7+K9L73f74n/aNQUnH6Ortew=
+github.com/karrick/godirwalk v1.15.3/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk=
+github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
+github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
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/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
+github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -33,6 +88,13 @@ github.com/lytics/logrus v0.0.0-20170528191427-4389a17ed024 h1:QaKVrqyQRNPbdBNCp
github.com/lytics/logrus v0.0.0-20170528191427-4389a17ed024/go.mod h1:SkQviJ2s7rFyzyuxdVp6osZceHOabU91ZhKsEXF0RWg=
github.com/machinebox/graphql v0.2.2 h1:dWKpJligYKhYKO5A2gvNhkJdQMNZeChZYyBbrZkBZfo=
github.com/machinebox/graphql v0.2.2/go.mod h1:F+kbVMHuwrQ5tYgU9JXlnskM8nOaFxCAEolaQybkjWA=
+github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
+github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc=
+github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY=
+github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI=
+github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI=
+github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/matryer/moq v0.0.0-20200106131100-75d0ddfc0007/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
@@ -40,23 +102,42 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
+github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 h1:DpOJ2HYzCv8LZP15IdmG+YdwD2luVPHITV96TkirNBM=
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047 h1:zCoDWFD5nrJJVjbXiDZcVhOBSzKn3o9LgRLLMRNuru8=
github.com/mitchellh/mapstructure v0.0.0-20180203102830-a4e142e9c047/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
+github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mum4k/termdash v0.10.0 h1:uqM6ePiMf+smecb1tJJeON36o1hREeCfOmLFG0iz4a0=
github.com/mum4k/termdash v0.10.0/go.mod h1:l3tO+lJi9LZqXRq7cu7h5/8rDIK3AzelSuq2v/KncxI=
+github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
github.com/nsf/termbox-go v0.0.0-20190817171036-93860e161317 h1:hhGN4SFXgXo61Q4Sjj/X9sBjyeSa2kdpaOzCO+8EVQw=
github.com/nsf/termbox-go v0.0.0-20190817171036-93860e161317/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.2 h1:sq53g+DWf0J6/ceFUHpQ0nAEb6WgM++fq16MZ91cS6o=
github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=
github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
+github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
+github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
+github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
+github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
+github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
+github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -65,26 +146,66 @@ github.com/shurcooL/httpfs v0.0.0-20171119174359-809beceb2371/go.mod h1:ZY1cvUeJ
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20180121065927-ffb13db8def0/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
+github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
+github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
+github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
+github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
+github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
+github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
+github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vektah/dataloaden v0.2.1-0.20190515034641-a19b9a6e7c9e/go.mod h1:/HUdMve7rvxZma+2ZELQeNh88+003LL7Pf/CZ089j8U=
github.com/vektah/gqlparser/v2 v2.0.1 h1:xgl5abVnsd4hkN9rk65OJID9bfcLSMuTaTcZj777q1o=
github.com/vektah/gqlparser/v2 v2.0.1/go.mod h1:SyUiHgLATUR8BiYURfTirrTcGpcE+4XkV2se04Px1Ms=
+github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
+github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
+go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
+go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
+go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
+go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c h1:/nJuwDLoL/zrqY6gf57vxC+Pi+pZ8bfhpPkicO5H7W4=
+golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
+golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
+golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
+golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -93,16 +214,37 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190125232054-d66bd3c5d5a6/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190515012406-7d7faa4812bd/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589 h1:rjUrONFu4kLchcZTfp3/96bR8bW8dIa8uz3cR5n0cgM=
golang.org/x/tools v0.0.0-20200114235610-7ae403b6b589/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
+golang.org/x/tools v0.0.0-20200308013534-11ec41452d41 h1:9Di9iYgOt9ThCipBxChBVhgNipDoE5mxO84rQV7D0FE=
+golang.org/x/tools v0.0.0-20200308013534-11ec41452d41/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
+golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
+google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
+gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
+gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
+gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
sourcegraph.com/sourcegraph/appdash v0.0.0-20180110180208-2cc67fd64755/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU=
sourcegraph.com/sourcegraph/appdash-data v0.0.0-20151005221446-73f23eafcf67/go.mod h1:L5q+DGLGOQFpo1snNEkLOJT2d1YTW66rWNzatr3He1k=
diff --git a/graphql/aggregation/aggregation.go b/graphql/aggregation/aggregation.go
index fc11392..6effe5e 100644
--- a/graphql/aggregation/aggregation.go
+++ b/graphql/aggregation/aggregation.go
@@ -21,6 +21,8 @@ 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"
)
@@ -28,18 +30,7 @@ import (
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(`
- query ($name: String!, $topN: Int!, $duration: Duration!, $order: Order!) {
- result: getServiceTopN(
- duration: $duration,
- name: $name,
- topN: $topN,
- order: $order
- ) {
- id name value
- }
- }
- `)
+ request := graphql.NewRequest(assets.Read("graphqls/aggregation/ServiceTopN.graphql"))
request.Var("name", name)
request.Var("topN", topN)
request.Var("duration", duration)
@@ -53,18 +44,7 @@ func ServiceTopN(ctx *cli.Context, name string, topN int, duration schema.Durati
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(`
- query ($name: String!, $topN: Int!, $duration: Duration!, $order: Order!) {
- result: getAllServiceInstanceTopN(
- duration: $duration,
- name: $name,
- topN: $topN,
- order: $order
- ) {
- id name value
- }
- }
- `)
+ request := graphql.NewRequest(assets.Read("graphqls/aggregation/AllServiceInstanceTopN.graphql"))
request.Var("name", name)
request.Var("topN", topN)
request.Var("duration", duration)
@@ -78,19 +58,7 @@ func AllServiceInstanceTopN(ctx *cli.Context, name string, topN int, duration sc
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(`
- 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
- }
- }
- `)
+ request := graphql.NewRequest(assets.Read("graphqls/aggregation/ServiceInstanceTopN.graphql"))
request.Var("serviceId", serviceID)
request.Var("name", name)
request.Var("topN", topN)
@@ -105,18 +73,7 @@ func ServiceInstanceTopN(ctx *cli.Context, serviceID, name string, topN int, dur
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(`
- query ($name: String!, $topN: Int!, $duration: Duration!, $order: Order!) {
- result: getAllEndpointTopN(
- duration: $duration,
- name: $name,
- topN: $topN,
- order: $order
- ) {
- id name value
- }
- }
- `)
+ request := graphql.NewRequest(assets.Read("graphqls/aggregation/AllEndpointTopN.graphql"))
request.Var("name", name)
request.Var("topN", topN)
request.Var("duration", duration)
@@ -130,19 +87,7 @@ func AllEndpointTopN(ctx *cli.Context, name string, topN int, duration schema.Du
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(`
- 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
- }
- }
- `)
+ request := graphql.NewRequest(assets.Read("graphqls/aggregation/EndpointTopN.graphql"))
request.Var("serviceId", serviceID)
request.Var("name", name)
request.Var("topN", topN)
diff --git a/graphql/metadata/metadata.go b/graphql/metadata/metadata.go
index 93b6875..49e88be 100644
--- a/graphql/metadata/metadata.go
+++ b/graphql/metadata/metadata.go
@@ -20,6 +20,8 @@ package metadata
import (
"fmt"
+ "github.com/apache/skywalking-cli/assets"
+
"github.com/machinebox/graphql"
"github.com/urfave/cli"
@@ -29,105 +31,64 @@ import (
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 := graphql.NewRequest(assets.Read("graphqls/metadata/AllServices.graphql"))
request.Var("duration", duration)
client.ExecuteQueryOrFail(cliCtx, request, &response)
- return response["services"]
+ return response["result"]
}
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 := graphql.NewRequest(assets.Read("graphqls/metadata/SearchService.graphql"))
request.Var("serviceCode", serviceCode)
client.ExecuteQueryOrFail(cliCtx, request, &response)
- service = response["service"]
+
+ service = response["result"]
+
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 := graphql.NewRequest(assets.Read("graphqls/metadata/SearchEndpoints.graphql"))
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"]
+ return response["result"]
}
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 := graphql.NewRequest(assets.Read("graphqls/metadata/Instances.graphql"))
request.Var("serviceId", serviceID)
request.Var("duration", duration)
client.ExecuteQueryOrFail(cliCtx, request, &response)
- return response["instances"]
+
+ return response["result"]
}
func ServerTimeInfo(cliCtx *cli.Context) (schema.TimeInfo, error) {
var response map[string]schema.TimeInfo
- request := graphql.NewRequest(`
- query {
- timeInfo: getTimeInfo {
- timezone, currentTimestamp
- }
- }
- `)
+
+ request := graphql.NewRequest(assets.Read("graphqls/metadata/ServerTimeInfo.graphql"))
if err := client.ExecuteQuery(cliCtx, request, &response); err != nil {
return schema.TimeInfo{}, err
}
- return response["timeInfo"], nil
+
+ return response["result"], nil
}
diff --git a/graphql/metrics/metrics.go b/graphql/metrics/metrics.go
index ef71e32..6b12837 100644
--- a/graphql/metrics/metrics.go
+++ b/graphql/metrics/metrics.go
@@ -21,6 +21,8 @@ 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"
@@ -29,72 +31,52 @@ import (
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 := graphql.NewRequest(assets.Read("graphqls/metadata/IntValues.graphql"))
+
request.Var("metric", condition)
request.Var("duration", duration)
client.ExecuteQueryOrFail(ctx, request, &response)
- return response["metrics"]
+ return response["result"]
}
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 := graphql.NewRequest(assets.Read("graphqls/metadata/LinearIntValues.graphql"))
+
request.Var("metric", condition)
request.Var("duration", duration)
client.ExecuteQueryOrFail(ctx, request, &response)
- return response["metrics"]
+ return response["result"]
}
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 }
- }
- }
- `)
+ var response map[string][]schema.IntValues
+
+ request := graphql.NewRequest(assets.Read("graphqls/metadata/MultipleLinearIntValues.graphql"))
+
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"]
+ return response["result"]
}
func Thermodynamic(ctx *cli.Context, condition schema.MetricCondition, duration schema.Duration) schema.Thermodynamic {
- request := graphql.NewRequest(`
- query ($metric: MetricCondition!, $duration: Duration!) {
- metrics: getThermodynamic(metric: $metric, duration: $duration) {
- nodes axisYStep
- }
- }
- `)
+ var response map[string]schema.Thermodynamic
+
+ request := graphql.NewRequest(assets.Read("graphqls/metadata/Thermodynamic.graphql"))
+
request.Var("metric", condition)
request.Var("duration", duration)
- var response map[string]schema.Thermodynamic
-
client.ExecuteQueryOrFail(ctx, request, &response)
- return response["metrics"]
+ return response["result"]
}
diff --git a/display/graph/graph.go b/graphql/trace/trace.go
similarity index 53%
copy from display/graph/graph.go
copy to graphql/trace/trace.go
index e8fc072..b09a56f 100644
--- a/display/graph/graph.go
+++ b/graphql/trace/trace.go
@@ -15,37 +15,24 @@
// specific language governing permissions and limitations
// under the License.
-package graph
+package trace
import (
- "fmt"
- "reflect"
+ "github.com/machinebox/graphql"
+ "github.com/urfave/cli"
- "github.com/apache/skywalking-cli/display/graph/heatmap"
+ "github.com/apache/skywalking-cli/assets"
+ "github.com/apache/skywalking-cli/graphql/client"
"github.com/apache/skywalking-cli/graphql/schema"
-
- d "github.com/apache/skywalking-cli/display/displayable"
- "github.com/apache/skywalking-cli/display/graph/linear"
)
-func Display(displayable *d.Displayable) error {
- data := displayable.Data
-
- if reflect.TypeOf(data) == reflect.TypeOf(schema.Thermodynamic{}) {
- return heatmap.Display(displayable)
- }
-
- if reflect.TypeOf(data) == reflect.TypeOf(map[string]float64{}) {
- kvs := []map[string]float64{data.(map[string]float64)}
-
- return linear.Display(kvs)
- }
+func Trace(ctx *cli.Context, traceID string) schema.Trace {
+ var response map[string]schema.Trace
- if reflect.TypeOf(data) == reflect.TypeOf([]map[string]float64{}) {
- kvs := data.([]map[string]float64)
+ request := graphql.NewRequest(assets.Read("graphqls/trace/Trace.graphql"))
+ request.Var("traceId", traceID)
- return linear.Display(kvs)
- }
+ client.ExecuteQueryOrFail(ctx, request, &response)
- return fmt.Errorf("type of %T is not supported to be displayed as ascii graph", reflect.TypeOf(data))
+ return response["result"]
}
diff --git a/util/lang.go b/util/lang.go
new file mode 100644
index 0000000..4ba5fec
--- /dev/null
+++ b/util/lang.go
@@ -0,0 +1,26 @@
+// 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 util
+
+type Stringify struct {
+ Str string
+}
+
+func (s Stringify) String() string {
+ return s.Str
+}