Skip to content

Commit d430156

Browse files
authored
exporter/signalfx: Remove send_compatible_metrics option (#2267)
* exporter/signalfx: Remove send_compatible_metrics option This is a **breaking change**. Remove `send_compatible_metrics` options. Instead just use the `translation_rules` field to determine whether or not compatible metrics are to be sent. If `translation_rules` is not specified, default rules will be applied and compatible metrics will be sent. Compatible metrics can be turned off by setting it to `[]`. * Update comment in custom unmarshaler
1 parent d12186a commit d430156

File tree

7 files changed

+69
-111
lines changed

7 files changed

+69
-111
lines changed

exporter/signalfxexporter/README.md

+4-6
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,9 @@ The following configuration options can also be configured:
4242
receiver](../../receiver/signalfxreceiver/README.md) to preserve datapoint
4343
origin.
4444
- `exclude_metrics`: List of metric filters that will determine metrics to be
45-
excluded from sending to Signalfx backend. If `send_compatible_metrics`
46-
or `translation_rules` options are enabled, the exclusion will be applied
47-
on translated metrics. See [here](./testdata/config.yaml) for examples.
45+
excluded from sending to Signalfx backend. If `translation_rules` options
46+
are enabled, the exclusion will be applied on translated metrics.
47+
See [here](./testdata/config.yaml) for examples.
4848
- `include_metrics`: List of filters to override exclusion of any metrics.
4949
This option can be used to included metrics that are otherwise dropped by
5050
default. See [here](./translation/default_metrics.go) for a list of metrics
@@ -62,13 +62,11 @@ The following configuration options can also be configured:
6262
- `headers` (no default): Headers to pass in the payload.
6363
- `log_dimension_updates` (default = `false`): Whether or not to log dimension
6464
updates.
65-
- `send_compatible_metrics` (default = `false`): Whether metrics must be
66-
translated to a format backward-compatible with SignalFx naming conventions.
6765
- `timeout` (default = 5s): Amount of time to wait for a send operation to
6866
complete.
6967
- `translation_rules`: Set of rules on how to translate metrics to a SignalFx
7068
compatible format. Rules defined in `translation/constants.go` are used by
71-
default. Applicable only when `send_compatible_metrics` set to `true`.
69+
default. Set this option to `[]` to override the default behavior.
7270
- `sync_host_metadata`: Defines whether the exporter should scrape host metadata
7371
and send it as property updates to SignalFx backend. Disabled by default.
7472
IMPORTANT: Host metadata synchronization relies on `resourcedetection`

exporter/signalfxexporter/config.go

+7-10
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ import (
2929
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/splunk"
3030
)
3131

32+
const (
33+
translationRulesConfigKey = "translation_rules"
34+
)
35+
3236
// Config defines configuration for SignalFx exporter.
3337
type Config struct {
3438
configmodels.ExporterSettings `mapstructure:",squash"` // squash ensures fields are correctly decoded in embedded struct.
@@ -64,10 +68,6 @@ type Config struct {
6468

6569
splunk.AccessTokenPassthroughConfig `mapstructure:",squash"`
6670

67-
// SendCompatibleMetrics specifies if metrics must be sent in a format backward-compatible with
68-
// SignalFx naming conventions, "false" by default.
69-
SendCompatibleMetrics bool `mapstructure:"send_compatible_metrics"`
70-
7171
// TranslationRules defines a set of rules how to translate metrics to a SignalFx compatible format
7272
// Rules defined in translation/constants.go are used by default.
7373
TranslationRules []translation.Rule `mapstructure:"translation_rules"`
@@ -120,12 +120,9 @@ func (cfg *Config) getOptionsFromConfig() (*exporterOptions, error) {
120120
cfg.Timeout = 5 * time.Second
121121
}
122122

123-
var metricTranslator *translation.MetricTranslator
124-
if cfg.SendCompatibleMetrics {
125-
metricTranslator, err = translation.NewMetricTranslator(cfg.TranslationRules, cfg.DeltaTranslationTTL)
126-
if err != nil {
127-
return nil, fmt.Errorf("invalid \"translation_rules\": %v", err)
128-
}
123+
metricTranslator, err := translation.NewMetricTranslator(cfg.TranslationRules, cfg.DeltaTranslationTTL)
124+
if err != nil {
125+
return nil, fmt.Errorf("invalid \"%s\": %v", translationRulesConfigKey, err)
129126
}
130127

131128
return &exporterOptions{

exporter/signalfxexporter/config_test.go

+30-22
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ func TestLoadConfig(t *testing.T) {
5454
// Realm doesn't have a default value so set it directly.
5555
defaultCfg := factory.CreateDefaultConfig().(*Config)
5656
defaultCfg.Realm = "ap0"
57+
defaultTranslationRules, err := loadDefaultTranslationRules()
58+
require.NoError(t, err)
59+
defaultCfg.TranslationRules = defaultTranslationRules
5760
assert.Equal(t, defaultCfg, e0)
5861

5962
expectedName := "signalfx/allsettings"
@@ -86,7 +89,6 @@ func TestLoadConfig(t *testing.T) {
8689
}, AccessTokenPassthroughConfig: splunk.AccessTokenPassthroughConfig{
8790
AccessTokenPassthrough: false,
8891
},
89-
SendCompatibleMetrics: true,
9092
TranslationRules: []translation.Rule{
9193
{
9294
Action: translation.ActionRenameDimensionKeys,
@@ -167,17 +169,21 @@ func TestLoadConfig(t *testing.T) {
167169
}
168170

169171
func TestConfig_getOptionsFromConfig(t *testing.T) {
172+
emptyTranslator := func() *translation.MetricTranslator {
173+
translator, err := translation.NewMetricTranslator(nil, 3600)
174+
require.NoError(t, err)
175+
return translator
176+
}
170177
type fields struct {
171-
ExporterSettings configmodels.ExporterSettings
172-
AccessToken string
173-
Realm string
174-
IngestURL string
175-
APIURL string
176-
Timeout time.Duration
177-
Headers map[string]string
178-
SendCompatibleMetrics bool
179-
TranslationRules []translation.Rule
180-
SyncHostMetadata bool
178+
ExporterSettings configmodels.ExporterSettings
179+
AccessToken string
180+
Realm string
181+
IngestURL string
182+
APIURL string
183+
Timeout time.Duration
184+
Headers map[string]string
185+
TranslationRules []translation.Rule
186+
SyncHostMetadata bool
181187
}
182188
tests := []struct {
183189
name string
@@ -204,8 +210,9 @@ func TestConfig_getOptionsFromConfig(t *testing.T) {
204210
Host: "api.us1.signalfx.com",
205211
Path: "/",
206212
},
207-
httpTimeout: 5 * time.Second,
208-
token: "access_token",
213+
httpTimeout: 5 * time.Second,
214+
token: "access_token",
215+
metricTranslator: emptyTranslator(),
209216
},
210217
wantErr: false,
211218
},
@@ -226,8 +233,9 @@ func TestConfig_getOptionsFromConfig(t *testing.T) {
226233
Scheme: "https",
227234
Host: "api.us0.signalfx.com",
228235
},
229-
httpTimeout: 10 * time.Second,
230-
token: "access_token",
236+
httpTimeout: 10 * time.Second,
237+
token: "access_token",
238+
metricTranslator: emptyTranslator(),
231239
},
232240
wantErr: false,
233241
},
@@ -270,9 +278,8 @@ func TestConfig_getOptionsFromConfig(t *testing.T) {
270278
{
271279
name: "Test invalid translation rules",
272280
fields: fields{
273-
Realm: "us0",
274-
AccessToken: "access_token",
275-
SendCompatibleMetrics: true,
281+
Realm: "us0",
282+
AccessToken: "access_token",
276283
TranslationRules: []translation.Rule{
277284
{
278285
Action: translation.ActionRenameDimensionKeys,
@@ -294,11 +301,12 @@ func TestConfig_getOptionsFromConfig(t *testing.T) {
294301
TimeoutSettings: exporterhelper.TimeoutSettings{
295302
Timeout: tt.fields.Timeout,
296303
},
297-
Headers: tt.fields.Headers,
298-
SendCompatibleMetrics: tt.fields.SendCompatibleMetrics,
299-
TranslationRules: tt.fields.TranslationRules,
300-
SyncHostMetadata: tt.fields.SyncHostMetadata,
304+
Headers: tt.fields.Headers,
305+
TranslationRules: tt.fields.TranslationRules,
306+
SyncHostMetadata: tt.fields.SyncHostMetadata,
307+
DeltaTranslationTTL: 3600,
301308
}
309+
302310
got, err := cfg.getOptionsFromConfig()
303311
if (err != nil) != tt.wantErr {
304312
t.Errorf("getOptionsFromConfig() error = %v, wantErr %v", err, tt.wantErr)

exporter/signalfxexporter/factory.go

+26-20
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"strings"
2222
"time"
2323

24+
"github.com/spf13/viper"
2425
"go.opentelemetry.io/collector/component"
2526
otelconfig "go.opentelemetry.io/collector/config"
2627
"go.opentelemetry.io/collector/config/configmodels"
@@ -49,6 +50,7 @@ func NewFactory() component.ExporterFactory {
4950
exporterhelper.WithMetrics(createMetricsExporter),
5051
exporterhelper.WithLogs(createLogsExporter),
5152
exporterhelper.WithTraces(createTraceExporter),
53+
exporterhelper.WithCustomUnmarshaler(customUnmarshaler),
5254
)
5355
}
5456

@@ -64,13 +66,32 @@ func createDefaultConfig() configmodels.Exporter {
6466
AccessTokenPassthroughConfig: splunk.AccessTokenPassthroughConfig{
6567
AccessTokenPassthrough: true,
6668
},
67-
SendCompatibleMetrics: false,
68-
TranslationRules: nil,
69-
DeltaTranslationTTL: 3600,
70-
Correlation: correlation.DefaultConfig(),
69+
DeltaTranslationTTL: 3600,
70+
Correlation: correlation.DefaultConfig(),
7171
}
7272
}
7373

74+
func customUnmarshaler(componentViperSection *viper.Viper, intoCfg interface{}) (err error) {
75+
if componentViperSection == nil {
76+
// Nothing to do if there is no config given.
77+
return nil
78+
}
79+
80+
if err = componentViperSection.Unmarshal(intoCfg); err != nil {
81+
return err
82+
}
83+
84+
config := intoCfg.(*Config)
85+
86+
// If translations_config is not set in the config, set it to the defaults and return.
87+
if !componentViperSection.IsSet(translationRulesConfigKey) {
88+
config.TranslationRules, err = loadDefaultTranslationRules()
89+
return err
90+
}
91+
92+
return nil
93+
}
94+
7495
func createTraceExporter(
7596
_ context.Context,
7697
params component.ExporterCreateParams,
@@ -106,12 +127,8 @@ func createMetricsExporter(
106127
) (component.MetricsExporter, error) {
107128

108129
expCfg := config.(*Config)
109-
err := setTranslationRules(expCfg)
110-
if err != nil {
111-
return nil, err
112-
}
113130

114-
err = setDefaultExcludes(expCfg)
131+
err := setDefaultExcludes(expCfg)
115132
if err != nil {
116133
return nil, err
117134
}
@@ -149,17 +166,6 @@ func createMetricsExporter(
149166
}, nil
150167
}
151168

152-
func setTranslationRules(cfg *Config) error {
153-
if cfg.SendCompatibleMetrics && cfg.TranslationRules == nil {
154-
defaultRules, err := loadDefaultTranslationRules()
155-
if err != nil {
156-
return err
157-
}
158-
cfg.TranslationRules = defaultRules
159-
}
160-
return nil
161-
}
162-
163169
func loadDefaultTranslationRules() ([]translation.Rule, error) {
164170
config := Config{}
165171

exporter/signalfxexporter/factory_test.go

-52
Original file line numberDiff line numberDiff line change
@@ -185,58 +185,6 @@ func TestFactory_CreateMetricsExporterFails(t *testing.T) {
185185
}
186186
}
187187

188-
func TestCreateMetricsExporterWithDefaultTranslationRules(t *testing.T) {
189-
config := &Config{
190-
ExporterSettings: configmodels.ExporterSettings{
191-
TypeVal: configmodels.Type(typeStr),
192-
NameVal: typeStr,
193-
},
194-
AccessToken: "testToken",
195-
Realm: "us1",
196-
SendCompatibleMetrics: true,
197-
}
198-
199-
te, err := createMetricsExporter(context.Background(), component.ExporterCreateParams{Logger: zap.NewNop()}, config)
200-
assert.NoError(t, err)
201-
assert.NotNil(t, te)
202-
203-
// Validate that default translation rules are loaded
204-
// Expected values has to be updated once default config changed
205-
assert.Equal(t, 64, len(config.TranslationRules))
206-
assert.Equal(t, translation.ActionRenameDimensionKeys, config.TranslationRules[0].Action)
207-
assert.Equal(t, 33, len(config.TranslationRules[0].Mapping))
208-
}
209-
210-
func TestCreateMetricsExporterWithSpecifiedTranslaitonRules(t *testing.T) {
211-
config := &Config{
212-
ExporterSettings: configmodels.ExporterSettings{
213-
TypeVal: configmodels.Type(typeStr),
214-
NameVal: typeStr,
215-
},
216-
AccessToken: "testToken",
217-
Realm: "us1",
218-
SendCompatibleMetrics: true,
219-
TranslationRules: []translation.Rule{
220-
{
221-
Action: translation.ActionRenameDimensionKeys,
222-
Mapping: map[string]string{
223-
"old_dimension": "new_dimension",
224-
},
225-
},
226-
},
227-
}
228-
229-
te, err := createMetricsExporter(context.Background(), component.ExporterCreateParams{Logger: zap.NewNop()}, config)
230-
assert.NoError(t, err)
231-
assert.NotNil(t, te)
232-
233-
// Validate that specified translation rules are loaded instead of default ones
234-
assert.Equal(t, 1, len(config.TranslationRules))
235-
assert.Equal(t, translation.ActionRenameDimensionKeys, config.TranslationRules[0].Action)
236-
assert.Equal(t, 1, len(config.TranslationRules[0].Mapping))
237-
assert.Equal(t, "new_dimension", config.TranslationRules[0].Mapping["old_dimension"])
238-
}
239-
240188
func TestDefaultTranslationRules(t *testing.T) {
241189
rules, err := loadDefaultTranslationRules()
242190
require.NoError(t, err)

exporter/signalfxexporter/go.mod

+2
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ require (
1212
github.com/shirou/gopsutil v3.21.1+incompatible
1313
github.com/signalfx/com_signalfx_metrics_protobuf v0.0.2
1414
github.com/signalfx/signalfx-agent/pkg/apm v0.0.0-20201202163743-65b4fa925fc8
15+
github.com/spf13/viper v1.7.1
1516
github.com/stretchr/testify v1.7.0
1617
go.opentelemetry.io/collector v0.19.1-0.20210127225953-68c5961f7bc2
1718
go.uber.org/multierr v1.6.0 // indirect
1819
go.uber.org/zap v1.16.0
1920
google.golang.org/protobuf v1.25.0
21+
gopkg.in/yaml.v2 v2.4.0
2022
)
2123

2224
replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/common => ../../internal/common

exporter/signalfxexporter/testdata/config.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ exporters:
2424
added-entry: "added value"
2525
dot.test: test
2626
access_token_passthrough: false
27-
send_compatible_metrics: true
2827
translation_rules:
2928
- action: rename_dimension_keys
3029
mapping:

0 commit comments

Comments
 (0)