Skip to content

Commit

Permalink
fix(outputs.influxdb_v2): Expose HTTP/2 client timeouts (#13562)
Browse files Browse the repository at this point in the history
  • Loading branch information
powersj authored Jul 10, 2023
1 parent 1dd45b1 commit d2ebc8e
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 16 deletions.
8 changes: 4 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,13 @@ require (
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v0.39.0
go.opentelemetry.io/otel/sdk/metric v0.39.0
go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd
golang.org/x/crypto v0.10.0
golang.org/x/crypto v0.11.0
golang.org/x/mod v0.11.0
golang.org/x/net v0.11.0
golang.org/x/net v0.12.0
golang.org/x/oauth2 v0.9.0
golang.org/x/sync v0.3.0
golang.org/x/sys v0.9.0
golang.org/x/term v0.9.0
golang.org/x/sys v0.10.0
golang.org/x/term v0.10.0
golang.org/x/text v0.11.0
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20211230205640-daad0b7ba671
gonum.org/v1/gonum v0.13.0
Expand Down
16 changes: 8 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1610,8 +1610,8 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down Expand Up @@ -1728,8 +1728,8 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand Down Expand Up @@ -1860,8 +1860,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
Expand All @@ -1873,8 +1873,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c=
golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
12 changes: 12 additions & 0 deletions plugins/outputs/influxdb_v2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ to use them.
## Enable or disable uint support for writing uints influxdb 2.0.
# influx_uint_support = false

## HTTP/2 Timeouts
## The following values control the HTTP/2 client's timeouts. These settings
## are generally not required unless a user is seeing issues with client
## disconnects. If a user does see issues, then it is suggested to set these
## values to "15s" for ping timeout and "30s" for read idle timeout and
## retry.
##
## Note that the timer for read_idle_timeout begins at the end of the last
## successful write and not at the beginning of the next write.
# ping_timeout = "0s"
# read_idle_timeout = "0s"

## Optional TLS Config for use on HTTP connections.
# tls_ca = "/etc/telegraf/ca.pem"
# tls_cert = "/etc/telegraf/cert.pem"
Expand Down
10 changes: 10 additions & 0 deletions plugins/outputs/influxdb_v2/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/influxdata/telegraf/config"
"github.com/influxdata/telegraf/internal"
"github.com/influxdata/telegraf/plugins/serializers/influx"
"golang.org/x/net/http2"
)

type APIError struct {
Expand Down Expand Up @@ -52,6 +53,8 @@ type HTTPConfig struct {
Proxy *url.URL
UserAgent string
ContentEncoding string
PingTimeout config.Duration
ReadIdleTimeout config.Duration
TLSConfig *tls.Config

Serializer *influx.Serializer
Expand Down Expand Up @@ -126,6 +129,13 @@ func NewHTTPClient(cfg *HTTPConfig) (*httpClient, error) {
Proxy: proxy,
TLSClientConfig: cfg.TLSConfig,
}
if cfg.ReadIdleTimeout != 0 || cfg.PingTimeout != 0 {
http2Trans, err := http2.ConfigureTransports(transport)
if err == nil {
http2Trans.ReadIdleTimeout = time.Duration(cfg.ReadIdleTimeout)
http2Trans.PingTimeout = time.Duration(cfg.PingTimeout)
}
}
case "unix":
transport = &http.Transport{
Dial: func(_, _ string) (net.Conn, error) {
Expand Down
76 changes: 72 additions & 4 deletions plugins/outputs/influxdb_v2/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/stretchr/testify/require"

"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/config"
influxdb "github.com/influxdata/telegraf/plugins/outputs/influxdb_v2"
"github.com/influxdata/telegraf/testutil"
)
Expand Down Expand Up @@ -40,6 +41,13 @@ func TestNewHTTPClient(t *testing.T) {
URL: genURL("unix://var/run/influxd.sock"),
},
},
{
cfg: &influxdb.HTTPConfig{
URL: genURL("unix://var/run/influxd.sock"),
PingTimeout: config.Duration(15 * time.Second),
ReadIdleTimeout: config.Duration(30 * time.Second),
},
},
}

for i := range tests {
Expand All @@ -56,6 +64,66 @@ func TestNewHTTPClient(t *testing.T) {
}
}

func TestWrite(t *testing.T) {
ts := httptest.NewServer(
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/api/v2/write":
err := r.ParseForm()
require.NoError(t, err)
require.Equal(t, r.Form["bucket"], []string{"foobar"})

body, err := io.ReadAll(r.Body)
require.NoError(t, err)
require.Contains(t, string(body), "cpu value=42.123")

w.WriteHeader(http.StatusNoContent)
return
default:
w.WriteHeader(http.StatusNotFound)
return
}
}),
)
defer ts.Close()

addr := &url.URL{
Scheme: "http",
Host: ts.Listener.Addr().String(),
}

cfg := &influxdb.HTTPConfig{
URL: addr,
Bucket: "telegraf",
BucketTag: "bucket",
ExcludeBucketTag: true,
PingTimeout: config.Duration(15 * time.Second),
ReadIdleTimeout: config.Duration(30 * time.Second),
}

client, err := influxdb.NewHTTPClient(cfg)
require.NoError(t, err)

metrics := []telegraf.Metric{
testutil.MustMetric(
"cpu",
map[string]string{
"bucket": "foobar",
},
map[string]interface{}{
"value": 42.123,
},
time.Unix(0, 0),
),
}

ctx := context.Background()
err = client.Write(ctx, metrics)
require.NoError(t, err)
err = client.Write(ctx, metrics)
require.NoError(t, err)
}

func TestWriteBucketTagWorksOnRetry(t *testing.T) {
ts := httptest.NewServer(
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -84,14 +152,14 @@ func TestWriteBucketTagWorksOnRetry(t *testing.T) {
Host: ts.Listener.Addr().String(),
}

config := &influxdb.HTTPConfig{
cfg := &influxdb.HTTPConfig{
URL: addr,
Bucket: "telegraf",
BucketTag: "bucket",
ExcludeBucketTag: true,
}

client, err := influxdb.NewHTTPClient(config)
client, err := influxdb.NewHTTPClient(cfg)
require.NoError(t, err)

metrics := []telegraf.Metric{
Expand Down Expand Up @@ -146,15 +214,15 @@ func TestTooLargeWriteRetry(t *testing.T) {
Host: ts.Listener.Addr().String(),
}

config := &influxdb.HTTPConfig{
cfg := &influxdb.HTTPConfig{
URL: addr,
Bucket: "telegraf",
BucketTag: "bucket",
ExcludeBucketTag: true,
Log: testutil.Logger{},
}

client, err := influxdb.NewHTTPClient(config)
client, err := influxdb.NewHTTPClient(cfg)
require.NoError(t, err)

// Together the metric batch size is too big, split up, we get success
Expand Down
4 changes: 4 additions & 0 deletions plugins/outputs/influxdb_v2/influxdb_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ type InfluxDB struct {
UserAgent string `toml:"user_agent"`
ContentEncoding string `toml:"content_encoding"`
UintSupport bool `toml:"influx_uint_support"`
PingTimeout config.Duration `toml:"ping_timeout"`
ReadIdleTimeout config.Duration `toml:"read_idle_timeout"`
tls.ClientConfig

Log telegraf.Logger `toml:"-"`
Expand Down Expand Up @@ -144,6 +146,8 @@ func (i *InfluxDB) getHTTPClient(address *url.URL, proxy *url.URL) (Client, erro
ContentEncoding: i.ContentEncoding,
TLSConfig: tlsConfig,
Serializer: serializer,
PingTimeout: i.PingTimeout,
ReadIdleTimeout: i.ReadIdleTimeout,
Log: i.Log,
}

Expand Down
12 changes: 12 additions & 0 deletions plugins/outputs/influxdb_v2/sample.conf
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@
## Enable or disable uint support for writing uints influxdb 2.0.
# influx_uint_support = false

## HTTP/2 Timeouts
## The following values control the HTTP/2 client's timeouts. These settings
## are generally not required unless a user is seeing issues with client
## disconnects. If a user does see issues, then it is suggested to set these
## values to "15s" for ping timeout and "30s" for read idle timeout and
## retry.
##
## Note that the timer for read_idle_timeout begins at the end of the last
## successful write and not at the beginning of the next write.
# ping_timeout = "0s"
# read_idle_timeout = "0s"

## Optional TLS Config for use on HTTP connections.
# tls_ca = "/etc/telegraf/ca.pem"
# tls_cert = "/etc/telegraf/cert.pem"
Expand Down

0 comments on commit d2ebc8e

Please sign in to comment.