From f7854037a6e4d6589329c80634f84b26e91d1df5 Mon Sep 17 00:00:00 2001 From: Dimitrij Denissenko Date: Fri, 18 Mar 2016 08:36:26 +0000 Subject: [PATCH] First draft --- .gitignore | 1 + Makefile | 33 +++++++++++++++++++++++ README.md | 34 +++++++++++++++++++++++ cmd/grpc-health/main.go | 60 +++++++++++++++++++++++++++++++++++++++++ grpctools_test.go | 13 +++++++++ logger.go | 10 +++++++ server.go | 42 +++++++++++++++++++++++++++++ 7 files changed, 193 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 cmd/grpc-health/main.go create mode 100644 grpctools_test.go create mode 100644 logger.go create mode 100644 server.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..01d0a08 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +pkg/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..281805b --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +VERSION=0.1.2 + +default: vet errcheck test + +deps: + go get -t ./... + +test: + go test ./... + +vet: + go tool vet -composites=false $(wildcard *.go) + +errcheck: + errcheck -ignoretests -ignore 'Close' $$(go list ./...) + +pkg-deps: + go get github.com/mitchellh/gox + +pkg: pkg-deps \ + pkg/release/grpc-health_${VERSION}_linux_amd64.zip + +.PHONY: test vet errcheck deps pkg + +# --------------------------------------------------------------------- + +pkg/build/linux/amd64/grpc-health: cmd/grpc-health/main.go + mkdir -p $(dir $@) + gox -osarch="linux/amd64" -output $@ ./$(dir $<) + +pkg/release/grpc-health_${VERSION}_linux_amd64.zip: pkg/build/linux/amd64/grpc-health + mkdir -p $(dir $@) + zip -9 -j $@ $< diff --git a/README.md b/README.md new file mode 100644 index 0000000..db3a5ea --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# grpctools + +Little helpers for grpc + +## Testing + +Simply run: + + make + +## Licence + +``` +Copyright (c) 2016 Black Square Media + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` diff --git a/cmd/grpc-health/main.go b/cmd/grpc-health/main.go new file mode 100644 index 0000000..a104d20 --- /dev/null +++ b/cmd/grpc-health/main.go @@ -0,0 +1,60 @@ +package main + +import ( + "flag" + "fmt" + "os" + "time" + + "golang.org/x/net/context" + "google.golang.org/grpc" + healthpb "google.golang.org/grpc/health/grpc_health_v1" +) + +var flags struct { + Addr, Service string + Timeout time.Duration +} + +func init() { + flag.StringVar(&flags.Addr, "a", "127.0.0.1:8080", "Address to connect to. Default: 127.0.0.1:8080") + flag.StringVar(&flags.Service, "s", "", "The service name. REQUIRED.") + flag.DurationVar(&flags.Timeout, "timeout", 30*time.Second, "The request timeout. Default: 30s") +} + +func main() { + flag.Parse() + + if flags.Service == "" { + flag.PrintDefaults() + os.Exit(64) + } + + os.Exit(run()) +} + +func run() int { + conn, err := grpc.Dial(flags.Addr, grpc.WithInsecure(), grpc.WithTimeout(flags.Timeout)) + if err != nil { + fmt.Println(err) + return 1 + } + defer conn.Close() + + req := &healthpb.HealthCheckRequest{Service: flags.Service} + resp, err := healthpb.NewHealthClient(conn).Check(context.Background(), req) + if err != nil { + fmt.Println(err) + return 1 + } + + fmt.Println("Status:", resp.Status.String()) + switch resp.Status { + case healthpb.HealthCheckResponse_SERVING: + return 0 + case healthpb.HealthCheckResponse_NOT_SERVING: + return 2 + default: + return 1 + } +} diff --git a/grpctools_test.go b/grpctools_test.go new file mode 100644 index 0000000..6dbfb54 --- /dev/null +++ b/grpctools_test.go @@ -0,0 +1,13 @@ +package grpctools + +import ( + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +func TestSuite(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "grpctools") +} diff --git a/logger.go b/logger.go new file mode 100644 index 0000000..08fdfc0 --- /dev/null +++ b/logger.go @@ -0,0 +1,10 @@ +package grpctools + +import ( + "google.golang.org/grpc/grpclog" +) + +// SetLogger is a proxy to grpclog.SetLogger +func SetLogger(logger grpclog.Logger) { + grpclog.SetLogger(logger) +} diff --git a/server.go b/server.go new file mode 100644 index 0000000..887e493 --- /dev/null +++ b/server.go @@ -0,0 +1,42 @@ +package grpctools + +import ( + "net" + + "google.golang.org/grpc" + "google.golang.org/grpc/health" + healthpb "google.golang.org/grpc/health/grpc_health_v1" +) + +// Server embeds a standard grpc Server with a healthcheck +type Server struct { + *grpc.Server + + name string + health *health.HealthServer +} + +// NewServer returns a new Server instance. +func NewServer(name string) *Server { + srv := &Server{ + Server: grpc.NewServer(), + name: name, + health: health.NewHealthServer(), + } + healthpb.RegisterHealthServer(srv.Server, srv.health) + return srv +} + +// ListenAndServe starts the server (blocking). +func (s *Server) ListenAndServe(addr string) error { + lis, err := net.Listen("tcp", addr) + if err != nil { + return err + } + defer lis.Close() + + s.health.SetServingStatus(s.name, healthpb.HealthCheckResponse_SERVING) + err = s.Serve(lis) + s.health.SetServingStatus(s.name, healthpb.HealthCheckResponse_NOT_SERVING) + return err +}