[Feature] Support instance list command (#10)
* add instance command
* add instance command
* fix license
* fix
* fix analyzers took error
* list command
* list command
* list command
* add instance command
* Add command manual and documentations (#8)
* Add command manual and ˆdocumentation
* Rename GitHub Action and display build status and coverage badge
* Update documentation to add developer guide and polishing
diff --git a/README.md b/README.md
index aacbdf8..d8f3678 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,8 @@
- [`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)
### `swctl` top-level command
`swctl` is the top-level command, which has some options that will take effects globally.
@@ -86,6 +88,20 @@
| `--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.
+
+#### `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.
+
+| option | description | default |
+| :--- | :--- | :--- |
+| `--service-id` | Query service id (priority over --service-name)| |
+| `--service-name` | Query service name | |
+| `--start` | See [Common options](#common-options) | See [Common options](#common-options) |
+| `--end` | See [Common options](#common-options) | See [Common options](#common-options) |
+
# Developer guide
## Compiling and building
@@ -118,4 +134,4 @@
```
# License
-[Apache 2.0 License.](/LICENSE)
+[Apache 2.0 License.](/LICENSE)
\ No newline at end of file
diff --git a/commands/flags/instance.go b/commands/flags/instance.go
new file mode 100644
index 0000000..70839b1
--- /dev/null
+++ b/commands/flags/instance.go
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ *
+ */
+
+package flags
+
+import "github.com/urfave/cli"
+
+var InstanceServiceIdFlags = append(DurationFlags,
+ cli.StringFlag{
+ Name: "service-id",
+ Usage: "query service `ID` (priority over \"--service-name\")",
+ },
+ cli.StringFlag{
+ Name: "service-name",
+ Usage: "query service `Name`",
+ },
+)
diff --git a/commands/instance/instance.go b/commands/instance/instance.go
new file mode 100644
index 0000000..12dae3c
--- /dev/null
+++ b/commands/instance/instance.go
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ *
+ */
+
+package instance
+
+import (
+ "github.com/urfave/cli"
+)
+
+var Command = cli.Command{
+ Name: "instance",
+ ShortName: "i",
+ Usage: "Instance related sub-command",
+ Subcommands: cli.Commands{
+ ListCommand,
+ },
+}
diff --git a/commands/instance/list.go b/commands/instance/list.go
new file mode 100644
index 0000000..7b56c29
--- /dev/null
+++ b/commands/instance/list.go
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ *
+ */
+
+package instance
+
+import (
+ "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"
+ "github.com/apache/skywalking-cli/logger"
+ "github.com/urfave/cli"
+)
+
+var ListCommand = cli.Command{
+ Name: "list",
+ ShortName: "ls",
+ Usage: "List all available instance by given --service-id or --service-name parameter",
+ Flags: flags.InstanceServiceIdFlags,
+ Before: interceptor.BeforeChain([]cli.BeforeFunc{
+ interceptor.DurationInterceptor,
+ }),
+ Action: func(ctx *cli.Context) error {
+ serviceId := ctx.String("service-id")
+ serviceName := ctx.String("service-name")
+
+ if serviceId == "" && serviceName == "" {
+ logger.Log.Fatalf("flags \"service-id, service-name\" must set one")
+ }
+
+ if serviceId == "" && serviceName != "" {
+ service, err := client.SearchService(ctx, serviceName)
+ if err != nil {
+ logger.Log.Fatalln(err)
+ }
+ serviceId = service.ID
+ }
+
+ end := ctx.String("end")
+ start := ctx.String("start")
+ step := ctx.Generic("step")
+
+ instances := client.Instances(ctx, serviceId, schema.Duration{
+ Start: start,
+ End: end,
+ Step: step.(*model.StepEnumValue).Selected,
+ })
+
+ return display.Display(ctx, instances)
+ },
+}
diff --git a/graphql/client/client.go b/graphql/client/client.go
index 2bbb412..d72bc06 100644
--- a/graphql/client/client.go
+++ b/graphql/client/client.go
@@ -20,18 +20,30 @@
import (
"context"
+ "fmt"
"github.com/apache/skywalking-cli/graphql/schema"
"github.com/apache/skywalking-cli/logger"
"github.com/machinebox/graphql"
"github.com/urfave/cli"
)
-func Services(cliCtx *cli.Context, duration schema.Duration) []schema.Service {
- client := graphql.NewClient(cliCtx.GlobalString("base-url"))
+func newClient(cliCtx *cli.Context) (client *graphql.Client) {
+ client = graphql.NewClient(cliCtx.GlobalString("base-url"))
client.Log = func(msg string) {
logger.Log.Debugln(msg)
}
+ return
+}
+func executeQuery(cliCtx *cli.Context, request *graphql.Request, response interface{}) {
+ client := newClient(cliCtx)
+ ctx := context.Background()
+ if err := client.Run(ctx, request, response); err != nil {
+ logger.Log.Fatalln(err)
+ }
+}
+
+func Services(cliCtx *cli.Context, duration schema.Duration) []schema.Service {
var response map[string][]schema.Service
request := graphql.NewRequest(`
query ($duration: Duration!) {
@@ -42,11 +54,48 @@
`)
request.Var("duration", duration)
- ctx := context.Background()
- if err := client.Run(ctx, request, &response); err != nil {
- logger.Log.Fatalln(err)
- panic(err)
- }
-
+ executeQuery(cliCtx, request, &response)
return response["services"]
}
+
+func Instances(cliCtx *cli.Context, serviceId string, duration schema.Duration) []schema.ServiceInstance {
+ var response map[string][]schema.ServiceInstance
+ request := graphql.NewRequest(`
+ query ($serviceId: ID!, $duration: Duration!) {
+ instances: getServiceInstances(duration: $duration, serviceId: $serviceId) {
+ id
+ name
+ language
+ instanceUUID
+ attributes {
+ name
+ value
+ }
+ }
+ }
+ `)
+ request.Var("serviceId", serviceId)
+ request.Var("duration", duration)
+
+ executeQuery(cliCtx, request, &response)
+ return response["instances"]
+}
+
+func SearchService(cliCtx *cli.Context, serviceCode string) (service schema.Service, err error) {
+ var response map[string]schema.Service
+ request := graphql.NewRequest(`
+ query searchService($serviceCode: String!) {
+ service: searchService(serviceCode: $serviceCode) {
+ id name
+ }
+ }
+ `)
+ request.Var("serviceCode", serviceCode)
+
+ executeQuery(cliCtx, request, &response)
+ service = response["service"]
+ if service.ID == "" {
+ return service, fmt.Errorf("no such service [%s]", serviceCode)
+ }
+ return service, nil
+}
diff --git a/swctl/main.go b/swctl/main.go
index 0667211..e0ec990 100644
--- a/swctl/main.go
+++ b/swctl/main.go
@@ -19,6 +19,7 @@
package main
import (
+ "github.com/apache/skywalking-cli/commands/instance"
"github.com/apache/skywalking-cli/commands/interceptor"
"github.com/apache/skywalking-cli/commands/service"
"github.com/apache/skywalking-cli/logger"
@@ -60,12 +61,14 @@
altsrc.NewStringFlag(cli.StringFlag{
Name: "display",
Required: false,
- Usage: "display `style` of the result, supported styles are: json, yaml",
+ Usage: "display `style` of the result, supported styles are: json, yaml, table",
+ Value: "json",
}),
}
app.Commands = []cli.Command{
service.Command,
+ instance.Command,
}
app.Before = interceptor.BeforeChain([]cli.BeforeFunc{