From 045abf77479219bdbfccb13de1981d57defaa578 Mon Sep 17 00:00:00 2001 From: zhang-wei Date: Sun, 24 Nov 2019 19:51:03 +0800 Subject: [PATCH] [Feature] Support instance search command (#15) --- README.md | 12 +++++++ commands/flags/instance.go | 4 +-- commands/flags/search.go | 28 +++++++++++++++ commands/instance/instance.go | 22 ++++++++++++ commands/instance/list.go | 18 ++-------- commands/instance/search.go | 65 +++++++++++++++++++++++++++++++++++ display/json/json_test.go | 42 ++++++++++++++++++++++ display/table/table.go | 4 +++ display/table/table_test.go | 42 ++++++++++++++++++++++ display/yaml/yaml_test.go | 42 ++++++++++++++++++++++ 10 files changed, 261 insertions(+), 18 deletions(-) create mode 100644 commands/flags/search.go create mode 100644 commands/instance/search.go create mode 100644 display/json/json_test.go create mode 100644 display/table/table_test.go create mode 100644 display/yaml/yaml_test.go diff --git a/README.md b/README.md index d8f3678..a6529b4 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,7 @@ This section covers all the available commands in SkyWalking CLI and their usage - [`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` is the top-level command, which has some options that will take effects globally. @@ -102,6 +103,17 @@ and it also has some options and third-level commands. | `--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=] [--service-id=] [--service-name=] [--start=] [--end=]` +`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 | | +| `--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 diff --git a/commands/flags/instance.go b/commands/flags/instance.go index 39137dd..28cac45 100644 --- a/commands/flags/instance.go +++ b/commands/flags/instance.go @@ -19,7 +19,7 @@ package flags import "github.com/urfave/cli" -var InstanceServiceIDFlags = append(DurationFlags, +var InstanceServiceIDFlags = []cli.Flag{ cli.StringFlag{ Name: "service-id", Usage: "query service `ID` (priority over \"--service-name\")", @@ -28,4 +28,4 @@ var InstanceServiceIDFlags = append(DurationFlags, Name: "service-name", Usage: "query service `Name`", }, -) +} diff --git a/commands/flags/search.go b/commands/flags/search.go new file mode 100644 index 0000000..ef48585 --- /dev/null +++ b/commands/flags/search.go @@ -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. + +package flags + +import "github.com/urfave/cli" + +var SearchRegexFlags = []cli.Flag{ + cli.StringFlag{ + Name: "regex", + Required: true, + Usage: "search `Regex`", + }, +} diff --git a/commands/instance/instance.go b/commands/instance/instance.go index fa479ca..da83c80 100644 --- a/commands/instance/instance.go +++ b/commands/instance/instance.go @@ -19,6 +19,9 @@ package instance import ( "github.com/urfave/cli" + + "github.com/apache/skywalking-cli/graphql/client" + "github.com/apache/skywalking-cli/logger" ) var Command = cli.Command{ @@ -27,5 +30,24 @@ var Command = cli.Command{ Usage: "Instance related sub-command", Subcommands: cli.Commands{ ListCommand, + SearchCommand, }, } + +func verifyAndSwitchServiceParameter(ctx *cli.Context) string { + 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 + } + return serviceID +} diff --git a/commands/instance/list.go b/commands/instance/list.go index 04a230e..9f84be7 100644 --- a/commands/instance/list.go +++ b/commands/instance/list.go @@ -26,32 +26,18 @@ import ( "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" ) var ListCommand = cli.Command{ Name: "list", ShortName: "ls", Usage: "List all available instance by given --service-id or --service-name parameter", - Flags: flags.InstanceServiceIDFlags, + Flags: append(flags.DurationFlags, 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 - } + serviceID := verifyAndSwitchServiceParameter(ctx) end := ctx.String("end") start := ctx.String("start") diff --git a/commands/instance/search.go b/commands/instance/search.go new file mode 100644 index 0000000..856273f --- /dev/null +++ b/commands/instance/search.go @@ -0,0 +1,65 @@ +// 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 instance + +import ( + "regexp" + + "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 SearchCommand = cli.Command{ + Name: "search", + Usage: "Filter the instance from the existing service instance list", + Flags: append(flags.DurationFlags, append(flags.SearchRegexFlags, flags.InstanceServiceIDFlags...)...), + Before: interceptor.BeforeChain([]cli.BeforeFunc{ + interceptor.DurationInterceptor, + }), + Action: func(ctx *cli.Context) error { + serviceID := verifyAndSwitchServiceParameter(ctx) + + end := ctx.String("end") + start := ctx.String("start") + step := ctx.Generic("step") + + regex := ctx.String("regex") + + instances := client.Instances(ctx, serviceID, schema.Duration{ + Start: start, + End: end, + Step: step.(*model.StepEnumValue).Selected, + }) + + var result []schema.ServiceInstance + if len(instances) > 0 { + for _, instance := range instances { + if ok, _ := regexp.Match(regex, []byte(instance.Name)); ok { + result = append(result, instance) + } + } + } + return display.Display(ctx, result) + }, +} diff --git a/display/json/json_test.go b/display/json/json_test.go new file mode 100644 index 0000000..8e30107 --- /dev/null +++ b/display/json/json_test.go @@ -0,0 +1,42 @@ +// 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 json + +import ( + "testing" + + "github.com/apache/skywalking-cli/graphql/schema" +) + +func TestJsonDisplay(t *testing.T) { + var result []schema.Service + display(t, result) + result = make([]schema.Service, 0) + display(t, result) + result = append(result, schema.Service{ + ID: "1", + Name: "json", + }) + display(t, result) +} + +func display(t *testing.T, result []schema.Service) { + if err := Display(result); err != nil { + t.Error(err) + } +} diff --git a/display/table/table.go b/display/table/table.go index 422bd1c..d79f917 100644 --- a/display/table/table.go +++ b/display/table/table.go @@ -30,6 +30,10 @@ func Display(object interface{}) error { bytes, _ := json.Marshal(object) _ = json.Unmarshal(bytes, &objMaps) + if len(objMaps) < 1 { + return nil + } + var header []string for k := range objMaps[0] { diff --git a/display/table/table_test.go b/display/table/table_test.go new file mode 100644 index 0000000..fd24460 --- /dev/null +++ b/display/table/table_test.go @@ -0,0 +1,42 @@ +// 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 table + +import ( + "testing" + + "github.com/apache/skywalking-cli/graphql/schema" +) + +func TestTableDisplay(t *testing.T) { + var result []schema.Service + display(t, result) + result = make([]schema.Service, 0) + display(t, result) + result = append(result, schema.Service{ + ID: "1", + Name: "table", + }) + display(t, result) +} + +func display(t *testing.T, result []schema.Service) { + if err := Display(result); err != nil { + t.Error(err) + } +} diff --git a/display/yaml/yaml_test.go b/display/yaml/yaml_test.go new file mode 100644 index 0000000..81a772b --- /dev/null +++ b/display/yaml/yaml_test.go @@ -0,0 +1,42 @@ +// 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 yaml + +import ( + "testing" + + "github.com/apache/skywalking-cli/graphql/schema" +) + +func TestYamlDisplay(t *testing.T) { + var result []schema.Service + display(t, result) + result = make([]schema.Service, 0) + display(t, result) + result = append(result, schema.Service{ + ID: "1", + Name: "yaml", + }) + display(t, result) +} + +func display(t *testing.T, result []schema.Service) { + if err := Display(result); err != nil { + t.Error(err) + } +} -- GitLab