From 57ae016825f081cab7e1049445ffa303285234ff Mon Sep 17 00:00:00 2001 From: jeremyh Date: Mon, 8 Jul 2024 14:29:19 -0400 Subject: [PATCH 1/7] config function and testing --- connector/sumconnector/config.go | 95 +++++ connector/sumconnector/config_test.go | 450 ++++++++++++++++++++ connector/sumconnector/testdata/config.yaml | 185 ++++++++ 3 files changed, 730 insertions(+) create mode 100644 connector/sumconnector/config_test.go create mode 100644 connector/sumconnector/testdata/config.yaml diff --git a/connector/sumconnector/config.go b/connector/sumconnector/config.go index 1aba734793d5..c65eb665e565 100644 --- a/connector/sumconnector/config.go +++ b/connector/sumconnector/config.go @@ -3,6 +3,16 @@ package sumconnector // import "github.com/open-telemetry/opentelemetry-collector-contrib/connector/sumconnector" +import ( + "fmt" + "go.opentelemetry.io/collector/component" + + "go.uber.org/zap" + + "github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter/filterottl" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl" +) + // Config for the connector type Config struct { Spans map[string]MetricInfo `mapstructure:"spans"` @@ -24,3 +34,88 @@ type AttributeConfig struct { Key string `mapstructure:"key"` DefaultValue any `mapstructure:"default_value"` } + +func (c *Config) Validate() error { + for name, info := range c.Spans { + if name == "" { + return fmt.Errorf("spans: metric name missing") + } + if _, err := filterottl.NewBoolExprForSpan(info.Conditions, filterottl.StandardSpanFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { + return fmt.Errorf("spans condition: metric %q: %w", name, err) + } + if err := info.validateAttributes(); err != nil { + return fmt.Errorf("spans attributes: metric %q: %w", name, err) + } + if info.SourceAttribute == "" { + return fmt.Errorf("spans: metric source attribute missing") + } + } + for name, info := range c.SpanEvents { + if name == "" { + return fmt.Errorf("spanevents: metric name missing") + } + if _, err := filterottl.NewBoolExprForSpanEvent(info.Conditions, filterottl.StandardSpanEventFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { + return fmt.Errorf("spanevents condition: metric %q: %w", name, err) + } + if err := info.validateAttributes(); err != nil { + return fmt.Errorf("spanevents attributes: metric %q: %w", name, err) + } + if info.SourceAttribute == "" { + return fmt.Errorf("spanevents: metric source attribute missing") + } + } + for name, info := range c.Metrics { + if name == "" { + return fmt.Errorf("metrics: metric name missing") + } + if _, err := filterottl.NewBoolExprForMetric(info.Conditions, filterottl.StandardMetricFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { + return fmt.Errorf("metrics condition: metric %q: %w", name, err) + } + if len(info.Attributes) > 0 { + return fmt.Errorf("metrics attributes not supported: metric %q", name) + } + if info.SourceAttribute == "" { + return fmt.Errorf("metrics: metric source attribute missing") + } + } + for name, info := range c.DataPoints { + if name == "" { + return fmt.Errorf("datapoints: metric name missing") + } + if _, err := filterottl.NewBoolExprForDataPoint(info.Conditions, filterottl.StandardDataPointFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { + return fmt.Errorf("datapoints condition: metric %q: %w", name, err) + } + if err := info.validateAttributes(); err != nil { + return fmt.Errorf("spans attributes: metric %q: %w", name, err) + } + if info.SourceAttribute == "" { + return fmt.Errorf("datapoints: metric source attribute missing") + } + } + for name, info := range c.Logs { + if name == "" { + return fmt.Errorf("logs: metric name missing") + } + if _, err := filterottl.NewBoolExprForLog(info.Conditions, filterottl.StandardLogFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { + return fmt.Errorf("logs condition: metric %q: %w", name, err) + } + if err := info.validateAttributes(); err != nil { + return fmt.Errorf("logs attributes: metric %q: %w", name, err) + } + if info.SourceAttribute == "" { + return fmt.Errorf("logs: metric source attribute missing") + } + } + return nil +} + +func (i *MetricInfo) validateAttributes() error { + for _, attr := range i.Attributes { + if attr.Key == "" { + return fmt.Errorf("attribute key missing") + } + } + return nil +} + +var _ component.ConfigValidator = (*Config)(nil) \ No newline at end of file diff --git a/connector/sumconnector/config_test.go b/connector/sumconnector/config_test.go new file mode 100644 index 000000000000..f37697742805 --- /dev/null +++ b/connector/sumconnector/config_test.go @@ -0,0 +1,450 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package sumconnector + +import ( + "fmt" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/confmap/confmaptest" + + "github.com/open-telemetry/opentelemetry-collector-contrib/connector/sumconnector/internal/metadata" +) + +func TestLoadConfig(t *testing.T) { + testCases := []struct { + name string + expect *Config + }{ + { + name: "custom_description", + expect: &Config{ + Spans: map[string]MetricInfo{ + "my.span.sum": { + Description: "My span record sum.", + SourceAttribute: "my.attribute", + }, + }, + SpanEvents: map[string]MetricInfo{ + "my.spanevent.sum": { + Description: "My spanevent sum.", + SourceAttribute: "my.attribute", + }, + }, + Metrics: map[string]MetricInfo{ + "my.metric.sum": { + Description: "My metric sum.", + SourceAttribute: "my.attribute", + }, + }, + DataPoints: map[string]MetricInfo{ + "my.datapoint.sum": { + Description: "My datapoint sum.", + SourceAttribute: "my.attribute", + }, + }, + Logs: map[string]MetricInfo{ + "my.logrecord.sum": { + Description: "My log sum.", + SourceAttribute: "my.attribute", + }, + }, + }, + }, + { + name: "custom_metric", + expect: &Config{ + Spans: map[string]MetricInfo{ + "my.span.sum": { + Description: "My span sum.", + }, + }, + SpanEvents: map[string]MetricInfo{ + "my.spanevent.sum": { + Description: "My span event sum.", + }, + }, + Metrics: map[string]MetricInfo{ + "my.metric.sum": { + Description: "My metric sum.", + }, + }, + DataPoints: map[string]MetricInfo{ + "my.datapoint.sum": { + Description: "My data point sum.", + }, + }, + Logs: map[string]MetricInfo{ + "my.logrecord.sum": { + Description: "My log record sum.", + }, + }, + }, + }, + { + name: "condition", + expect: &Config{ + Spans: map[string]MetricInfo{ + "my.span.sum": { + Description: "My span sum.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s")`}, + }, + }, + SpanEvents: map[string]MetricInfo{ + "my.spanevent.sum": { + Description: "My span event sum.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e")`}, + }, + }, + Metrics: map[string]MetricInfo{ + "my.metric.sum": { + Description: "My metric sum.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-m")`}, + }, + }, + DataPoints: map[string]MetricInfo{ + "my.datapoint.sum": { + Description: "My data point sum.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d")`}, + }, + }, + Logs: map[string]MetricInfo{ + "my.logrecord.sum": { + Description: "My log record sum.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l")`}, + }, + }, + }, + }, + { + name: "multiple_condition", + expect: &Config{ + Spans: map[string]MetricInfo{ + "my.span.sum": { + Description: "My span sum.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-s")`, + `IsMatch(resource.attributes["foo"], "bar-s")`, + }, + }, + }, + SpanEvents: map[string]MetricInfo{ + "my.spanevent.sum": { + Description: "My span event sum.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-e")`, + `IsMatch(resource.attributes["foo"], "bar-e")`, + }, + }, + }, + Metrics: map[string]MetricInfo{ + "my.metric.sum": { + Description: "My metric sum.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-m")`, + `IsMatch(resource.attributes["foo"], "bar-m")`, + }, + }, + }, + DataPoints: map[string]MetricInfo{ + "my.datapoint.sum": { + Description: "My data point sum.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-d")`, + `IsMatch(resource.attributes["foo"], "bar-d")`, + }, + }, + }, + Logs: map[string]MetricInfo{ + "my.logrecord.sum": { + Description: "My log record sum.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-l")`, + `IsMatch(resource.attributes["foo"], "bar-l")`, + }, + }, + }, + }, + }, + { + name: "attribute", + expect: &Config{ + Spans: map[string]MetricInfo{ + "my.span.sum": { + Description: "My span sum by environment.", + Attributes: []AttributeConfig{ + {Key: "env"}, + }, + }, + }, + SpanEvents: map[string]MetricInfo{ + "my.spanevent.sum": { + Description: "My span event sum by environment.", + Attributes: []AttributeConfig{ + {Key: "env"}, + }, + }, + }, + Metrics: map[string]MetricInfo{ + "my.metric.sum": { + Description: "My metric sum.", + }, + }, + DataPoints: map[string]MetricInfo{ + "my.datapoint.sum": { + Description: "My data point sum by environment.", + Attributes: []AttributeConfig{ + {Key: "env"}, + }, + }, + }, + Logs: map[string]MetricInfo{ + "my.logrecord.sum": { + Description: "My log record sum by environment.", + Attributes: []AttributeConfig{ + {Key: "env"}, + }, + }, + }, + }, + }, + { + name: "multiple_metrics", + expect: &Config{ + Spans: map[string]MetricInfo{ + "my.span.sum": { + Description: "My span sum.", + }, + "limited.span.sum": { + Description: "Limited span sum.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s")`}, + Attributes: []AttributeConfig{ + { + Key: "env", + }, + { + Key: "component", + DefaultValue: "other", + }, + }, + }, + }, + SpanEvents: map[string]MetricInfo{ + "my.spanevent.sum": { + Description: "My span event sum.", + }, + "limited.spanevent.sum": { + Description: "Limited span event sum.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e")`}, + Attributes: []AttributeConfig{ + { + Key: "env", + }, + { + Key: "component", + DefaultValue: "other", + }, + }, + }, + }, + Metrics: map[string]MetricInfo{ + "my.metric.sum": { + Description: "My metric sum."}, + "limited.metric.sum": { + Description: "Limited metric sum.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-m")`}, + }, + }, + DataPoints: map[string]MetricInfo{ + "my.datapoint.sum": { + Description: "My data point sum.", + }, + "limited.datapoint.sum": { + Description: "Limited data point sum.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d")`}, + Attributes: []AttributeConfig{ + { + Key: "env", + }, + { + Key: "component", + DefaultValue: "other", + }, + }, + }, + }, + Logs: map[string]MetricInfo{ + "my.logrecord.sum": { + Description: "My log record sum.", + }, + "limited.logrecord.sum": { + Description: "Limited log record sum.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l")`}, + Attributes: []AttributeConfig{ + { + Key: "env", + }, + { + Key: "component", + DefaultValue: "other", + }, + }, + }, + }, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + cm, err := confmaptest.LoadConf(filepath.Join("testdata", "config.yaml")) + require.NoError(t, err) + + factory := NewFactory() + cfg := factory.CreateDefaultConfig() + + sub, err := cm.Sub(component.NewIDWithName(metadata.Type, tc.name).String()) + require.NoError(t, err) + require.NoError(t, sub.Unmarshal(cfg)) + + assert.Equal(t, tc.expect, cfg) + }) + } +} + +func TestConfigErrors(t *testing.T) { + testCases := []struct { + name string + input *Config + expect string + }{ + { + name: "missing_metric_name_span", + input: &Config{ + Spans: map[string]MetricInfo{ + "": { + SourceAttribute: "my.attribute", + }, + }, + }, + expect: "spans: metric name missing", + }, + { + name: "missing_metric_name_spanevent", + input: &Config{ + SpanEvents: map[string]MetricInfo{ + "": { + SourceAttribute: "my.attribute", + }, + }, + }, + expect: "spanevents: metric name missing", + }, + { + name: "missing_metric_name_metric", + input: &Config{ + Metrics: map[string]MetricInfo{ + "": { + SourceAttribute: "my.attribute", + }, + }, + }, + expect: "metrics: metric name missing", + }, + { + name: "missing_metric_name_datapoint", + input: &Config{ + DataPoints: map[string]MetricInfo{ + "": { + SourceAttribute: "my.attribute", + }, + }, + }, + expect: "datapoints: metric name missing", + }, + { + name: "missing_metric_name_log", + input: &Config{ + Logs: map[string]MetricInfo{ + "": { + SourceAttribute: "my.attribute", + }, + }, + }, + expect: "logs: metric name missing", + }, + { + name: "invalid_condition_span", + input: &Config{ + Spans: map[string]MetricInfo{ + "metric.name.spans": { + SourceAttribute: "my.attribute", + Conditions: []string{"invalid condition"}, + }, + }, + }, + expect: fmt.Sprintf("spans condition: metric %q: unable to parse OTTL condition", "metric.name.spans"), + }, + { + name: "invalid_condition_spanevent", + input: &Config{ + SpanEvents: map[string]MetricInfo{ + "metric.name.spanevents": { + SourceAttribute: "my.attribute", + Conditions: []string{"invalid condition"}, + }, + }, + }, + expect: fmt.Sprintf("spanevents condition: metric %q: unable to parse OTTL condition", "metric.name.spanevents"), + }, + { + name: "invalid_condition_metric", + input: &Config{ + Metrics: map[string]MetricInfo{ + "metric.name.metrics": { + SourceAttribute: "my.attribute", + Conditions: []string{"invalid condition"}, + }, + }, + }, + expect: fmt.Sprintf("metrics condition: metric %q: unable to parse OTTL condition", "metric.name.metrics"), + }, + { + name: "invalid_condition_datapoint", + input: &Config{ + DataPoints: map[string]MetricInfo{ + "metric.name.datapoints": { + SourceAttribute: "my.attribute", + Conditions: []string{"invalid condition"}, + }, + }, + }, + expect: fmt.Sprintf("datapoints condition: metric %q: unable to parse OTTL condition", "metric.name.datapoints"), + }, + { + name: "invalid_condition_log", + input: &Config{ + Logs: map[string]MetricInfo{ + "metric.name.logs": { + SourceAttribute: "my.attribute", + Conditions: []string{"invalid condition"}, + }, + }, + }, + expect: fmt.Sprintf("logs condition: metric %q: unable to parse OTTL condition", "metric.name.logs"), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := tc.input.Validate() + assert.Error(t, err) + assert.Contains(t, err.Error(), tc.expect) + }) + } +} diff --git a/connector/sumconnector/testdata/config.yaml b/connector/sumconnector/testdata/config.yaml new file mode 100644 index 000000000000..539ef547b3fd --- /dev/null +++ b/connector/sumconnector/testdata/config.yaml @@ -0,0 +1,185 @@ + sum: + sum/custom_description: + spans: + my.span.sum: + description: My span record sum. + source_attribute: my.attribute + spanevents: + my.spanevent.sum: + description: My spanevent sum. + source_attribute: my.attribute + metrics: + my.metric.sum: + description: My metric sum. + source_attribute: my.attribute + datapoints: + my.datapoint.sum: + description: My datapoint sum. + source_attribute: my.attribute + logs: + my.logrecord.sum: + description: My log sum. + source_attribute: my.attribute + sum/custom_metric: + spans: + my.span.sum: + description: My span sum. + spanevents: + my.spanevent.sum: + description: My span event sum. + metrics: + my.metric.sum: + description: My metric sum. + datapoints: + my.datapoint.sum: + description: My data point sum. + logs: + my.logrecord.sum: + description: My log record sum. + sum/condition: + spans: + my.span.sum: + description: My span sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-s") + spanevents: + my.spanevent.sum: + description: My span event sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-e") + metrics: + my.metric.sum: + description: My metric sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-m") + datapoints: + my.datapoint.sum: + description: My data point sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-d") + logs: + my.logrecord.sum: + description: My log record sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-l") + sum/multiple_condition: + spans: + my.span.sum: + description: My span sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-s") + - IsMatch(resource.attributes["foo"], "bar-s") + spanevents: + my.spanevent.sum: + description: My span event sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-e") + - IsMatch(resource.attributes["foo"], "bar-e") + metrics: + my.metric.sum: + description: My metric sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-m") + - IsMatch(resource.attributes["foo"], "bar-m") + datapoints: + my.datapoint.sum: + description: My data point sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-d") + - IsMatch(resource.attributes["foo"], "bar-d") + logs: + my.logrecord.sum: + description: My log record sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-l") + - IsMatch(resource.attributes["foo"], "bar-l") + sum/attribute: + spans: + my.span.sum: + description: My span sum by environment. + attributes: + - key: env + spanevents: + my.spanevent.sum: + description: My span event sum by environment. + attributes: + - key: env + metrics: + my.metric.sum: + description: My metric sum. + # Metrics do not have attributes. + datapoints: + my.datapoint.sum: + description: My data point sum by environment. + attributes: + - key: env + logs: + my.logrecord.sum: + description: My log record sum by environment. + attributes: + - key: env + sum/multiple_metrics: + spans: + my.span.sum: + description: My span sum. + limited.span.sum: + description: Limited span sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-s") + attributes: + - key: env + - key: component + default_value: other + spanevents: + my.spanevent.sum: + description: My span event sum. + limited.spanevent.sum: + description: Limited span event sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-e") + attributes: + - key: env + - key: component + default_value: other + metrics: + my.metric.sum: + description: My metric sum. + limited.metric.sum: + description: Limited metric sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-m") + datapoints: + my.datapoint.sum: + description: My data point sum. + limited.datapoint.sum: + description: Limited data point sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-d") + attributes: + - key: env + - key: component + default_value: other + logs: + my.logrecord.sum: + description: My log record sum. + limited.logrecord.sum: + description: Limited log record sum. + conditions: + - IsMatch(resource.attributes["host.name"], "pod-l") + attributes: + - key: env + - key: component + default_value: other + sum/default_values: + logs: + my.logrecord.sum: + description: My log record sum with default values. + limited.logrecord.sum: + description: Limited log record sum. + attributes: + - key: env + default_value: "local" + - key: http_code + default_value: 200 + - key: request_success + default_value: 0.85 \ No newline at end of file From d0ef23d50b4676cc55bfc4a4e287807ec7cec0aa Mon Sep 17 00:00:00 2001 From: jeremyh Date: Tue, 9 Jul 2024 11:39:19 -0400 Subject: [PATCH 2/7] additional config and config test tweaks --- connector/sumconnector/config.go | 14 +-- connector/sumconnector/config_test.go | 113 +++++++++++++++----- connector/sumconnector/factory.go | 12 ++- connector/sumconnector/go.mod | 2 +- connector/sumconnector/testdata/config.yaml | 65 ++++++----- 5 files changed, 135 insertions(+), 71 deletions(-) diff --git a/connector/sumconnector/config.go b/connector/sumconnector/config.go index c65eb665e565..fd0239075a3a 100644 --- a/connector/sumconnector/config.go +++ b/connector/sumconnector/config.go @@ -5,8 +5,8 @@ package sumconnector // import "github.com/open-telemetry/opentelemetry-collecto import ( "fmt" + "go.opentelemetry.io/collector/component" - "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter/filterottl" @@ -47,7 +47,7 @@ func (c *Config) Validate() error { return fmt.Errorf("spans attributes: metric %q: %w", name, err) } if info.SourceAttribute == "" { - return fmt.Errorf("spans: metric source attribute missing") + return fmt.Errorf("spans: metric source_attribute missing") } } for name, info := range c.SpanEvents { @@ -61,7 +61,7 @@ func (c *Config) Validate() error { return fmt.Errorf("spanevents attributes: metric %q: %w", name, err) } if info.SourceAttribute == "" { - return fmt.Errorf("spanevents: metric source attribute missing") + return fmt.Errorf("spanevents: metric source_attribute missing") } } for name, info := range c.Metrics { @@ -75,7 +75,7 @@ func (c *Config) Validate() error { return fmt.Errorf("metrics attributes not supported: metric %q", name) } if info.SourceAttribute == "" { - return fmt.Errorf("metrics: metric source attribute missing") + return fmt.Errorf("metrics: metric source_attribute missing") } } for name, info := range c.DataPoints { @@ -89,7 +89,7 @@ func (c *Config) Validate() error { return fmt.Errorf("spans attributes: metric %q: %w", name, err) } if info.SourceAttribute == "" { - return fmt.Errorf("datapoints: metric source attribute missing") + return fmt.Errorf("datapoints: metric source_attribute missing") } } for name, info := range c.Logs { @@ -103,7 +103,7 @@ func (c *Config) Validate() error { return fmt.Errorf("logs attributes: metric %q: %w", name, err) } if info.SourceAttribute == "" { - return fmt.Errorf("logs: metric source attribute missing") + return fmt.Errorf("logs: metric source_attribute missing") } } return nil @@ -118,4 +118,4 @@ func (i *MetricInfo) validateAttributes() error { return nil } -var _ component.ConfigValidator = (*Config)(nil) \ No newline at end of file +var _ component.ConfigValidator = (*Config)(nil) diff --git a/connector/sumconnector/config_test.go b/connector/sumconnector/config_test.go index f37697742805..7f117b7fa30b 100644 --- a/connector/sumconnector/config_test.go +++ b/connector/sumconnector/config_test.go @@ -61,27 +61,27 @@ func TestLoadConfig(t *testing.T) { expect: &Config{ Spans: map[string]MetricInfo{ "my.span.sum": { - Description: "My span sum.", + SourceAttribute: "my.attribute", }, }, SpanEvents: map[string]MetricInfo{ "my.spanevent.sum": { - Description: "My span event sum.", + SourceAttribute: "my.attribute", }, }, Metrics: map[string]MetricInfo{ "my.metric.sum": { - Description: "My metric sum.", + SourceAttribute: "my.attribute", }, }, DataPoints: map[string]MetricInfo{ "my.datapoint.sum": { - Description: "My data point sum.", + SourceAttribute: "my.attribute", }, }, Logs: map[string]MetricInfo{ "my.logrecord.sum": { - Description: "My log record sum.", + SourceAttribute: "my.attribute", }, }, }, @@ -91,32 +91,32 @@ func TestLoadConfig(t *testing.T) { expect: &Config{ Spans: map[string]MetricInfo{ "my.span.sum": { - Description: "My span sum.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s")`}, + SourceAttribute: "my.attribute", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s")`}, }, }, SpanEvents: map[string]MetricInfo{ "my.spanevent.sum": { - Description: "My span event sum.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e")`}, + SourceAttribute: "my.attribute", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e")`}, }, }, Metrics: map[string]MetricInfo{ "my.metric.sum": { - Description: "My metric sum.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-m")`}, + SourceAttribute: "my.attribute", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-m")`}, }, }, DataPoints: map[string]MetricInfo{ "my.datapoint.sum": { - Description: "My data point sum.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d")`}, + SourceAttribute: "my.attribute", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d")`}, }, }, Logs: map[string]MetricInfo{ "my.logrecord.sum": { - Description: "My log record sum.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l")`}, + SourceAttribute: "my.attribute", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l")`}, }, }, }, @@ -126,7 +126,7 @@ func TestLoadConfig(t *testing.T) { expect: &Config{ Spans: map[string]MetricInfo{ "my.span.sum": { - Description: "My span sum.", + SourceAttribute: "my.attribute", Conditions: []string{ `IsMatch(resource.attributes["host.name"], "pod-s")`, `IsMatch(resource.attributes["foo"], "bar-s")`, @@ -135,7 +135,7 @@ func TestLoadConfig(t *testing.T) { }, SpanEvents: map[string]MetricInfo{ "my.spanevent.sum": { - Description: "My span event sum.", + SourceAttribute: "my.attribute", Conditions: []string{ `IsMatch(resource.attributes["host.name"], "pod-e")`, `IsMatch(resource.attributes["foo"], "bar-e")`, @@ -144,7 +144,7 @@ func TestLoadConfig(t *testing.T) { }, Metrics: map[string]MetricInfo{ "my.metric.sum": { - Description: "My metric sum.", + SourceAttribute: "my.attribute", Conditions: []string{ `IsMatch(resource.attributes["host.name"], "pod-m")`, `IsMatch(resource.attributes["foo"], "bar-m")`, @@ -153,7 +153,7 @@ func TestLoadConfig(t *testing.T) { }, DataPoints: map[string]MetricInfo{ "my.datapoint.sum": { - Description: "My data point sum.", + SourceAttribute: "my.attribute", Conditions: []string{ `IsMatch(resource.attributes["host.name"], "pod-d")`, `IsMatch(resource.attributes["foo"], "bar-d")`, @@ -162,7 +162,7 @@ func TestLoadConfig(t *testing.T) { }, Logs: map[string]MetricInfo{ "my.logrecord.sum": { - Description: "My log record sum.", + SourceAttribute: "my.attribute", Conditions: []string{ `IsMatch(resource.attributes["host.name"], "pod-l")`, `IsMatch(resource.attributes["foo"], "bar-l")`, @@ -176,7 +176,7 @@ func TestLoadConfig(t *testing.T) { expect: &Config{ Spans: map[string]MetricInfo{ "my.span.sum": { - Description: "My span sum by environment.", + SourceAttribute: "my.attribute", Attributes: []AttributeConfig{ {Key: "env"}, }, @@ -184,7 +184,7 @@ func TestLoadConfig(t *testing.T) { }, SpanEvents: map[string]MetricInfo{ "my.spanevent.sum": { - Description: "My span event sum by environment.", + SourceAttribute: "my.attribute", Attributes: []AttributeConfig{ {Key: "env"}, }, @@ -192,12 +192,12 @@ func TestLoadConfig(t *testing.T) { }, Metrics: map[string]MetricInfo{ "my.metric.sum": { - Description: "My metric sum.", + SourceAttribute: "my.attribute", }, }, DataPoints: map[string]MetricInfo{ "my.datapoint.sum": { - Description: "My data point sum by environment.", + SourceAttribute: "my.attribute", Attributes: []AttributeConfig{ {Key: "env"}, }, @@ -205,7 +205,7 @@ func TestLoadConfig(t *testing.T) { }, Logs: map[string]MetricInfo{ "my.logrecord.sum": { - Description: "My log record sum by environment.", + SourceAttribute: "my.attribute", Attributes: []AttributeConfig{ {Key: "env"}, }, @@ -219,9 +219,11 @@ func TestLoadConfig(t *testing.T) { Spans: map[string]MetricInfo{ "my.span.sum": { Description: "My span sum.", + SourceAttribute: "my.attribute", }, "limited.span.sum": { Description: "Limited span sum.", + SourceAttribute: "my.attribute", Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s")`}, Attributes: []AttributeConfig{ { @@ -237,9 +239,11 @@ func TestLoadConfig(t *testing.T) { SpanEvents: map[string]MetricInfo{ "my.spanevent.sum": { Description: "My span event sum.", + SourceAttribute: "my.attribute", }, "limited.spanevent.sum": { Description: "Limited span event sum.", + SourceAttribute: "my.attribute", Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e")`}, Attributes: []AttributeConfig{ { @@ -254,18 +258,23 @@ func TestLoadConfig(t *testing.T) { }, Metrics: map[string]MetricInfo{ "my.metric.sum": { - Description: "My metric sum."}, + Description: "My metric sum.", + SourceAttribute: "my.attribute", + }, "limited.metric.sum": { Description: "Limited metric sum.", + SourceAttribute: "my.attribute", Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-m")`}, }, }, DataPoints: map[string]MetricInfo{ "my.datapoint.sum": { Description: "My data point sum.", + SourceAttribute: "my.attribute", }, "limited.datapoint.sum": { Description: "Limited data point sum.", + SourceAttribute: "my.attribute", Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d")`}, Attributes: []AttributeConfig{ { @@ -281,9 +290,11 @@ func TestLoadConfig(t *testing.T) { Logs: map[string]MetricInfo{ "my.logrecord.sum": { Description: "My log record sum.", + SourceAttribute: "my.attribute", }, "limited.logrecord.sum": { Description: "Limited log record sum.", + SourceAttribute: "my.attribute", Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l")`}, Attributes: []AttributeConfig{ { @@ -323,6 +334,56 @@ func TestConfigErrors(t *testing.T) { input *Config expect string }{ + { + name: "missing_source_attribute_span", + input: &Config{ + Spans: map[string]MetricInfo{ + "span.missing.source.attribute": { + }, + }, + }, + expect: "spans: metric source_attribute missing", + }, + { + name: "missing_source_attribute_spanevent", + input: &Config{ + SpanEvents: map[string]MetricInfo{ + "spanevent.missing.source.attribute": { + }, + }, + }, + expect: "spanevents: metric source_attribute missing", + }, + { + name: "missing_source_attribute_metric", + input: &Config{ + Metrics: map[string]MetricInfo{ + "metric.missing.source.attribute": { + }, + }, + }, + expect: "metrics: metric source_attribute missing", + }, + { + name: "missing_source_attribute_datapoint", + input: &Config{ + DataPoints: map[string]MetricInfo{ + "datapoint.missing.source.attribute": { + }, + }, + }, + expect: "datapoints: metric source_attribute missing", + }, + { + name: "missing_source_attribute_log", + input: &Config{ + Logs: map[string]MetricInfo{ + "log.missing.source.attribute": { + }, + }, + }, + expect: "logs: metric source_attribute missing", + }, { name: "missing_metric_name_span", input: &Config{ diff --git a/connector/sumconnector/factory.go b/connector/sumconnector/factory.go index e239bc31b0ee..11aa9a1e5858 100644 --- a/connector/sumconnector/factory.go +++ b/connector/sumconnector/factory.go @@ -59,6 +59,7 @@ func createTracesToMetrics( condition, _ := filterottl.NewBoolExprForSpan(info.Conditions, filterottl.StandardSpanFuncs(), ottl.PropagateError, set.TelemetrySettings) md.condition = condition } + md.sourceAttr = info.SourceAttribute spanMetricDefs[name] = md } @@ -73,6 +74,7 @@ func createTracesToMetrics( condition, _ := filterottl.NewBoolExprForSpanEvent(info.Conditions, filterottl.StandardSpanEventFuncs(), ottl.PropagateError, set.TelemetrySettings) md.condition = condition } + md.sourceAttr = info.SourceAttribute spanEventMetricDefs[name] = md } @@ -102,6 +104,7 @@ func createMetricsToMetrics( condition, _ := filterottl.NewBoolExprForMetric(info.Conditions, filterottl.StandardMetricFuncs(), ottl.PropagateError, set.TelemetrySettings) md.condition = condition } + md.sourceAttr = info.SourceAttribute metricMetricDefs[name] = md } @@ -116,6 +119,7 @@ func createMetricsToMetrics( condition, _ := filterottl.NewBoolExprForDataPoint(info.Conditions, filterottl.StandardDataPointFuncs(), ottl.PropagateError, set.TelemetrySettings) md.condition = condition } + md.sourceAttr = info.SourceAttribute dataPointMetricDefs[name] = md } @@ -146,6 +150,7 @@ func createLogsToMetrics( condition, _ := filterottl.NewBoolExprForLog(info.Conditions, filterottl.StandardLogFuncs(), ottl.PropagateError, set.TelemetrySettings) md.condition = condition } + md.sourceAttr = info.SourceAttribute metricDefs[name] = md } @@ -156,7 +161,8 @@ func createLogsToMetrics( } type metricDef[K any] struct { - condition expr.BoolExpr[K] - desc string - attrs []AttributeConfig + condition expr.BoolExpr[K] + desc string + attrs []AttributeConfig + sourceAttr string } diff --git a/connector/sumconnector/go.mod b/connector/sumconnector/go.mod index 168504b8e726..dc014fe490b2 100644 --- a/connector/sumconnector/go.mod +++ b/connector/sumconnector/go.mod @@ -12,6 +12,7 @@ require ( go.opentelemetry.io/collector/consumer v0.104.0 go.opentelemetry.io/collector/pdata v1.11.0 go.uber.org/goleak v1.3.0 + go.uber.org/zap v1.27.0 ) require ( @@ -53,7 +54,6 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.27.0 // indirect go.opentelemetry.io/otel/trace v1.27.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.0 // indirect golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/net v0.26.0 // indirect golang.org/x/sys v0.21.0 // indirect diff --git a/connector/sumconnector/testdata/config.yaml b/connector/sumconnector/testdata/config.yaml index 539ef547b3fd..d2a2bcb1de1c 100644 --- a/connector/sumconnector/testdata/config.yaml +++ b/connector/sumconnector/testdata/config.yaml @@ -23,107 +23,109 @@ sum/custom_metric: spans: my.span.sum: - description: My span sum. + source_attribute: my.attribute spanevents: my.spanevent.sum: - description: My span event sum. + source_attribute: my.attribute metrics: my.metric.sum: - description: My metric sum. + source_attribute: my.attribute datapoints: my.datapoint.sum: - description: My data point sum. + source_attribute: my.attribute logs: my.logrecord.sum: - description: My log record sum. + source_attribute: my.attribute sum/condition: spans: my.span.sum: - description: My span sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-s") spanevents: my.spanevent.sum: - description: My span event sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-e") metrics: my.metric.sum: - description: My metric sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-m") datapoints: my.datapoint.sum: - description: My data point sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-d") logs: my.logrecord.sum: - description: My log record sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-l") sum/multiple_condition: spans: my.span.sum: - description: My span sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-s") - IsMatch(resource.attributes["foo"], "bar-s") spanevents: my.spanevent.sum: - description: My span event sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-e") - IsMatch(resource.attributes["foo"], "bar-e") metrics: my.metric.sum: - description: My metric sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-m") - IsMatch(resource.attributes["foo"], "bar-m") datapoints: my.datapoint.sum: - description: My data point sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-d") - IsMatch(resource.attributes["foo"], "bar-d") logs: my.logrecord.sum: - description: My log record sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-l") - IsMatch(resource.attributes["foo"], "bar-l") sum/attribute: spans: my.span.sum: - description: My span sum by environment. + source_attribute: my.attribute attributes: - key: env spanevents: my.spanevent.sum: - description: My span event sum by environment. + source_attribute: my.attribute attributes: - key: env metrics: my.metric.sum: - description: My metric sum. + source_attribute: my.attribute # Metrics do not have attributes. datapoints: my.datapoint.sum: - description: My data point sum by environment. + source_attribute: my.attribute attributes: - key: env logs: my.logrecord.sum: - description: My log record sum by environment. + source_attribute: my.attribute attributes: - key: env sum/multiple_metrics: spans: my.span.sum: description: My span sum. + source_attribute: my.attribute limited.span.sum: description: Limited span sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-s") attributes: @@ -133,8 +135,10 @@ spanevents: my.spanevent.sum: description: My span event sum. + source_attribute: my.attribute limited.spanevent.sum: description: Limited span event sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-e") attributes: @@ -144,15 +148,19 @@ metrics: my.metric.sum: description: My metric sum. + source_attribute: my.attribute limited.metric.sum: description: Limited metric sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-m") datapoints: my.datapoint.sum: description: My data point sum. + source_attribute: my.attribute limited.datapoint.sum: description: Limited data point sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-d") attributes: @@ -162,24 +170,13 @@ logs: my.logrecord.sum: description: My log record sum. + source_attribute: my.attribute limited.logrecord.sum: description: Limited log record sum. + source_attribute: my.attribute conditions: - IsMatch(resource.attributes["host.name"], "pod-l") attributes: - key: env - key: component - default_value: other - sum/default_values: - logs: - my.logrecord.sum: - description: My log record sum with default values. - limited.logrecord.sum: - description: Limited log record sum. - attributes: - - key: env - default_value: "local" - - key: http_code - default_value: 200 - - key: request_success - default_value: 0.85 \ No newline at end of file + default_value: other \ No newline at end of file From 56f38bdf4272f4427008886551425758c6fe1a7f Mon Sep 17 00:00:00 2001 From: jeremyh Date: Tue, 9 Jul 2024 14:25:03 -0400 Subject: [PATCH 3/7] tidy etc --- connector/sumconnector/config_test.go | 45 +++++++++---------- connector/sumconnector/factory.go | 28 ++++++------ .../sumconnector/generated_package_test.go | 3 +- 3 files changed, 35 insertions(+), 41 deletions(-) diff --git a/connector/sumconnector/config_test.go b/connector/sumconnector/config_test.go index 7f117b7fa30b..e125943bbe97 100644 --- a/connector/sumconnector/config_test.go +++ b/connector/sumconnector/config_test.go @@ -218,13 +218,13 @@ func TestLoadConfig(t *testing.T) { expect: &Config{ Spans: map[string]MetricInfo{ "my.span.sum": { - Description: "My span sum.", + Description: "My span sum.", SourceAttribute: "my.attribute", }, "limited.span.sum": { - Description: "Limited span sum.", + Description: "Limited span sum.", SourceAttribute: "my.attribute", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s")`}, + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s")`}, Attributes: []AttributeConfig{ { Key: "env", @@ -238,13 +238,13 @@ func TestLoadConfig(t *testing.T) { }, SpanEvents: map[string]MetricInfo{ "my.spanevent.sum": { - Description: "My span event sum.", + Description: "My span event sum.", SourceAttribute: "my.attribute", }, "limited.spanevent.sum": { - Description: "Limited span event sum.", + Description: "Limited span event sum.", SourceAttribute: "my.attribute", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e")`}, + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e")`}, Attributes: []AttributeConfig{ { Key: "env", @@ -258,24 +258,24 @@ func TestLoadConfig(t *testing.T) { }, Metrics: map[string]MetricInfo{ "my.metric.sum": { - Description: "My metric sum.", + Description: "My metric sum.", SourceAttribute: "my.attribute", }, "limited.metric.sum": { - Description: "Limited metric sum.", + Description: "Limited metric sum.", SourceAttribute: "my.attribute", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-m")`}, + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-m")`}, }, }, DataPoints: map[string]MetricInfo{ "my.datapoint.sum": { - Description: "My data point sum.", + Description: "My data point sum.", SourceAttribute: "my.attribute", }, "limited.datapoint.sum": { - Description: "Limited data point sum.", + Description: "Limited data point sum.", SourceAttribute: "my.attribute", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d")`}, + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d")`}, Attributes: []AttributeConfig{ { Key: "env", @@ -289,13 +289,13 @@ func TestLoadConfig(t *testing.T) { }, Logs: map[string]MetricInfo{ "my.logrecord.sum": { - Description: "My log record sum.", + Description: "My log record sum.", SourceAttribute: "my.attribute", }, "limited.logrecord.sum": { - Description: "Limited log record sum.", + Description: "Limited log record sum.", SourceAttribute: "my.attribute", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l")`}, + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l")`}, Attributes: []AttributeConfig{ { Key: "env", @@ -338,8 +338,7 @@ func TestConfigErrors(t *testing.T) { name: "missing_source_attribute_span", input: &Config{ Spans: map[string]MetricInfo{ - "span.missing.source.attribute": { - }, + "span.missing.source.attribute": {}, }, }, expect: "spans: metric source_attribute missing", @@ -348,8 +347,7 @@ func TestConfigErrors(t *testing.T) { name: "missing_source_attribute_spanevent", input: &Config{ SpanEvents: map[string]MetricInfo{ - "spanevent.missing.source.attribute": { - }, + "spanevent.missing.source.attribute": {}, }, }, expect: "spanevents: metric source_attribute missing", @@ -358,8 +356,7 @@ func TestConfigErrors(t *testing.T) { name: "missing_source_attribute_metric", input: &Config{ Metrics: map[string]MetricInfo{ - "metric.missing.source.attribute": { - }, + "metric.missing.source.attribute": {}, }, }, expect: "metrics: metric source_attribute missing", @@ -368,8 +365,7 @@ func TestConfigErrors(t *testing.T) { name: "missing_source_attribute_datapoint", input: &Config{ DataPoints: map[string]MetricInfo{ - "datapoint.missing.source.attribute": { - }, + "datapoint.missing.source.attribute": {}, }, }, expect: "datapoints: metric source_attribute missing", @@ -378,8 +374,7 @@ func TestConfigErrors(t *testing.T) { name: "missing_source_attribute_log", input: &Config{ Logs: map[string]MetricInfo{ - "log.missing.source.attribute": { - }, + "log.missing.source.attribute": {}, }, }, expect: "logs: metric source_attribute missing", diff --git a/connector/sumconnector/factory.go b/connector/sumconnector/factory.go index 11aa9a1e5858..122484c9a843 100644 --- a/connector/sumconnector/factory.go +++ b/connector/sumconnector/factory.go @@ -51,30 +51,30 @@ func createTracesToMetrics( spanMetricDefs := make(map[string]metricDef[ottlspan.TransformContext], len(c.Spans)) for name, info := range c.Spans { md := metricDef[ottlspan.TransformContext]{ - desc: info.Description, - attrs: info.Attributes, + desc: info.Description, + attrs: info.Attributes, + sourceAttr: info.SourceAttribute, } if len(info.Conditions) > 0 { // Error checked in Config.Validate() condition, _ := filterottl.NewBoolExprForSpan(info.Conditions, filterottl.StandardSpanFuncs(), ottl.PropagateError, set.TelemetrySettings) md.condition = condition } - md.sourceAttr = info.SourceAttribute spanMetricDefs[name] = md } spanEventMetricDefs := make(map[string]metricDef[ottlspanevent.TransformContext], len(c.SpanEvents)) for name, info := range c.SpanEvents { md := metricDef[ottlspanevent.TransformContext]{ - desc: info.Description, - attrs: info.Attributes, + desc: info.Description, + attrs: info.Attributes, + sourceAttr: info.SourceAttribute, } if len(info.Conditions) > 0 { // Error checked in Config.Validate() condition, _ := filterottl.NewBoolExprForSpanEvent(info.Conditions, filterottl.StandardSpanEventFuncs(), ottl.PropagateError, set.TelemetrySettings) md.condition = condition } - md.sourceAttr = info.SourceAttribute spanEventMetricDefs[name] = md } @@ -97,29 +97,29 @@ func createMetricsToMetrics( metricMetricDefs := make(map[string]metricDef[ottlmetric.TransformContext], len(c.Metrics)) for name, info := range c.Metrics { md := metricDef[ottlmetric.TransformContext]{ - desc: info.Description, + desc: info.Description, + sourceAttr: info.SourceAttribute, } if len(info.Conditions) > 0 { // Error checked in Config.Validate() condition, _ := filterottl.NewBoolExprForMetric(info.Conditions, filterottl.StandardMetricFuncs(), ottl.PropagateError, set.TelemetrySettings) md.condition = condition } - md.sourceAttr = info.SourceAttribute metricMetricDefs[name] = md } dataPointMetricDefs := make(map[string]metricDef[ottldatapoint.TransformContext], len(c.DataPoints)) for name, info := range c.DataPoints { md := metricDef[ottldatapoint.TransformContext]{ - desc: info.Description, - attrs: info.Attributes, + desc: info.Description, + attrs: info.Attributes, + sourceAttr: info.SourceAttribute, } if len(info.Conditions) > 0 { // Error checked in Config.Validate() condition, _ := filterottl.NewBoolExprForDataPoint(info.Conditions, filterottl.StandardDataPointFuncs(), ottl.PropagateError, set.TelemetrySettings) md.condition = condition } - md.sourceAttr = info.SourceAttribute dataPointMetricDefs[name] = md } @@ -142,15 +142,15 @@ func createLogsToMetrics( metricDefs := make(map[string]metricDef[ottllog.TransformContext], len(c.Logs)) for name, info := range c.Logs { md := metricDef[ottllog.TransformContext]{ - desc: info.Description, - attrs: info.Attributes, + desc: info.Description, + attrs: info.Attributes, + sourceAttr: info.SourceAttribute, } if len(info.Conditions) > 0 { // Error checked in Config.Validate() condition, _ := filterottl.NewBoolExprForLog(info.Conditions, filterottl.StandardLogFuncs(), ottl.PropagateError, set.TelemetrySettings) md.condition = condition } - md.sourceAttr = info.SourceAttribute metricDefs[name] = md } diff --git a/connector/sumconnector/generated_package_test.go b/connector/sumconnector/generated_package_test.go index 6a2e7f1b6171..2c6d0cb52ca9 100644 --- a/connector/sumconnector/generated_package_test.go +++ b/connector/sumconnector/generated_package_test.go @@ -3,9 +3,8 @@ package sumconnector import ( - "testing" - "go.uber.org/goleak" + "testing" ) func TestMain(m *testing.M) { From c20b0f94b3fdc4c23e83356dc40a90616b16050d Mon Sep 17 00:00:00 2001 From: jeremyh Date: Wed, 10 Jul 2024 10:52:38 -0400 Subject: [PATCH 4/7] collect and report errors --- connector/sumconnector/config.go | 49 ++++----- connector/sumconnector/config_test.go | 99 ++++++++++++++++--- .../sumconnector/generated_package_test.go | 3 +- connector/sumconnector/go.mod | 2 +- 4 files changed, 115 insertions(+), 38 deletions(-) diff --git a/connector/sumconnector/config.go b/connector/sumconnector/config.go index fd0239075a3a..ef8a3cd0dff2 100644 --- a/connector/sumconnector/config.go +++ b/connector/sumconnector/config.go @@ -7,6 +7,7 @@ import ( "fmt" "go.opentelemetry.io/collector/component" + "go.uber.org/multierr" "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter/filterottl" @@ -31,87 +32,87 @@ type MetricInfo struct { } type AttributeConfig struct { - Key string `mapstructure:"key"` + AttrKey string `mapstructure:"key"` DefaultValue any `mapstructure:"default_value"` } -func (c *Config) Validate() error { +func (c *Config) Validate() (errors error) { for name, info := range c.Spans { if name == "" { - return fmt.Errorf("spans: metric name missing") + errors = multierr.Append(errors, fmt.Errorf("spans: metric name missing")) } if _, err := filterottl.NewBoolExprForSpan(info.Conditions, filterottl.StandardSpanFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { - return fmt.Errorf("spans condition: metric %q: %w", name, err) + errors = multierr.Append(errors, fmt.Errorf("spans condition: metric %q: %w", name, err)) } if err := info.validateAttributes(); err != nil { - return fmt.Errorf("spans attributes: metric %q: %w", name, err) + errors = multierr.Append(errors, fmt.Errorf("spans attributes: metric %q: %w", name, err)) } if info.SourceAttribute == "" { - return fmt.Errorf("spans: metric source_attribute missing") + errors = multierr.Append(errors, fmt.Errorf("spans: metric source_attribute missing")) } } for name, info := range c.SpanEvents { if name == "" { - return fmt.Errorf("spanevents: metric name missing") + errors = multierr.Append(errors, fmt.Errorf("spanevents: metric name missing")) } if _, err := filterottl.NewBoolExprForSpanEvent(info.Conditions, filterottl.StandardSpanEventFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { - return fmt.Errorf("spanevents condition: metric %q: %w", name, err) + errors = multierr.Append(errors, fmt.Errorf("spanevents condition: metric %q: %w", name, err)) } if err := info.validateAttributes(); err != nil { - return fmt.Errorf("spanevents attributes: metric %q: %w", name, err) + errors = multierr.Append(errors, fmt.Errorf("spanevents attributes: metric %q: %w", name, err)) } if info.SourceAttribute == "" { - return fmt.Errorf("spanevents: metric source_attribute missing") + errors = multierr.Append(errors, fmt.Errorf("spanevents: metric source_attribute missing")) } } for name, info := range c.Metrics { if name == "" { - return fmt.Errorf("metrics: metric name missing") + errors = multierr.Append(errors, fmt.Errorf("metrics: metric name missing")) } if _, err := filterottl.NewBoolExprForMetric(info.Conditions, filterottl.StandardMetricFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { - return fmt.Errorf("metrics condition: metric %q: %w", name, err) + errors = multierr.Append(errors, fmt.Errorf("metrics condition: metric %q: %w", name, err)) } if len(info.Attributes) > 0 { - return fmt.Errorf("metrics attributes not supported: metric %q", name) + errors = multierr.Append(errors, fmt.Errorf("metrics attributes not supported: metric %q", name)) } if info.SourceAttribute == "" { - return fmt.Errorf("metrics: metric source_attribute missing") + errors = multierr.Append(errors, fmt.Errorf("metrics: metric source_attribute missing")) } } for name, info := range c.DataPoints { if name == "" { - return fmt.Errorf("datapoints: metric name missing") + errors = multierr.Append(errors, fmt.Errorf("datapoints: metric name missing")) } if _, err := filterottl.NewBoolExprForDataPoint(info.Conditions, filterottl.StandardDataPointFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { - return fmt.Errorf("datapoints condition: metric %q: %w", name, err) + errors = multierr.Append(errors, fmt.Errorf("datapoints condition: metric %q: %w", name, err)) } if err := info.validateAttributes(); err != nil { - return fmt.Errorf("spans attributes: metric %q: %w", name, err) + errors = multierr.Append(errors, fmt.Errorf("spans attributes: metric %q: %w", name, err)) } if info.SourceAttribute == "" { - return fmt.Errorf("datapoints: metric source_attribute missing") + errors = multierr.Append(errors, fmt.Errorf("datapoints: metric source_attribute missing")) } } for name, info := range c.Logs { if name == "" { - return fmt.Errorf("logs: metric name missing") + errors = multierr.Append(errors, fmt.Errorf("logs: metric name missing")) } if _, err := filterottl.NewBoolExprForLog(info.Conditions, filterottl.StandardLogFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { - return fmt.Errorf("logs condition: metric %q: %w", name, err) + errors = multierr.Append(errors, fmt.Errorf("logs condition: metric %q: %w", name, err)) } if err := info.validateAttributes(); err != nil { - return fmt.Errorf("logs attributes: metric %q: %w", name, err) + errors = multierr.Append(errors, fmt.Errorf("logs attributes: metric %q: %w", name, err)) } if info.SourceAttribute == "" { - return fmt.Errorf("logs: metric source_attribute missing") + errors = multierr.Append(errors, fmt.Errorf("logs: metric source_attribute missing")) } } - return nil + return errors } func (i *MetricInfo) validateAttributes() error { for _, attr := range i.Attributes { - if attr.Key == "" { + if attr.AttrKey == "" { return fmt.Errorf("attribute key missing") } } diff --git a/connector/sumconnector/config_test.go b/connector/sumconnector/config_test.go index e125943bbe97..4b74716bca1a 100644 --- a/connector/sumconnector/config_test.go +++ b/connector/sumconnector/config_test.go @@ -178,7 +178,7 @@ func TestLoadConfig(t *testing.T) { "my.span.sum": { SourceAttribute: "my.attribute", Attributes: []AttributeConfig{ - {Key: "env"}, + {AttrKey: "env"}, }, }, }, @@ -186,7 +186,7 @@ func TestLoadConfig(t *testing.T) { "my.spanevent.sum": { SourceAttribute: "my.attribute", Attributes: []AttributeConfig{ - {Key: "env"}, + {AttrKey: "env"}, }, }, }, @@ -199,7 +199,7 @@ func TestLoadConfig(t *testing.T) { "my.datapoint.sum": { SourceAttribute: "my.attribute", Attributes: []AttributeConfig{ - {Key: "env"}, + {AttrKey: "env"}, }, }, }, @@ -207,7 +207,7 @@ func TestLoadConfig(t *testing.T) { "my.logrecord.sum": { SourceAttribute: "my.attribute", Attributes: []AttributeConfig{ - {Key: "env"}, + {AttrKey: "env"}, }, }, }, @@ -227,10 +227,10 @@ func TestLoadConfig(t *testing.T) { Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s")`}, Attributes: []AttributeConfig{ { - Key: "env", + AttrKey: "env", }, { - Key: "component", + AttrKey: "component", DefaultValue: "other", }, }, @@ -247,10 +247,10 @@ func TestLoadConfig(t *testing.T) { Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e")`}, Attributes: []AttributeConfig{ { - Key: "env", + AttrKey: "env", }, { - Key: "component", + AttrKey: "component", DefaultValue: "other", }, }, @@ -278,10 +278,10 @@ func TestLoadConfig(t *testing.T) { Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d")`}, Attributes: []AttributeConfig{ { - Key: "env", + AttrKey: "env", }, { - Key: "component", + AttrKey: "component", DefaultValue: "other", }, }, @@ -298,10 +298,10 @@ func TestLoadConfig(t *testing.T) { Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l")`}, Attributes: []AttributeConfig{ { - Key: "env", + AttrKey: "env", }, { - Key: "component", + AttrKey: "component", DefaultValue: "other", }, }, @@ -494,6 +494,81 @@ func TestConfigErrors(t *testing.T) { }, expect: fmt.Sprintf("logs condition: metric %q: unable to parse OTTL condition", "metric.name.logs"), }, + { + name: "multi_error_span", + input: &Config{ + Spans: map[string]MetricInfo{ + "": { + SourceAttribute: "", + Conditions: []string{"invalid condition"}, + Attributes: []AttributeConfig{ + {AttrKey: ""}, + }, + }, + }, + }, + expect: `spans: metric name missing; spans condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value); spans attributes: metric "": attribute key missing; spans: metric source_attribute missing`, + }, + { + name: "multi_error_spanevent", + input: &Config{ + SpanEvents: map[string]MetricInfo{ + "": { + SourceAttribute: "", + Conditions: []string{"invalid condition"}, + Attributes: []AttributeConfig{ + {AttrKey: ""}, + }, + }, + }, + }, + expect: `spanevents: metric name missing; spanevents condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value); spanevents attributes: metric "": attribute key missing; spanevents: metric source_attribute missing`, + }, + { + name: "invalid_condition_metric", + input: &Config{ + Metrics: map[string]MetricInfo{ + "": { + SourceAttribute: "", + Conditions: []string{"invalid condition"}, + Attributes: []AttributeConfig{ + {AttrKey: ""}, + }, + }, + }, + }, + expect: `metrics: metric name missing; metrics condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value); metrics attributes not supported: metric ""; metrics: metric source_attribute missing`, + }, + { + name: "multi_error_datapoint", + input: &Config{ + DataPoints: map[string]MetricInfo{ + "": { + SourceAttribute: "", + Conditions: []string{"invalid condition"}, + Attributes: []AttributeConfig{ + {AttrKey: ""}, + }, + }, + }, + }, + expect: `datapoints: metric name missing; datapoints condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value); spans attributes: metric "": attribute key missing; datapoints: metric source_attribute missing`, + }, + { + name: "multi_error_log", + input: &Config{ + Logs: map[string]MetricInfo{ + "": { + SourceAttribute: "", + Conditions: []string{"invalid condition"}, + Attributes: []AttributeConfig{ + {AttrKey: ""}, + }, + }, + }, + }, + expect: `logs: metric name missing; logs condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value); logs attributes: metric "": attribute key missing; logs: metric source_attribute missing`, + }, } for _, tc := range testCases { diff --git a/connector/sumconnector/generated_package_test.go b/connector/sumconnector/generated_package_test.go index 2c6d0cb52ca9..6a2e7f1b6171 100644 --- a/connector/sumconnector/generated_package_test.go +++ b/connector/sumconnector/generated_package_test.go @@ -3,8 +3,9 @@ package sumconnector import ( - "go.uber.org/goleak" "testing" + + "go.uber.org/goleak" ) func TestMain(m *testing.M) { diff --git a/connector/sumconnector/go.mod b/connector/sumconnector/go.mod index 7b430d95723a..f302f4c9ee7d 100644 --- a/connector/sumconnector/go.mod +++ b/connector/sumconnector/go.mod @@ -12,6 +12,7 @@ require ( go.opentelemetry.io/collector/consumer v0.104.1-0.20240709093154-e7ce1d50fb5e go.opentelemetry.io/collector/pdata v1.11.1-0.20240709093154-e7ce1d50fb5e go.uber.org/goleak v1.3.0 + go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 ) @@ -55,7 +56,6 @@ require ( go.opentelemetry.io/otel/sdk v1.28.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect From 1d4071468b6990e0e5ba29dd9ff8c66f2feb3c71 Mon Sep 17 00:00:00 2001 From: jeremyh Date: Mon, 15 Jul 2024 11:35:01 -0400 Subject: [PATCH 5/7] update order of tests, use join instead of multierr --- connector/sumconnector/config.go | 66 +++++++++++++-------------- connector/sumconnector/config_test.go | 12 ++--- connector/sumconnector/go.mod | 2 +- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/connector/sumconnector/config.go b/connector/sumconnector/config.go index ef8a3cd0dff2..cdbc45169373 100644 --- a/connector/sumconnector/config.go +++ b/connector/sumconnector/config.go @@ -4,10 +4,10 @@ package sumconnector // import "github.com/open-telemetry/opentelemetry-collector-contrib/connector/sumconnector" import ( + "errors" "fmt" "go.opentelemetry.io/collector/component" - "go.uber.org/multierr" "go.uber.org/zap" "github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter/filterottl" @@ -36,78 +36,78 @@ type AttributeConfig struct { DefaultValue any `mapstructure:"default_value"` } -func (c *Config) Validate() (errors error) { +func (c *Config) Validate() (combinedErrors error) { for name, info := range c.Spans { if name == "" { - errors = multierr.Append(errors, fmt.Errorf("spans: metric name missing")) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("spans: metric name missing")) + } + if info.SourceAttribute == "" { + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("spans: metric source_attribute missing")) } if _, err := filterottl.NewBoolExprForSpan(info.Conditions, filterottl.StandardSpanFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { - errors = multierr.Append(errors, fmt.Errorf("spans condition: metric %q: %w", name, err)) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("spans condition: metric %q: %w", name, err)) } if err := info.validateAttributes(); err != nil { - errors = multierr.Append(errors, fmt.Errorf("spans attributes: metric %q: %w", name, err)) - } - if info.SourceAttribute == "" { - errors = multierr.Append(errors, fmt.Errorf("spans: metric source_attribute missing")) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("spans attributes: metric %q: %w", name, err)) } } for name, info := range c.SpanEvents { if name == "" { - errors = multierr.Append(errors, fmt.Errorf("spanevents: metric name missing")) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("spanevents: metric name missing")) + } + if info.SourceAttribute == "" { + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("spanevents: metric source_attribute missing")) } if _, err := filterottl.NewBoolExprForSpanEvent(info.Conditions, filterottl.StandardSpanEventFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { - errors = multierr.Append(errors, fmt.Errorf("spanevents condition: metric %q: %w", name, err)) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("spanevents condition: metric %q: %w", name, err)) } if err := info.validateAttributes(); err != nil { - errors = multierr.Append(errors, fmt.Errorf("spanevents attributes: metric %q: %w", name, err)) - } - if info.SourceAttribute == "" { - errors = multierr.Append(errors, fmt.Errorf("spanevents: metric source_attribute missing")) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("spanevents attributes: metric %q: %w", name, err)) } } for name, info := range c.Metrics { if name == "" { - errors = multierr.Append(errors, fmt.Errorf("metrics: metric name missing")) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("metrics: metric name missing")) + } + if info.SourceAttribute == "" { + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("metrics: metric source_attribute missing")) } if _, err := filterottl.NewBoolExprForMetric(info.Conditions, filterottl.StandardMetricFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { - errors = multierr.Append(errors, fmt.Errorf("metrics condition: metric %q: %w", name, err)) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("metrics condition: metric %q: %w", name, err)) } if len(info.Attributes) > 0 { - errors = multierr.Append(errors, fmt.Errorf("metrics attributes not supported: metric %q", name)) - } - if info.SourceAttribute == "" { - errors = multierr.Append(errors, fmt.Errorf("metrics: metric source_attribute missing")) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("metrics attributes not supported: metric %q", name)) } } for name, info := range c.DataPoints { if name == "" { - errors = multierr.Append(errors, fmt.Errorf("datapoints: metric name missing")) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("datapoints: metric name missing")) + } + if info.SourceAttribute == "" { + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("datapoints: metric source_attribute missing")) } if _, err := filterottl.NewBoolExprForDataPoint(info.Conditions, filterottl.StandardDataPointFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { - errors = multierr.Append(errors, fmt.Errorf("datapoints condition: metric %q: %w", name, err)) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("datapoints condition: metric %q: %w", name, err)) } if err := info.validateAttributes(); err != nil { - errors = multierr.Append(errors, fmt.Errorf("spans attributes: metric %q: %w", name, err)) - } - if info.SourceAttribute == "" { - errors = multierr.Append(errors, fmt.Errorf("datapoints: metric source_attribute missing")) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("datapoints attributes: metric %q: %w", name, err)) } } for name, info := range c.Logs { if name == "" { - errors = multierr.Append(errors, fmt.Errorf("logs: metric name missing")) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("logs: metric name missing")) + } + if info.SourceAttribute == "" { + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("logs: metric source_attribute missing")) } if _, err := filterottl.NewBoolExprForLog(info.Conditions, filterottl.StandardLogFuncs(), ottl.PropagateError, component.TelemetrySettings{Logger: zap.NewNop()}); err != nil { - errors = multierr.Append(errors, fmt.Errorf("logs condition: metric %q: %w", name, err)) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("logs condition: metric %q: %w", name, err)) } if err := info.validateAttributes(); err != nil { - errors = multierr.Append(errors, fmt.Errorf("logs attributes: metric %q: %w", name, err)) - } - if info.SourceAttribute == "" { - errors = multierr.Append(errors, fmt.Errorf("logs: metric source_attribute missing")) + combinedErrors = errors.Join(combinedErrors, fmt.Errorf("logs attributes: metric %q: %w", name, err)) } } - return errors + return combinedErrors } func (i *MetricInfo) validateAttributes() error { diff --git a/connector/sumconnector/config_test.go b/connector/sumconnector/config_test.go index 4b74716bca1a..3b8a4df0f80f 100644 --- a/connector/sumconnector/config_test.go +++ b/connector/sumconnector/config_test.go @@ -507,7 +507,7 @@ func TestConfigErrors(t *testing.T) { }, }, }, - expect: `spans: metric name missing; spans condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value); spans attributes: metric "": attribute key missing; spans: metric source_attribute missing`, + expect: `spans: metric name missing`+"\n"+`spans: metric source_attribute missing`+"\n"+`spans condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)`+"\n"+`spans attributes: metric "": attribute key missing`, }, { name: "multi_error_spanevent", @@ -522,10 +522,10 @@ func TestConfigErrors(t *testing.T) { }, }, }, - expect: `spanevents: metric name missing; spanevents condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value); spanevents attributes: metric "": attribute key missing; spanevents: metric source_attribute missing`, + expect: `spanevents: metric name missing`+"\n"+`spanevents: metric source_attribute missing`+"\n"+`spanevents condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)`+"\n"+`spanevents attributes: metric "": attribute key missing`, }, { - name: "invalid_condition_metric", + name: "multi_error_metric", input: &Config{ Metrics: map[string]MetricInfo{ "": { @@ -537,7 +537,7 @@ func TestConfigErrors(t *testing.T) { }, }, }, - expect: `metrics: metric name missing; metrics condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value); metrics attributes not supported: metric ""; metrics: metric source_attribute missing`, + expect: `metrics: metric name missing`+"\n"+`metrics: metric source_attribute missing`+"\n"+`metrics condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)`+"\n"+`metrics attributes not supported: metric ""`, }, { name: "multi_error_datapoint", @@ -552,7 +552,7 @@ func TestConfigErrors(t *testing.T) { }, }, }, - expect: `datapoints: metric name missing; datapoints condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value); spans attributes: metric "": attribute key missing; datapoints: metric source_attribute missing`, + expect: `datapoints: metric name missing`+"\n"+`datapoints: metric source_attribute missing`+"\n"+`datapoints condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)`+"\n"+`datapoints attributes: metric "": attribute key missing`, }, { name: "multi_error_log", @@ -567,7 +567,7 @@ func TestConfigErrors(t *testing.T) { }, }, }, - expect: `logs: metric name missing; logs condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value); logs attributes: metric "": attribute key missing; logs: metric source_attribute missing`, + expect: `logs: metric name missing`+"\n"+`logs: metric source_attribute missing`+"\n"+`logs condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)`+"\n"+`logs attributes: metric "": attribute key missing`, }, } diff --git a/connector/sumconnector/go.mod b/connector/sumconnector/go.mod index f302f4c9ee7d..7b430d95723a 100644 --- a/connector/sumconnector/go.mod +++ b/connector/sumconnector/go.mod @@ -12,7 +12,6 @@ require ( go.opentelemetry.io/collector/consumer v0.104.1-0.20240709093154-e7ce1d50fb5e go.opentelemetry.io/collector/pdata v1.11.1-0.20240709093154-e7ce1d50fb5e go.uber.org/goleak v1.3.0 - go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 ) @@ -56,6 +55,7 @@ require ( go.opentelemetry.io/otel/sdk v1.28.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect + go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/sys v0.22.0 // indirect From 15fd76bd68cc7b6b52aec5402d267d6975542f4e Mon Sep 17 00:00:00 2001 From: jeremyh Date: Mon, 15 Jul 2024 13:06:34 -0400 Subject: [PATCH 6/7] gci fmt lint --- connector/sumconnector/config_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/connector/sumconnector/config_test.go b/connector/sumconnector/config_test.go index 3b8a4df0f80f..2efa3473c545 100644 --- a/connector/sumconnector/config_test.go +++ b/connector/sumconnector/config_test.go @@ -507,7 +507,7 @@ func TestConfigErrors(t *testing.T) { }, }, }, - expect: `spans: metric name missing`+"\n"+`spans: metric source_attribute missing`+"\n"+`spans condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)`+"\n"+`spans attributes: metric "": attribute key missing`, + expect: `spans: metric name missing` + "\n" + `spans: metric source_attribute missing` + "\n" + `spans condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)` + "\n" + `spans attributes: metric "": attribute key missing`, }, { name: "multi_error_spanevent", @@ -522,7 +522,7 @@ func TestConfigErrors(t *testing.T) { }, }, }, - expect: `spanevents: metric name missing`+"\n"+`spanevents: metric source_attribute missing`+"\n"+`spanevents condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)`+"\n"+`spanevents attributes: metric "": attribute key missing`, + expect: `spanevents: metric name missing` + "\n" + `spanevents: metric source_attribute missing` + "\n" + `spanevents condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)` + "\n" + `spanevents attributes: metric "": attribute key missing`, }, { name: "multi_error_metric", @@ -537,7 +537,7 @@ func TestConfigErrors(t *testing.T) { }, }, }, - expect: `metrics: metric name missing`+"\n"+`metrics: metric source_attribute missing`+"\n"+`metrics condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)`+"\n"+`metrics attributes not supported: metric ""`, + expect: `metrics: metric name missing` + "\n" + `metrics: metric source_attribute missing` + "\n" + `metrics condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)` + "\n" + `metrics attributes not supported: metric ""`, }, { name: "multi_error_datapoint", @@ -552,7 +552,7 @@ func TestConfigErrors(t *testing.T) { }, }, }, - expect: `datapoints: metric name missing`+"\n"+`datapoints: metric source_attribute missing`+"\n"+`datapoints condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)`+"\n"+`datapoints attributes: metric "": attribute key missing`, + expect: `datapoints: metric name missing` + "\n" + `datapoints: metric source_attribute missing` + "\n" + `datapoints condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)` + "\n" + `datapoints attributes: metric "": attribute key missing`, }, { name: "multi_error_log", @@ -567,7 +567,7 @@ func TestConfigErrors(t *testing.T) { }, }, }, - expect: `logs: metric name missing`+"\n"+`logs: metric source_attribute missing`+"\n"+`logs condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)`+"\n"+`logs attributes: metric "": attribute key missing`, + expect: `logs: metric name missing` + "\n" + `logs: metric source_attribute missing` + "\n" + `logs condition: metric "": unable to parse OTTL condition "invalid condition": condition has invalid syntax: 1:9: unexpected token "condition" (expected Value)` + "\n" + `logs attributes: metric "": attribute key missing`, }, } From 4f43f724b7aa742f4d3a12803ac555ca2f3f5450 Mon Sep 17 00:00:00 2001 From: jeremyh Date: Tue, 16 Jul 2024 09:39:08 -0400 Subject: [PATCH 7/7] revert attrkey change --- connector/sumconnector/config.go | 4 ++-- connector/sumconnector/config_test.go | 34 +++++++++++++-------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/connector/sumconnector/config.go b/connector/sumconnector/config.go index cdbc45169373..5ca87a03a7bd 100644 --- a/connector/sumconnector/config.go +++ b/connector/sumconnector/config.go @@ -32,7 +32,7 @@ type MetricInfo struct { } type AttributeConfig struct { - AttrKey string `mapstructure:"key"` + Key string `mapstructure:"key"` DefaultValue any `mapstructure:"default_value"` } @@ -112,7 +112,7 @@ func (c *Config) Validate() (combinedErrors error) { func (i *MetricInfo) validateAttributes() error { for _, attr := range i.Attributes { - if attr.AttrKey == "" { + if attr.Key == "" { return fmt.Errorf("attribute key missing") } } diff --git a/connector/sumconnector/config_test.go b/connector/sumconnector/config_test.go index 2efa3473c545..17cc98ed5926 100644 --- a/connector/sumconnector/config_test.go +++ b/connector/sumconnector/config_test.go @@ -178,7 +178,7 @@ func TestLoadConfig(t *testing.T) { "my.span.sum": { SourceAttribute: "my.attribute", Attributes: []AttributeConfig{ - {AttrKey: "env"}, + {Key: "env"}, }, }, }, @@ -186,7 +186,7 @@ func TestLoadConfig(t *testing.T) { "my.spanevent.sum": { SourceAttribute: "my.attribute", Attributes: []AttributeConfig{ - {AttrKey: "env"}, + {Key: "env"}, }, }, }, @@ -199,7 +199,7 @@ func TestLoadConfig(t *testing.T) { "my.datapoint.sum": { SourceAttribute: "my.attribute", Attributes: []AttributeConfig{ - {AttrKey: "env"}, + {Key: "env"}, }, }, }, @@ -207,7 +207,7 @@ func TestLoadConfig(t *testing.T) { "my.logrecord.sum": { SourceAttribute: "my.attribute", Attributes: []AttributeConfig{ - {AttrKey: "env"}, + {Key: "env"}, }, }, }, @@ -227,10 +227,10 @@ func TestLoadConfig(t *testing.T) { Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s")`}, Attributes: []AttributeConfig{ { - AttrKey: "env", + Key: "env", }, { - AttrKey: "component", + Key: "component", DefaultValue: "other", }, }, @@ -247,10 +247,10 @@ func TestLoadConfig(t *testing.T) { Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e")`}, Attributes: []AttributeConfig{ { - AttrKey: "env", + Key: "env", }, { - AttrKey: "component", + Key: "component", DefaultValue: "other", }, }, @@ -278,10 +278,10 @@ func TestLoadConfig(t *testing.T) { Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d")`}, Attributes: []AttributeConfig{ { - AttrKey: "env", + Key: "env", }, { - AttrKey: "component", + Key: "component", DefaultValue: "other", }, }, @@ -298,10 +298,10 @@ func TestLoadConfig(t *testing.T) { Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l")`}, Attributes: []AttributeConfig{ { - AttrKey: "env", + Key: "env", }, { - AttrKey: "component", + Key: "component", DefaultValue: "other", }, }, @@ -502,7 +502,7 @@ func TestConfigErrors(t *testing.T) { SourceAttribute: "", Conditions: []string{"invalid condition"}, Attributes: []AttributeConfig{ - {AttrKey: ""}, + {Key: ""}, }, }, }, @@ -517,7 +517,7 @@ func TestConfigErrors(t *testing.T) { SourceAttribute: "", Conditions: []string{"invalid condition"}, Attributes: []AttributeConfig{ - {AttrKey: ""}, + {Key: ""}, }, }, }, @@ -532,7 +532,7 @@ func TestConfigErrors(t *testing.T) { SourceAttribute: "", Conditions: []string{"invalid condition"}, Attributes: []AttributeConfig{ - {AttrKey: ""}, + {Key: ""}, }, }, }, @@ -547,7 +547,7 @@ func TestConfigErrors(t *testing.T) { SourceAttribute: "", Conditions: []string{"invalid condition"}, Attributes: []AttributeConfig{ - {AttrKey: ""}, + {Key: ""}, }, }, }, @@ -562,7 +562,7 @@ func TestConfigErrors(t *testing.T) { SourceAttribute: "", Conditions: []string{"invalid condition"}, Attributes: []AttributeConfig{ - {AttrKey: ""}, + {Key: ""}, }, }, },