Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[exporter/signalfxexporter] Add all HTTP client settings to the configuration #16837

Merged
merged 11 commits into from
Jan 2, 2023
16 changes: 16 additions & 0 deletions .chloggen/signalfx-exporter-http-settings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver)
component: signalfxexporter

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add all HTTP client settings to the SignalFx exporter configuration

# One or more tracking issues related to the change
issues: [16807]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:
10 changes: 9 additions & 1 deletion exporter/signalfxexporter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ The following configuration options can also be configured:
that are allowed to be used as a dimension key in addition to alphanumeric
characters. Each nonalphanumeric dimension key character that isn't in this string
will be replaced with a `_`.
- `max_connections` (default = 100): The maximum number of idle HTTP connection the exporter can keep open.
- `max_connections` (default = 100): The maximum number of idle HTTP connections the exporter can keep open. Deprecated: use `max_idle_conns` or `max_idle_conns_per_host` instead. See [HTTP settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/confighttp/README.md) for more info.
- `ingest_tls`: (no default) exposes a list of TLS settings to establish a secure connection with signafx receiver configured on another collector instance.
- `ca_file` needs to be set if the exporter's `ingest_url` is pointing to a signalfx receiver
with TLS enabled and using a self-signed certificate where its CA is not loaded in the system cert pool.
Expand Down Expand Up @@ -271,5 +271,13 @@ with detailed sample configurations [here](testdata/config.yaml).
This exporter also offers proxy support as documented
[here](https://github.com/open-telemetry/opentelemetry-collector/tree/main/exporter#proxy-support).

## Advanced Configuration

Several helper files are leveraged to provide additional capabilities automatically:

- [HTTP settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/confighttp/README.md)
- [TLS and mTLS settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/config/configtls/README.md)
- [Queuing, retry and timeout settings](https://github.com/open-telemetry/opentelemetry-collector/blob/main/exporter/exporterhelper/README.md)

[beta]:https://github.com/open-telemetry/opentelemetry-collector#beta
[contrib]:https://github.com/open-telemetry/opentelemetry-collector-releases/tree/main/distributions/otelcol-contrib
22 changes: 9 additions & 13 deletions exporter/signalfxexporter/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"net/url"
"time"

"go.opentelemetry.io/collector/config/confighttp"
"go.opentelemetry.io/collector/config/configtls"
"go.opentelemetry.io/collector/confmap"
"go.opentelemetry.io/collector/exporter/exporterhelper"
Expand All @@ -38,9 +39,9 @@ var _ confmap.Unmarshaler = (*Config)(nil)

// Config defines configuration for SignalFx exporter.
type Config struct {
exporterhelper.TimeoutSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct.
exporterhelper.QueueSettings `mapstructure:"sending_queue"`
exporterhelper.RetrySettings `mapstructure:"retry_on_failure"`
exporterhelper.QueueSettings `mapstructure:"sending_queue"`
exporterhelper.RetrySettings `mapstructure:"retry_on_failure"`
confighttp.HTTPClientSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct.

// AccessToken is the authentication token provided by SignalFx.
AccessToken string `mapstructure:"access_token"`
Expand All @@ -66,12 +67,6 @@ type Config struct {
// with TLS enabled and using a self-signed certificate where its CA is not loaded in the system cert pool.
APITLSSettings configtls.TLSClientSetting `mapstructure:"api_tls,omitempty"`

// Headers are a set of headers to be added to the HTTP request sending
// trace data. These can override pre-defined header values used by the
// exporter, eg: "User-Agent" can be set to a custom value if specified
// here.
Headers map[string]string `mapstructure:"headers"`

// Whether to log datapoints dispatched to Splunk Observability Cloud
LogDataPoints bool `mapstructure:"log_data_points"`

Expand Down Expand Up @@ -116,6 +111,7 @@ type Config struct {
NonAlphanumericDimensionChars string `mapstructure:"nonalphanumeric_dimension_chars"`

// MaxConnections is used to set a limit to the maximum idle HTTP connection the exporter can keep open.
// Deprecated: use HTTPClientSettings.MaxIdleConns or HTTPClientSettings.MaxIdleConnsPerHost instead.
MaxConnections int `mapstructure:"max_connections"`
}

Expand All @@ -134,8 +130,8 @@ func (cfg *Config) getOptionsFromConfig() (*exporterOptions, error) {
return nil, fmt.Errorf("invalid \"api_url\": %w", err)
}

if cfg.Timeout == 0 {
cfg.Timeout = 5 * time.Second
if cfg.HTTPClientSettings.Timeout == 0 {
cfg.HTTPClientSettings.Timeout = 5 * time.Second
}

metricTranslator, err := translation.NewMetricTranslator(cfg.TranslationRules, cfg.DeltaTranslationTTL)
Expand All @@ -148,7 +144,7 @@ func (cfg *Config) getOptionsFromConfig() (*exporterOptions, error) {
ingestTLSSettings: cfg.IngestTLSSettings,
apiURL: apiURL,
apiTLSSettings: cfg.APITLSSettings,
httpTimeout: cfg.Timeout,
httpTimeout: cfg.HTTPClientSettings.Timeout,
token: cfg.AccessToken,
logDataPoints: cfg.LogDataPoints,
logDimUpdate: cfg.LogDimensionUpdates,
Expand All @@ -166,7 +162,7 @@ func (cfg *Config) validateConfig() error {
` "ingest_url" and "api_url" should be explicitly set`)
}

if cfg.Timeout < 0 {
if cfg.HTTPClientSettings.Timeout < 0 {
return errors.New(`cannot have a negative "timeout"`)
}

Expand Down
18 changes: 9 additions & 9 deletions exporter/signalfxexporter/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/stretchr/testify/require"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config/confighttp"
"go.opentelemetry.io/collector/config/configopaque"
"go.opentelemetry.io/collector/confmap/confmaptest"
"go.opentelemetry.io/collector/exporter/exporterhelper"

Expand Down Expand Up @@ -61,12 +62,11 @@ func TestLoadConfig(t *testing.T) {
AccessToken: "testToken",
Realm: "us1",
MaxConnections: 70,
Headers: map[string]string{
"added-entry": "added value",
"dot.test": "test",
},
TimeoutSettings: exporterhelper.TimeoutSettings{
Timeout: 2 * time.Second,
HTTPClientSettings: confighttp.HTTPClientSettings{Timeout: 2 * time.Second,
Headers: map[string]configopaque.String{
"added-entry": "added value",
"dot.test": "test",
},
},
RetrySettings: exporterhelper.RetrySettings{
Enabled: true,
Expand Down Expand Up @@ -207,7 +207,7 @@ func TestConfig_getOptionsFromConfig(t *testing.T) {
IngestURL string
APIURL string
Timeout time.Duration
Headers map[string]string
Headers map[string]configopaque.String
TranslationRules []translation.Rule
SyncHostMetadata bool
}
Expand Down Expand Up @@ -323,10 +323,10 @@ func TestConfig_getOptionsFromConfig(t *testing.T) {
Realm: tt.fields.Realm,
IngestURL: tt.fields.IngestURL,
APIURL: tt.fields.APIURL,
TimeoutSettings: exporterhelper.TimeoutSettings{
HTTPClientSettings: confighttp.HTTPClientSettings{
Timeout: tt.fields.Timeout,
Headers: tt.fields.Headers,
},
Headers: tt.fields.Headers,
TranslationRules: tt.fields.TranslationRules,
SyncHostMetadata: tt.fields.SyncHostMetadata,
DeltaTranslationTTL: 3600,
Expand Down
21 changes: 0 additions & 21 deletions exporter/signalfxexporter/dpclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,27 +148,6 @@ func (s *sfxDPClient) pushMetricsDataForToken(ctx context.Context, sfxDataPoints
return 0, nil
}

func buildHeaders(config *Config) map[string]string {
headers := map[string]string{
"Connection": "keep-alive",
"Content-Type": "application/x-protobuf",
"User-Agent": "OpenTelemetry-Collector SignalFx Exporter/v0.0.1",
}

if config.AccessToken != "" {
headers[splunk.SFxAccessTokenHeader] = config.AccessToken
}

// Add any custom headers from the config. They will override the pre-defined
// ones above in case of conflict, but, not the content encoding one since
// the latter one is defined according to the payload.
for k, v := range config.Headers {
headers[k] = v
}

return headers
}

func (s *sfxDPClient) encodeBody(dps []*sfxpb.DataPoint) (bodyReader io.Reader, compressed bool, err error) {
msg := sfxpb.DataPointUploadMessage{
Datapoints: dps,
Expand Down
Loading