From 6e1d939b2134cb69c637c36b5d5af131190c20c5 Mon Sep 17 00:00:00 2001 From: Sean Liao Date: Tue, 12 Sep 2023 20:37:37 +0100 Subject: [PATCH 1/3] add gRPC health check --- .chloggen/grpc-healthcheck.yaml | 25 +++++++++++++++++++++++++ config/configgrpc/configgrpc.go | 16 +++++++++++++++- config/configgrpc/configgrpc_test.go | 16 +++++++++++++++- 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 .chloggen/grpc-healthcheck.yaml diff --git a/.chloggen/grpc-healthcheck.yaml b/.chloggen/grpc-healthcheck.yaml new file mode 100644 index 00000000000..9d883aabb41 --- /dev/null +++ b/.chloggen/grpc-healthcheck.yaml @@ -0,0 +1,25 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) +component: configgrpc + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: gRPC servers now have the option to register the standard grpc.health.v1.Health healthcheck service. + +# One or more tracking issues or pull requests related to the change +issues: [3040] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/config/configgrpc/configgrpc.go b/config/configgrpc/configgrpc.go index f6da798f165..e19bddfdd93 100644 --- a/config/configgrpc/configgrpc.go +++ b/config/configgrpc/configgrpc.go @@ -21,6 +21,8 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/encoding/gzip" + "google.golang.org/grpc/health" + "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" @@ -143,6 +145,10 @@ type GRPCServerSettings struct { // Keepalive anchor for all the settings related to keepalive. Keepalive *KeepaliveServerConfig `mapstructure:"keepalive"` + // HealthCheck service for the gRPC server. See gRPC health checking. + // (https://github.com/grpc/grpc/blob/master/doc/health-checking.md) + HealthCheck bool `mapstructure:"healthcheck"` + // Auth for this receiver Auth *configauth.Authentication `mapstructure:"auth"` @@ -280,7 +286,15 @@ func (gss *GRPCServerSettings) ToServer(host component.Host, settings component. return nil, err } opts = append(opts, extraOpts...) - return grpc.NewServer(opts...), nil + grpcServer, err := grpc.NewServer(opts...), nil + if err != nil { + return nil, err + } + if gss.HealthCheck { + healthServer := health.NewServer() + grpc_health_v1.RegisterHealthServer(grpcServer, healthServer) + } + return grpcServer, nil } func (gss *GRPCServerSettings) toServerOption(host component.Host, settings component.TelemetrySettings) ([]grpc.ServerOption, error) { diff --git a/config/configgrpc/configgrpc_test.go b/config/configgrpc/configgrpc_test.go index 175848a5ebf..42842075fb2 100644 --- a/config/configgrpc/configgrpc_test.go +++ b/config/configgrpc/configgrpc_test.go @@ -19,6 +19,7 @@ import ( "go.uber.org/zap/zaptest/observer" "google.golang.org/grpc" "google.golang.org/grpc/balancer" + "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/metadata" "google.golang.org/grpc/peer" @@ -236,6 +237,20 @@ func TestGrpcServerAuthSettings(t *testing.T) { assert.NotNil(t, srv) } +func TestGrpcHealthCheck(t *testing.T) { + gss := &GRPCServerSettings{ + NetAddr: confignet.NetAddr{ + Endpoint: "localhost:1234", + Transport: "tcp", + }, + HealthCheck: true, + } + gsvr, err := gss.ToServer(componenttest.NewNopHost(), componenttest.NewNopTelemetrySettings()) + assert.NoError(t, err) + info := gsvr.GetServiceInfo()[grpc_health_v1.Health_ServiceDesc.ServiceName] + assert.Len(t, info.Methods, 2) // assert the 2 grpc health check endpoints were registered +} + func TestGRPCClientSettingsError(t *testing.T) { tt, err := obsreporttest.SetupTelemetry(component.NewID("component")) require.NoError(t, err) @@ -424,7 +439,6 @@ func TestGRPCServerWarning(t *testing.T) { require.Len(t, observed.FilterLevelExact(zap.WarnLevel).All(), test.len) }) } - } func TestGRPCServerSettingsError(t *testing.T) { From ac1c0ee808d6cd06c39f26c0a21d142ca8e68149 Mon Sep 17 00:00:00 2001 From: Sean Liao Date: Tue, 12 Sep 2023 20:43:37 +0100 Subject: [PATCH 2/3] update readme --- config/configgrpc/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/config/configgrpc/README.md b/config/configgrpc/README.md index b9cf2f01be2..faf2321698a 100644 --- a/config/configgrpc/README.md +++ b/config/configgrpc/README.md @@ -110,4 +110,5 @@ see [confignet README](../confignet/README.md). - [`read_buffer_size`](https://godoc.org/google.golang.org/grpc#ReadBufferSize) - [`tls`](../configtls/README.md) - [`write_buffer_size`](https://godoc.org/google.golang.org/grpc#WriteBufferSize) +- [`healthcheck`](https://github.com/grpc/grpc/blob/master/doc/health-checking.md): registers the health check service - [`auth`](../configauth/README.md) From e0dd4d4961ed82c816e7cd8f9b47cd23807d8ab6 Mon Sep 17 00:00:00 2001 From: Sean Liao Date: Tue, 12 Sep 2023 20:55:20 +0100 Subject: [PATCH 3/3] cleanup typo --- config/configgrpc/configgrpc.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/config/configgrpc/configgrpc.go b/config/configgrpc/configgrpc.go index e19bddfdd93..e6001c77a22 100644 --- a/config/configgrpc/configgrpc.go +++ b/config/configgrpc/configgrpc.go @@ -286,10 +286,7 @@ func (gss *GRPCServerSettings) ToServer(host component.Host, settings component. return nil, err } opts = append(opts, extraOpts...) - grpcServer, err := grpc.NewServer(opts...), nil - if err != nil { - return nil, err - } + grpcServer := grpc.NewServer(opts...) if gss.HealthCheck { healthServer := health.NewServer() grpc_health_v1.RegisterHealthServer(grpcServer, healthServer)