diff --git a/plugins/inputs/gnmi/README.md b/plugins/inputs/gnmi/README.md index 2b332a6cc..51d662753 100644 --- a/plugins/inputs/gnmi/README.md +++ b/plugins/inputs/gnmi/README.md @@ -52,6 +52,18 @@ See the [CONFIGURATION.md][CONFIGURATION.md] for more details. ## redial in case of failures after # redial = "10s" + ## gRPC Keepalive settings + ## See https://pkg.go.dev/google.golang.org/grpc/keepalive + ## The client will ping the server to see if the transport is still alive if it has + ## not see any activity for the given time. + ## If not set, none of the keep-alive setting (including those below) will be applied. + ## If set and set below 10 seconds, the gRPC library will apply a minimum value of 10s will be used instead. + # keepalive_time = "" + + ## Timeout for seeing any activity after the keep-alive probe was + ## sent. If no activity is seen the connection is closed. + # keepalive_timeout = "" + ## gRPC Maximum Message Size # max_msg_size = "4MB" diff --git a/plugins/inputs/gnmi/gnmi.go b/plugins/inputs/gnmi/gnmi.go index 9e19e57f0..8d552b5d7 100644 --- a/plugins/inputs/gnmi/gnmi.go +++ b/plugins/inputs/gnmi/gnmi.go @@ -12,6 +12,7 @@ import ( "github.com/google/gnxi/utils/xpath" gnmiLib "github.com/openconfig/gnmi/proto/gnmi" + "google.golang.org/grpc/keepalive" "google.golang.org/grpc/metadata" "github.com/influxdata/telegraf" @@ -57,6 +58,8 @@ type GNMI struct { GuessPathTag bool `toml:"guess_path_tag" deprecated:"1.30.0;use 'path_guessing_strategy' instead"` GuessPathStrategy string `toml:"path_guessing_strategy"` EnableTLS bool `toml:"enable_tls" deprecated:"1.27.0;use 'tls_enable' instead"` + KeepaliveTime config.Duration `toml:"keepalive_time"` + KeepaliveTimeout config.Duration `toml:"keepalive_timeout"` Log telegraf.Logger `toml:"-"` internaltls.ClientConfig @@ -233,6 +236,11 @@ func (c *GNMI) Start(acc telegraf.Accumulator) error { trimSlash: c.TrimFieldNames, guessPathStrategy: c.GuessPathStrategy, log: c.Log, + ClientParameters: keepalive.ClientParameters{ + Time: time.Duration(c.KeepaliveTime), + Timeout: time.Duration(c.KeepaliveTimeout), + PermitWithoutStream: false, + }, } for ctx.Err() == nil { if err := h.subscribeGNMI(ctx, acc, tlscfg, request); err != nil && ctx.Err() == nil { diff --git a/plugins/inputs/gnmi/handler.go b/plugins/inputs/gnmi/handler.go index eb9cbc5fc..988f76136 100644 --- a/plugins/inputs/gnmi/handler.go +++ b/plugins/inputs/gnmi/handler.go @@ -17,6 +17,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" + "google.golang.org/grpc/keepalive" "google.golang.org/protobuf/encoding/protojson" "google.golang.org/protobuf/proto" @@ -42,6 +43,7 @@ type handler struct { trimSlash bool guessPathStrategy string log telegraf.Logger + keepalive.ClientParameters } // SubscribeGNMI and extract telemetry data @@ -62,6 +64,10 @@ func (h *handler) subscribeGNMI(ctx context.Context, acc telegraf.Accumulator, t )) } + if h.ClientParameters.Time > 0 { + opts = append(opts, grpc.WithKeepaliveParams(h.ClientParameters)) + } + client, err := grpc.DialContext(ctx, h.address, opts...) if err != nil { return fmt.Errorf("failed to dial: %w", err) diff --git a/plugins/inputs/gnmi/sample.conf b/plugins/inputs/gnmi/sample.conf index 1ebf93035..4d473139d 100644 --- a/plugins/inputs/gnmi/sample.conf +++ b/plugins/inputs/gnmi/sample.conf @@ -13,6 +13,18 @@ ## redial in case of failures after # redial = "10s" + ## gRPC Keepalive settings + ## See https://pkg.go.dev/google.golang.org/grpc/keepalive + ## The client will ping the server to see if the transport is still alive if it has + ## not see any activity for the given time. + ## If not set, none of the keep-alive setting (including those below) will be applied. + ## If set and set below 10 seconds, the gRPC library will apply a minimum value of 10s will be used instead. + # keepalive_time = "" + + ## Timeout for seeing any activity after the keep-alive probe was + ## sent. If no activity is seen the connection is closed. + # keepalive_timeout = "" + ## gRPC Maximum Message Size # max_msg_size = "4MB"