Skip to content

Commit 135d723

Browse files
authored
[exporter/datadog] Respect confighttp configs and use better defaults (#31733)
**Description:** <Describe what has changed.> Datadog exporter respects a subset of settings in confighttp client configs and uses a consistent default HTTP transport settings as Datadog Agent (https://github.com/DataDog/datadog-agent/blob/f9ae7f4b842f83b23b2dfe3f15d31f9e6b12e857/pkg/util/http/transport.go#L91-L106).
1 parent 4ca7530 commit 135d723

21 files changed

+387
-81
lines changed

.chloggen/ddog-config-change.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: breaking
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: datadogexporter
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: "Remove config structs `LimitedClientConfig` and `LimitedTLSClientSettings`"
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [31733]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: This should have no impact to end users as long as they do not import Datadog exporter config structs in their source code.
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: [api]

.chloggen/ddog-http-defaults.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: datadogexporter
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Datadog exporter uses the same default HTTP settings as Datadog Agent HTTP transport
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [31733]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext:
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: []
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
7+
component: datadogexporter
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Datadog exporter respects a subset of settings in confighttp client configs
11+
12+
# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists.
13+
issues: [31733]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: "Currently the following configs are respected: `read_buffer_size`, `write_buffer_size`, `timeout`, `max_idle_conns`, `max_idle_conns_per_host`, `max_conns_per_host`, `idle_conn_timeout`, `disable_keep_alives` and `tls.insecure_skip_verify`."
19+
20+
# If your change doesn't affect end users or the exported elements of any package,
21+
# you should instead start your pull request title with [chore] or use the "Skip Changelog" label.
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: []

exporter/datadogexporter/config.go

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"strings"
1212

1313
"go.opentelemetry.io/collector/component"
14+
"go.opentelemetry.io/collector/config/confighttp"
1415
"go.opentelemetry.io/collector/config/confignet"
1516
"go.opentelemetry.io/collector/config/configopaque"
1617
"go.opentelemetry.io/collector/config/configretry"
@@ -390,24 +391,11 @@ type HostMetadataConfig struct {
390391
Tags []string `mapstructure:"tags"`
391392
}
392393

393-
// LimitedTLSClientSetting is a subset of TLSClientSetting, see LimitedClientConfig for more details
394-
type LimitedTLSClientSettings struct {
395-
// InsecureSkipVerify controls whether a client verifies the server's
396-
// certificate chain and host name.
397-
InsecureSkipVerify bool `mapstructure:"insecure_skip_verify"`
398-
}
399-
400-
type LimitedClientConfig struct {
401-
TLSSetting LimitedTLSClientSettings `mapstructure:"tls,omitempty"`
402-
}
403-
404394
// Config defines configuration for the Datadog exporter.
405395
type Config struct {
406-
exporterhelper.TimeoutSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct.
407-
exporterhelper.QueueSettings `mapstructure:"sending_queue"`
408-
configretry.BackOffConfig `mapstructure:"retry_on_failure"`
409-
410-
LimitedClientConfig `mapstructure:",squash"`
396+
confighttp.ClientConfig `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct.
397+
exporterhelper.QueueSettings `mapstructure:"sending_queue"`
398+
configretry.BackOffConfig `mapstructure:"retry_on_failure"`
411399

412400
TagsConfig `mapstructure:",squash"`
413401

@@ -450,6 +438,10 @@ var _ component.Config = (*Config)(nil)
450438

451439
// Validate the configuration for errors. This is required by component.Config.
452440
func (c *Config) Validate() error {
441+
if err := validateClientConfig(c.ClientConfig); err != nil {
442+
return err
443+
}
444+
453445
if c.OnlyMetadata && (!c.HostMetadata.Enabled || c.HostMetadata.HostnameSource != HostnameSourceFirstResource) {
454446
return errNoMetadata
455447
}
@@ -490,6 +482,36 @@ func (c *Config) Validate() error {
490482
return nil
491483
}
492484

485+
func validateClientConfig(cfg confighttp.ClientConfig) error {
486+
var unsupported []string
487+
if cfg.Auth != nil {
488+
unsupported = append(unsupported, "auth")
489+
}
490+
if cfg.Endpoint != "" {
491+
unsupported = append(unsupported, "endpoint")
492+
}
493+
if cfg.Compression != "" {
494+
unsupported = append(unsupported, "compression")
495+
}
496+
if cfg.ProxyURL != "" {
497+
unsupported = append(unsupported, "proxy_url")
498+
}
499+
if cfg.Headers != nil {
500+
unsupported = append(unsupported, "headers")
501+
}
502+
if cfg.HTTP2ReadIdleTimeout != 0 {
503+
unsupported = append(unsupported, "http2_read_idle_timeout")
504+
}
505+
if cfg.HTTP2PingTimeout != 0 {
506+
unsupported = append(unsupported, "http2_ping_timeout")
507+
}
508+
509+
if len(unsupported) > 0 {
510+
return fmt.Errorf("these confighttp client configs are currently not respected by Datadog exporter: %s", strings.Join(unsupported, ", "))
511+
}
512+
return nil
513+
}
514+
493515
var _ error = (*renameError)(nil)
494516

495517
// renameError is an error related to a renamed setting.

exporter/datadogexporter/config_test.go

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,25 @@ package datadogexporter
55

66
import (
77
"testing"
8+
"time"
89

910
"github.com/stretchr/testify/assert"
11+
"go.opentelemetry.io/collector/component"
12+
"go.opentelemetry.io/collector/config/configauth"
13+
"go.opentelemetry.io/collector/config/confighttp"
14+
"go.opentelemetry.io/collector/config/configopaque"
15+
"go.opentelemetry.io/collector/config/configtls"
1016
"go.opentelemetry.io/collector/confmap"
1117
)
1218

1319
func TestValidate(t *testing.T) {
20+
idleConnTimeout := 30 * time.Second
21+
maxIdleConn := 300
22+
maxIdleConnPerHost := 150
23+
maxConnPerHost := 250
24+
ty, err := component.NewType("ty")
25+
assert.NoError(t, err)
26+
auth := configauth.Authentication{AuthenticatorID: component.NewID(ty)}
1427

1528
tests := []struct {
1629
name string
@@ -94,8 +107,8 @@ func TestValidate(t *testing.T) {
94107
name: "TLS settings are valid",
95108
cfg: &Config{
96109
API: APIConfig{Key: "notnull"},
97-
LimitedClientConfig: LimitedClientConfig{
98-
TLSSetting: LimitedTLSClientSettings{
110+
ClientConfig: confighttp.ClientConfig{
111+
TLSSetting: configtls.ClientConfig{
99112
InsecureSkipVerify: true,
100113
},
101114
},
@@ -115,6 +128,40 @@ func TestValidate(t *testing.T) {
115128
Traces: TracesConfig{PeerTags: []string{"tag1", "tag2"}},
116129
},
117130
},
131+
{
132+
name: "With confighttp client configs",
133+
cfg: &Config{
134+
API: APIConfig{Key: "notnull"},
135+
ClientConfig: confighttp.ClientConfig{
136+
ReadBufferSize: 100,
137+
WriteBufferSize: 200,
138+
Timeout: 10 * time.Second,
139+
IdleConnTimeout: &idleConnTimeout,
140+
MaxIdleConns: &maxIdleConn,
141+
MaxIdleConnsPerHost: &maxIdleConnPerHost,
142+
MaxConnsPerHost: &maxConnPerHost,
143+
DisableKeepAlives: true,
144+
TLSSetting: configtls.ClientConfig{InsecureSkipVerify: true},
145+
},
146+
},
147+
},
148+
149+
{
150+
name: "unsupported confighttp client configs",
151+
cfg: &Config{
152+
API: APIConfig{Key: "notnull"},
153+
ClientConfig: confighttp.ClientConfig{
154+
Endpoint: "endpoint",
155+
Compression: "gzip",
156+
ProxyURL: "proxy",
157+
Auth: &auth,
158+
Headers: map[string]configopaque.String{"key": "val"},
159+
HTTP2ReadIdleTimeout: 250,
160+
HTTP2PingTimeout: 200,
161+
},
162+
},
163+
err: "these confighttp client configs are currently not respected by Datadog exporter: auth, endpoint, compression, proxy_url, headers, http2_read_idle_timeout, http2_ping_timeout",
164+
},
118165
}
119166
for _, testInstance := range tests {
120167
t.Run(testInstance.name, func(t *testing.T) {
@@ -129,10 +176,26 @@ func TestValidate(t *testing.T) {
129176
}
130177

131178
func TestUnmarshal(t *testing.T) {
179+
cfgWithHTTPConfigs := NewFactory().CreateDefaultConfig().(*Config)
180+
idleConnTimeout := 30 * time.Second
181+
maxIdleConn := 300
182+
maxIdleConnPerHost := 150
183+
maxConnPerHost := 250
184+
cfgWithHTTPConfigs.ReadBufferSize = 100
185+
cfgWithHTTPConfigs.WriteBufferSize = 200
186+
cfgWithHTTPConfigs.Timeout = 10 * time.Second
187+
cfgWithHTTPConfigs.MaxIdleConns = &maxIdleConn
188+
cfgWithHTTPConfigs.MaxIdleConnsPerHost = &maxIdleConnPerHost
189+
cfgWithHTTPConfigs.MaxConnsPerHost = &maxConnPerHost
190+
cfgWithHTTPConfigs.IdleConnTimeout = &idleConnTimeout
191+
cfgWithHTTPConfigs.DisableKeepAlives = true
192+
cfgWithHTTPConfigs.TLSSetting.InsecureSkipVerify = true
193+
cfgWithHTTPConfigs.warnings = nil
194+
132195
tests := []struct {
133196
name string
134197
configMap *confmap.Conf
135-
cfg Config
198+
cfg *Config
136199
err string
137200
}{
138201
{
@@ -264,6 +327,21 @@ func TestUnmarshal(t *testing.T) {
264327
}),
265328
err: "\"metrics::sums::initial_cumulative_monotonic_value\" can only be configured when \"metrics::sums::cumulative_monotonic_mode\" is set to \"to_delta\"",
266329
},
330+
{
331+
name: "unmarshall confighttp client configs",
332+
configMap: confmap.NewFromStringMap(map[string]any{
333+
"read_buffer_size": 100,
334+
"write_buffer_size": 200,
335+
"timeout": "10s",
336+
"max_idle_conns": 300,
337+
"max_idle_conns_per_host": 150,
338+
"max_conns_per_host": 250,
339+
"disable_keep_alives": true,
340+
"idle_conn_timeout": "30s",
341+
"tls": map[string]any{"insecure_skip_verify": true},
342+
}),
343+
cfg: cfgWithHTTPConfigs,
344+
},
267345
}
268346

269347
f := NewFactory()

exporter/datadogexporter/examples/collector.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,27 @@ exporters:
214214
## @param tls - boolean - optional - default: false
215215
# insecure_skip_verify: false
216216

217+
## @param read_buffer_size - integer - optional
218+
## @param write_buffer_size - integer - optional
219+
## @param timeout - duration - optional
220+
## @param max_idle_conns - integer - optional
221+
## @param max_idle_conns_per_host - integer - optional
222+
## @param max_conns_per_host - integer - optional
223+
## @param idle_conn_timeout - duration - optional
224+
## @param disable_keep_alives - boolean - optional
225+
##
226+
## Below are a subset of configs in confighttp that are respected by Datadog exporter.
227+
## See https://pkg.go.dev/go.opentelemetry.io/collector/config/confighttp for details on these configs.
228+
##
229+
# read_buffer_size: 0
230+
# write_buffer_size: 0
231+
# timeout: 15s
232+
# max_idle_conns: 100
233+
# max_idle_conns_per_host: 0
234+
# max_conns_per_host: 0
235+
# idle_conn_timeout: 0s
236+
# disable_keep_alives: false
237+
217238
## @param metrics - custom object - optional
218239
## Metric exporter specific configuration.
219240
#

exporter/datadogexporter/examples/logs.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ processors:
2323

2424
exporters:
2525
datadog:
26+
idle_conn_timeout: 10s
2627
api:
2728
site: ${env:DD_SITE}
2829
key: ${env:DD_API_KEY}

exporter/datadogexporter/factory.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes"
2020
"github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes/source"
2121
"go.opentelemetry.io/collector/component"
22+
"go.opentelemetry.io/collector/config/confighttp"
2223
"go.opentelemetry.io/collector/config/confignet"
2324
"go.opentelemetry.io/collector/config/configretry"
2425
"go.opentelemetry.io/collector/consumer"
@@ -170,18 +171,19 @@ func NewFactory() exporter.Factory {
170171
return newFactoryWithRegistry(featuregate.GlobalRegistry())
171172
}
172173

173-
func defaulttimeoutSettings() exporterhelper.TimeoutSettings {
174-
return exporterhelper.TimeoutSettings{
174+
func defaultClientConfig() confighttp.ClientConfig {
175+
// do not use NewDefaultClientConfig for backwards-compatibility
176+
return confighttp.ClientConfig{
175177
Timeout: 15 * time.Second,
176178
}
177179
}
178180

179181
// createDefaultConfig creates the default exporter configuration
180182
func (f *factory) createDefaultConfig() component.Config {
181183
return &Config{
182-
TimeoutSettings: defaulttimeoutSettings(),
183-
BackOffConfig: configretry.NewDefaultBackOffConfig(),
184-
QueueSettings: exporterhelper.NewDefaultQueueSettings(),
184+
ClientConfig: defaultClientConfig(),
185+
BackOffConfig: configretry.NewDefaultBackOffConfig(),
186+
QueueSettings: exporterhelper.NewDefaultQueueSettings(),
185187

186188
API: APIConfig{
187189
Site: "datadoghq.com",

0 commit comments

Comments
 (0)