From 6d315d791709cba7d814aca842ad57ba42969303 Mon Sep 17 00:00:00 2001 From: chen zhengwei Date: Fri, 11 Dec 2020 09:48:44 +0800 Subject: [PATCH] Add status command (#2684) * Add status command Signed-off-by: Chen Zhengwei Signed-off-by: chen zhengwei * Use make fmt Signed-off-by: Chen Zhengwei * Add unit test Signed-off-by: Chen Zhengwei Signed-off-by: chen zhengwei * Fix unit test. Signed-off-by: Chen Zhengwei Signed-off-by: chen zhengwei --- cmd/agent/main.go | 2 ++ cmd/all-in-one/main.go | 2 ++ cmd/collector/main.go | 2 ++ cmd/ingester/main.go | 2 ++ cmd/query/main.go | 2 ++ cmd/status/command.go | 70 ++++++++++++++++++++++++++++++++++++ cmd/status/command_test.go | 72 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 152 insertions(+) create mode 100644 cmd/status/command.go create mode 100644 cmd/status/command_test.go diff --git a/cmd/agent/main.go b/cmd/agent/main.go index c01d04d3ea7..dcd296e203c 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -32,6 +32,7 @@ import ( "github.com/jaegertracing/jaeger/cmd/agent/app/reporter/grpc" "github.com/jaegertracing/jaeger/cmd/docs" "github.com/jaegertracing/jaeger/cmd/flags" + "github.com/jaegertracing/jaeger/cmd/status" "github.com/jaegertracing/jaeger/pkg/config" "github.com/jaegertracing/jaeger/pkg/version" "github.com/jaegertracing/jaeger/ports" @@ -95,6 +96,7 @@ func main() { command.AddCommand(version.Command()) command.AddCommand(docs.Command(v)) + command.AddCommand(status.Command(v, ports.AgentAdminHTTP)) config.AddFlags( v, diff --git a/cmd/all-in-one/main.go b/cmd/all-in-one/main.go index bf2611cc328..f2565cb0ed2 100644 --- a/cmd/all-in-one/main.go +++ b/cmd/all-in-one/main.go @@ -41,6 +41,7 @@ import ( "github.com/jaegertracing/jaeger/cmd/flags" queryApp "github.com/jaegertracing/jaeger/cmd/query/app" "github.com/jaegertracing/jaeger/cmd/query/app/querysvc" + "github.com/jaegertracing/jaeger/cmd/status" "github.com/jaegertracing/jaeger/pkg/config" "github.com/jaegertracing/jaeger/pkg/version" ss "github.com/jaegertracing/jaeger/plugin/sampling/strategystore" @@ -182,6 +183,7 @@ by default uses only in-memory database.`, command.AddCommand(version.Command()) command.AddCommand(env.Command()) command.AddCommand(docs.Command(v)) + command.AddCommand(status.Command(v, ports.CollectorAdminHTTP)) config.AddFlags( v, diff --git a/cmd/collector/main.go b/cmd/collector/main.go index 66e19cd4e12..a476ff73d10 100644 --- a/cmd/collector/main.go +++ b/cmd/collector/main.go @@ -33,6 +33,7 @@ import ( "github.com/jaegertracing/jaeger/cmd/docs" "github.com/jaegertracing/jaeger/cmd/env" "github.com/jaegertracing/jaeger/cmd/flags" + "github.com/jaegertracing/jaeger/cmd/status" "github.com/jaegertracing/jaeger/pkg/config" "github.com/jaegertracing/jaeger/pkg/version" ss "github.com/jaegertracing/jaeger/plugin/sampling/strategystore" @@ -122,6 +123,7 @@ func main() { command.AddCommand(version.Command()) command.AddCommand(env.Command()) command.AddCommand(docs.Command(v)) + command.AddCommand(status.Command(v, ports.CollectorAdminHTTP)) config.AddFlags( v, diff --git a/cmd/ingester/main.go b/cmd/ingester/main.go index 683236c7e77..e93f5d566d0 100644 --- a/cmd/ingester/main.go +++ b/cmd/ingester/main.go @@ -31,6 +31,7 @@ import ( "github.com/jaegertracing/jaeger/cmd/flags" "github.com/jaegertracing/jaeger/cmd/ingester/app" "github.com/jaegertracing/jaeger/cmd/ingester/app/builder" + "github.com/jaegertracing/jaeger/cmd/status" "github.com/jaegertracing/jaeger/pkg/config" "github.com/jaegertracing/jaeger/pkg/version" "github.com/jaegertracing/jaeger/plugin/storage" @@ -99,6 +100,7 @@ func main() { command.AddCommand(version.Command()) command.AddCommand(env.Command()) command.AddCommand(docs.Command(v)) + command.AddCommand(status.Command(v, ports.IngesterAdminHTTP)) config.AddFlags( v, diff --git a/cmd/query/main.go b/cmd/query/main.go index a1a23f1bcb9..2f2f00bf457 100644 --- a/cmd/query/main.go +++ b/cmd/query/main.go @@ -34,6 +34,7 @@ import ( "github.com/jaegertracing/jaeger/cmd/flags" "github.com/jaegertracing/jaeger/cmd/query/app" "github.com/jaegertracing/jaeger/cmd/query/app/querysvc" + "github.com/jaegertracing/jaeger/cmd/status" "github.com/jaegertracing/jaeger/pkg/config" "github.com/jaegertracing/jaeger/pkg/version" "github.com/jaegertracing/jaeger/plugin/storage" @@ -134,6 +135,7 @@ func main() { command.AddCommand(version.Command()) command.AddCommand(env.Command()) command.AddCommand(docs.Command(v)) + command.AddCommand(status.Command(v, ports.QueryAdminHTTP)) config.AddFlags( v, diff --git a/cmd/status/command.go b/cmd/status/command.go new file mode 100644 index 00000000000..0be39d77232 --- /dev/null +++ b/cmd/status/command.go @@ -0,0 +1,70 @@ +// Copyright (c) 2020 The Jaeger Authors. +// +// Licensed 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 status + +import ( + "flag" + "fmt" + "io/ioutil" + "net/http" + "strings" + + "github.com/spf13/cobra" + "github.com/spf13/viper" + + "github.com/jaegertracing/jaeger/ports" +) + +const statusHTTPHostPort = "status.http.host-port" + +// Command for check component status. +func Command(v *viper.Viper, adminPort int) *cobra.Command { + c := &cobra.Command{ + Use: "status", + Short: "Print the status.", + Long: `Print Jaeger component status information, exit non-zero on any error.`, + RunE: func(cmd *cobra.Command, args []string) error { + url := convert(v.GetString(statusHTTPHostPort)) + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + body, _ := ioutil.ReadAll(resp.Body) + fmt.Println(string(body)) + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("abnormal value of http status code: %v", resp.StatusCode) + } + return nil + }, + } + c.Flags().AddGoFlagSet(flags(&flag.FlagSet{}, adminPort)) + v.BindPFlags(c.Flags()) + return c +} + +func flags(flagSet *flag.FlagSet, adminPort int) *flag.FlagSet { + adminPortStr := ports.PortToHostPort(adminPort) + flagSet.String(statusHTTPHostPort, adminPortStr, fmt.Sprintf( + "The host:port (e.g. 127.0.0.1%s or %s) for the health check", adminPortStr, adminPortStr)) + return flagSet +} + +func convert(httpHostPort string) string { + if strings.HasPrefix(httpHostPort, ":") { + return fmt.Sprintf("http://127.0.0.1%s", httpHostPort) + } + return fmt.Sprintf("http://%s", httpHostPort) +} diff --git a/cmd/status/command_test.go b/cmd/status/command_test.go new file mode 100644 index 00000000000..47af9ec2bfc --- /dev/null +++ b/cmd/status/command_test.go @@ -0,0 +1,72 @@ +// Copyright (c) 2020 The Jaeger Authors. +// +// Licensed 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 status + +import ( + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/spf13/viper" + "github.com/stretchr/testify/assert" +) + +func readyHandler(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + w.Write([]byte("{\"status\":\"Server available\"}")) +} + +func unavailableHandler(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusServiceUnavailable) + w.Write([]byte("{\"status\":\"Server not available\"}")) +} + +func TestReady(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(readyHandler)) + defer ts.Close() + v := viper.New() + cmd := Command(v, 80) + cmd.ParseFlags([]string{"--status.http.host-port=" + strings.TrimPrefix(ts.URL, "http://")}) + err := cmd.Execute() + assert.NoError(t, err) +} + +func TestOnlyPortConfig(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(readyHandler)) + defer ts.Close() + v := viper.New() + cmd := Command(v, 80) + cmd.ParseFlags([]string{"--status.http.host-port=:" + strings.Split(ts.URL, ":")[len(strings.Split(ts.URL, ":"))-1]}) + err := cmd.Execute() + assert.NoError(t, err) +} + +func TestUnready(t *testing.T) { + ts := httptest.NewServer(http.HandlerFunc(unavailableHandler)) + defer ts.Close() + v := viper.New() + cmd := Command(v, 80) + cmd.ParseFlags([]string{"--status.http.host-port=" + strings.TrimPrefix(ts.URL, "http://")}) + err := cmd.Execute() + assert.Error(t, err) +} + +func TestNoService(t *testing.T) { + v := viper.New() + cmd := Command(v, 12345) + err := cmd.Execute() + assert.Error(t, err) +}