diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d24d013f0f..0a39d94478c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,6 +61,8 @@ Main (unreleased) - Fix Docker log corruption for multiplexed long lines. (@axd1x8a) +- Allow configuration of `force_attempt_http2` and default it to `true` for otelcol exporters with HTTP client configurations. (@dehaansa) + v1.12.0 ----------------- diff --git a/docs/sources/reference/components/otelcol/otelcol.exporter.splunkhec.md b/docs/sources/reference/components/otelcol/otelcol.exporter.splunkhec.md index f95f500d10c..03b85d4b63d 100644 --- a/docs/sources/reference/components/otelcol/otelcol.exporter.splunkhec.md +++ b/docs/sources/reference/components/otelcol/otelcol.exporter.splunkhec.md @@ -149,6 +149,7 @@ The following arguments are supported: | Name | Type | Description | Default | Required | |---------------------------|------------|-------------------------------------------------------------------------------------------------|---------|----------| | `endpoint` | `string` | The Splunk HEC endpoint to use. | | yes | +| `force_attempt_http2` | `bool` | Force the HTTP client to try to use the HTTP/2 protocol. | `true` | no | | `disable_keep_alives` | `bool` | Disable HTTP keep-alive. | `false` | no | | `idle_conn_timeout` | `duration` | Time to wait before an idle connection closes itself. | `"45s"` | no | | `insecure_skip_verify` | `bool` | Ignores insecure server TLS certificates. | `false` | no | diff --git a/docs/sources/shared/reference/components/otelcol-http-client-block.md b/docs/sources/shared/reference/components/otelcol-http-client-block.md index 7e16bbfefbc..a161057b76b 100644 --- a/docs/sources/shared/reference/components/otelcol-http-client-block.md +++ b/docs/sources/shared/reference/components/otelcol-http-client-block.md @@ -12,6 +12,7 @@ The following arguments are supported: | `auth` | `capsule(otelcol.Handler)` | Handler from an `otelcol.auth` component to use for authenticating requests. | | no | | `compression` | `string` | Compression mechanism to use for requests. | `"gzip"` | no | | `disable_keep_alives` | `bool` | Disable HTTP keep-alive. | `false` | no | +| `force_attempt_http2` | `bool` | Force the HTTP client to try to use the HTTP/2 protocol. | `true` | no | | `headers` | `map(string)` | Additional headers to send with the request. | `{}` | no | | `http2_ping_timeout` | `duration` | Timeout after which the connection will be closed if a response to Ping isn't received. | `"15s"` | no | | `http2_read_idle_timeout` | `duration` | Timeout after which a health check using ping frame will be carried out if no frame is received on the connection. | `"0s"` | no | @@ -36,4 +37,7 @@ If `http2_ping_timeout` is unset or set to `0s`, it will default to `15s`. If `http2_read_idle_timeout` is unset or set to `0s`, then no health check will be performed. +Golang's default HTTP transport attempts HTTP/2 by default, however some settings (`max_conns_per_host`, `max_idle_conns_per_host`, `max_idle_conns`) are only relevant for HTTP/1. +The `force_attempt_http2` attribute allows a user to only attempt HTTP/1. + {{< docs/shared lookup="reference/components/otelcol-compression-field.md" source="alloy" version="" >}} diff --git a/internal/component/otelcol/config_http.go b/internal/component/otelcol/config_http.go index 2d886b8d003..9282ba59519 100644 --- a/internal/component/otelcol/config_http.go +++ b/internal/component/otelcol/config_http.go @@ -148,6 +148,7 @@ type HTTPClientArguments struct { DisableKeepAlives bool `alloy:"disable_keep_alives,attr,optional"` HTTP2ReadIdleTimeout time.Duration `alloy:"http2_read_idle_timeout,attr,optional"` HTTP2PingTimeout time.Duration `alloy:"http2_ping_timeout,attr,optional"` + ForceAttemptHTTP2 bool `alloy:"force_attempt_http2,attr,optional"` // Auth is a binding to an otelcol.auth.* component extension which handles // authentication. @@ -198,6 +199,7 @@ func (args *HTTPClientArguments) Convert() (*otelconfighttp.ClientConfig, error) DisableKeepAlives: args.DisableKeepAlives, HTTP2ReadIdleTimeout: args.HTTP2ReadIdleTimeout, HTTP2PingTimeout: args.HTTP2PingTimeout, + ForceAttemptHTTP2: args.ForceAttemptHTTP2, Auth: authentication, diff --git a/internal/component/otelcol/exporter/faro/faro.go b/internal/component/otelcol/exporter/faro/faro.go index 7fd5f9dccd2..adb143de8f5 100644 --- a/internal/component/otelcol/exporter/faro/faro.go +++ b/internal/component/otelcol/exporter/faro/faro.go @@ -99,11 +99,12 @@ type HTTPClientArguments otelcol.HTTPClientArguments // SetToDefault implements syntax.Defaulter. func (args *HTTPClientArguments) SetToDefault() { *args = HTTPClientArguments{ - Timeout: 30 * time.Second, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - Headers: map[string]string{}, - Compression: otelcol.CompressionTypeGzip, - WriteBufferSize: 512 * 1024, + Timeout: 30 * time.Second, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + Headers: map[string]string{}, + Compression: otelcol.CompressionTypeGzip, + WriteBufferSize: 512 * 1024, + ForceAttemptHTTP2: true, } } diff --git a/internal/component/otelcol/exporter/faro/faro_test.go b/internal/component/otelcol/exporter/faro/faro_test.go index 69be2c79f26..4e82d892bfa 100644 --- a/internal/component/otelcol/exporter/faro/faro_test.go +++ b/internal/component/otelcol/exporter/faro/faro_test.go @@ -37,6 +37,7 @@ func TestConfigConversion(t *testing.T) { headers = { "X-Scope-OrgID" = "123", } + force_attempt_http2 = false } sending_queue { enabled = true @@ -63,6 +64,7 @@ func TestConfigConversion(t *testing.T) { Headers: configopaque.MapList{ configopaque.Pair{Name: "X-Scope-OrgID", Value: "123"}, }, + ForceAttemptHTTP2: false, }, QueueConfig: defaultQueueConfig, RetryConfig: configretry.BackOffConfig{ @@ -84,13 +86,14 @@ func TestConfigConversion(t *testing.T) { `, expected: faroexporter.Config{ ClientConfig: confighttp.ClientConfig{ - Endpoint: "https://faro.example.com/collect", - Timeout: defaultTimeout, - Compression: "gzip", - WriteBufferSize: 512 * 1024, - MaxIdleConns: 100, - IdleConnTimeout: 90 * time.Second, - Headers: configopaque.MapList{}, + Endpoint: "https://faro.example.com/collect", + Timeout: defaultTimeout, + Compression: "gzip", + WriteBufferSize: 512 * 1024, + MaxIdleConns: 100, + IdleConnTimeout: 90 * time.Second, + Headers: configopaque.MapList{}, + ForceAttemptHTTP2: true, }, QueueConfig: defaultQueueConfig, RetryConfig: defaultRetrySettings, diff --git a/internal/component/otelcol/exporter/otlphttp/otlphttp.go b/internal/component/otelcol/exporter/otlphttp/otlphttp.go index 9aacea4f244..31a741985bf 100644 --- a/internal/component/otelcol/exporter/otlphttp/otlphttp.go +++ b/internal/component/otelcol/exporter/otlphttp/otlphttp.go @@ -137,11 +137,12 @@ func (args *HTTPClientArguments) SetToDefault() { MaxIdleConns: maxIdleConns, IdleConnTimeout: idleConnTimeout, - Timeout: 30 * time.Second, - Headers: map[string]string{}, - Compression: otelcol.CompressionTypeGzip, - ReadBufferSize: 0, - WriteBufferSize: 512 * 1024, - HTTP2PingTimeout: 15 * time.Second, + Timeout: 30 * time.Second, + Headers: map[string]string{}, + Compression: otelcol.CompressionTypeGzip, + ReadBufferSize: 0, + WriteBufferSize: 512 * 1024, + HTTP2PingTimeout: 15 * time.Second, + ForceAttemptHTTP2: true, } } diff --git a/internal/component/otelcol/exporter/splunkhec/config/splunkhec.go b/internal/component/otelcol/exporter/splunkhec/config/splunkhec.go index eb1391b93b8..43a9ede5f19 100644 --- a/internal/component/otelcol/exporter/splunkhec/config/splunkhec.go +++ b/internal/component/otelcol/exporter/splunkhec/config/splunkhec.go @@ -60,6 +60,8 @@ type SplunkHecClientArguments struct { DisableKeepAlives bool `alloy:"disable_keep_alives,attr,optional"` // TLSSetting for the HTTP client. InsecureSkipVerify bool `alloy:"insecure_skip_verify,attr,optional"` + // ForceAttemptHTTP2 for the HTTP client. + ForceAttemptHTTP2 bool `alloy:"force_attempt_http2,attr,optional"` } type SplunkConf struct { // DeprecatedBatcher is the deprecated batcher configuration. @@ -230,6 +232,7 @@ func (args *SplunkHecClientArguments) Convert() *confighttp.ClientConfig { MaxConnsPerHost: args.MaxConnsPerHost, IdleConnTimeout: args.IdleConnTimeout, DisableKeepAlives: args.DisableKeepAlives, + ForceAttemptHTTP2: args.ForceAttemptHTTP2, TLS: configtls.ClientConfig{ InsecureSkipVerify: args.InsecureSkipVerify, }, @@ -240,6 +243,7 @@ func (args *SplunkHecClientArguments) SetToDefault() { args.Timeout = 15 * time.Second args.MaxIdleConns = 100 args.IdleConnTimeout = 90 * time.Second + args.ForceAttemptHTTP2 = true } func (args *SplunkHecClientArguments) Validate() error { diff --git a/internal/component/otelcol/exporter/splunkhec/splunkhec_test.go b/internal/component/otelcol/exporter/splunkhec/splunkhec_test.go index e9a0d055d48..0993ab087ba 100644 --- a/internal/component/otelcol/exporter/splunkhec/splunkhec_test.go +++ b/internal/component/otelcol/exporter/splunkhec/splunkhec_test.go @@ -52,6 +52,7 @@ func TestConfigConversion(t *testing.T) { HTTP2ReadIdleTimeout: 0, HTTP2PingTimeout: 0, Cookies: confighttp.CookiesConfig{}, + ForceAttemptHTTP2: true, }, QueueSettings: exporterhelper.QueueBatchConfig{ Enabled: true, @@ -139,6 +140,7 @@ func TestConfigConversion(t *testing.T) { DisableKeepAlives: false, HTTP2ReadIdleTimeout: 0, HTTP2PingTimeout: 0, + ForceAttemptHTTP2: true, Cookies: confighttp.CookiesConfig{}}, QueueSettings: exporterhelper.QueueBatchConfig{ Enabled: true, diff --git a/internal/converter/internal/otelcolconvert/converter_faroexporter.go b/internal/converter/internal/otelcolconvert/converter_faroexporter.go index 22866b426b8..b47ec804be5 100644 --- a/internal/converter/internal/otelcolconvert/converter_faroexporter.go +++ b/internal/converter/internal/otelcolconvert/converter_faroexporter.go @@ -91,6 +91,7 @@ func toFaroHTTPClientArguments(cfg confighttp.ClientConfig) faro.HTTPClientArgum DisableKeepAlives: cfg.DisableKeepAlives, HTTP2PingTimeout: cfg.HTTP2PingTimeout, HTTP2ReadIdleTimeout: cfg.HTTP2ReadIdleTimeout, + ForceAttemptHTTP2: cfg.ForceAttemptHTTP2, Authentication: a, } diff --git a/internal/converter/internal/otelcolconvert/converter_otlphttpexporter.go b/internal/converter/internal/otelcolconvert/converter_otlphttpexporter.go index 7bdcfe333c4..26ab2d06310 100644 --- a/internal/converter/internal/otelcolconvert/converter_otlphttpexporter.go +++ b/internal/converter/internal/otelcolconvert/converter_otlphttpexporter.go @@ -92,6 +92,7 @@ func toHTTPClientArguments(cfg confighttp.ClientConfig) otelcol.HTTPClientArgume DisableKeepAlives: cfg.DisableKeepAlives, HTTP2PingTimeout: cfg.HTTP2PingTimeout, HTTP2ReadIdleTimeout: cfg.HTTP2ReadIdleTimeout, + ForceAttemptHTTP2: cfg.ForceAttemptHTTP2, Authentication: a, } diff --git a/internal/converter/internal/otelcolconvert/converter_splunkhecexporter.go b/internal/converter/internal/otelcolconvert/converter_splunkhecexporter.go index 14fa0ece8b2..3e76b3d8c1f 100644 --- a/internal/converter/internal/otelcolconvert/converter_splunkhecexporter.go +++ b/internal/converter/internal/otelcolconvert/converter_splunkhecexporter.go @@ -81,6 +81,7 @@ func toSplunkHecHTTPClientArguments(cfg *splunkhecexporter.Config) splunkhec_con IdleConnTimeout: cfg.IdleConnTimeout, DisableKeepAlives: cfg.DisableKeepAlives, InsecureSkipVerify: cfg.TLS.Insecure, + ForceAttemptHTTP2: cfg.ForceAttemptHTTP2, } }