fix(outputs.influxdb_v2): Expose HTTP/2 client timeouts (#13562)
This commit is contained in:
parent
1dd45b1d1c
commit
d2ebc8ecc0
8
go.mod
8
go.mod
|
|
@ -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
|
||||
|
|
|
|||
16
go.sum
16
go.sum
|
|
@ -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=
|
||||
|
|
@ -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=
|
||||
|
|
@ -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=
|
||||
|
|
@ -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=
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
@ -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
|
||||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
)
|
||||
|
|
@ -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 {
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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{
|
||||
|
|
@ -146,7 +214,7 @@ func TestTooLargeWriteRetry(t *testing.T) {
|
|||
Host: ts.Listener.Addr().String(),
|
||||
}
|
||||
|
||||
config := &influxdb.HTTPConfig{
|
||||
cfg := &influxdb.HTTPConfig{
|
||||
URL: addr,
|
||||
Bucket: "telegraf",
|
||||
BucketTag: "bucket",
|
||||
|
|
@ -154,7 +222,7 @@ func TestTooLargeWriteRetry(t *testing.T) {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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:"-"`
|
||||
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue