From 120e2cfe7974782dcd992045d7a99ecbf94b1f21 Mon Sep 17 00:00:00 2001 From: Dan Jaglowski Date: Thu, 9 Mar 2023 15:03:22 -0500 Subject: [PATCH 1/5] Allow count connector to count by attributes --- .chloggen/count-by-attributes.yaml | 16 + connector/countconnector/README.md | 60 +- connector/countconnector/config.go | 74 +- connector/countconnector/config_test.go | 344 +++- connector/countconnector/connector.go | 156 +- connector/countconnector/connector_test.go | 463 ++++- connector/countconnector/counter.go | 90 +- connector/countconnector/factory.go | 109 +- connector/countconnector/testdata/config.yaml | 41 + .../logs/condition_and_attribute.json | 126 ++ .../logs/default_attribute_value.json | 347 ++++ .../countconnector/testdata/logs/input.json | 268 ++- .../testdata/logs/multiple_attributes.json | 275 +++ .../testdata/logs/multiple_conditions.json | 75 +- .../testdata/logs/multiple_metrics.json | 79 +- .../testdata/logs/one_attribute.json | 227 +++ .../testdata/logs/one_condition.json | 52 +- .../testdata/logs/zero_conditions.json | 75 +- .../metrics/condition_and_attribute.json | 126 ++ .../metrics/default_attribute_value.json | 347 ++++ .../testdata/metrics/input.json | 1587 +++++++++++++++-- .../testdata/metrics/multiple_attributes.json | 275 +++ .../testdata/metrics/multiple_conditions.json | 123 +- .../testdata/metrics/multiple_metrics.json | 191 +- .../testdata/metrics/one_attribute.json | 227 +++ .../testdata/metrics/one_condition.json | 34 +- .../testdata/metrics/zero_conditions.json | 119 +- .../traces/condition_and_attribute.json | 194 ++ .../traces/default_attribute_value.json | 603 +++++++ .../countconnector/testdata/traces/input.json | 1136 +++++++++++- .../testdata/traces/multiple_attributes.json | 459 +++++ .../testdata/traces/multiple_conditions.json | 125 +- .../testdata/traces/multiple_metrics.json | 197 +- .../testdata/traces/one_attribute.json | 363 ++++ .../testdata/traces/one_condition.json | 36 +- .../testdata/traces/zero_conditions.json | 125 +- 36 files changed, 8308 insertions(+), 836 deletions(-) create mode 100755 .chloggen/count-by-attributes.yaml create mode 100644 connector/countconnector/testdata/logs/condition_and_attribute.json create mode 100644 connector/countconnector/testdata/logs/default_attribute_value.json create mode 100644 connector/countconnector/testdata/logs/multiple_attributes.json create mode 100644 connector/countconnector/testdata/logs/one_attribute.json create mode 100644 connector/countconnector/testdata/metrics/condition_and_attribute.json create mode 100644 connector/countconnector/testdata/metrics/default_attribute_value.json create mode 100644 connector/countconnector/testdata/metrics/multiple_attributes.json create mode 100644 connector/countconnector/testdata/metrics/one_attribute.json create mode 100644 connector/countconnector/testdata/traces/condition_and_attribute.json create mode 100644 connector/countconnector/testdata/traces/default_attribute_value.json create mode 100644 connector/countconnector/testdata/traces/multiple_attributes.json create mode 100644 connector/countconnector/testdata/traces/one_attribute.json diff --git a/.chloggen/count-by-attributes.yaml b/.chloggen/count-by-attributes.yaml new file mode 100755 index 000000000000..c83ff43390cc --- /dev/null +++ b/.chloggen/count-by-attributes.yaml @@ -0,0 +1,16 @@ +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: countconnector + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Add ability to count by attributes + +# One or more tracking issues related to the change +issues: [19432] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: diff --git a/connector/countconnector/README.md b/connector/countconnector/README.md index 2d9347282646..b8e397ba2648 100644 --- a/connector/countconnector/README.md +++ b/connector/countconnector/README.md @@ -62,11 +62,15 @@ Optionally, emit custom counts by defining metrics under one or more of the foll - `datapoints` - `logs` -Under each custom metric name, specify one or more conditions using [OTTL Syntax]. -Data that matches any one of the conditions will be counted. i.e. Conditions are ORed together. - Optionally, specify a description for the metric. +Note: If any custom metrics are defined for a data type, the default metric will not be emitted. + +#### Conditions + +Conditions may be specified for custom metrics. If specified, data that matches any one +of the conditions will be counted. i.e. Conditions are ORed together. + ```yaml receivers: foo: @@ -82,7 +86,29 @@ connectors: - 'name == "prodevent"' ``` -Note: If any custom metrics are defined for a data type, the default metric will not be emitted. +#### Attributes + +`spans`, `spanevents`, `datapoints`, and `logs` may be counted according to attributes. + +If attributes are specified for custom metrics, a separate count will be generated for each unique +set of attribute values. Each count will be emitted as a data point on the same metric. + +Optionally, include a `default_value` for an attribute, to count data that does not contain the attribute. + +```yaml +receivers: + foo: +exporters: + bar: +connectors: + count: + logs: + my.log.count: + description: The number of logs from each environment. + attributes: + - key: env + default_value: unspecified_environment +``` ### Example Usage @@ -177,6 +203,32 @@ service: exporters: [bar] ``` +Count logs with a severity of ERROR or higher. Maintain a separate count for each environment. + +```yaml +receivers: + foo: +exporters: + bar: +connectors: + count: + logs: + my.error.log.count: + description: Error+ logs. + conditions: + - `severity_number >= SEVERITY_NUMBER_ERROR` + attributes: + - key: env +service: + pipelines: + logs: + receivers: [foo] + exporters: [count] + metrics: + receivers: [count] + exporters: [bar] +``` + Count all spans and span events (default behavior). Count metrics and data points based on the `env` attribute. ```yaml diff --git a/connector/countconnector/config.go b/connector/countconnector/config.go index fb90b8ba0fcb..df23b3005292 100644 --- a/connector/countconnector/config.go +++ b/connector/countconnector/config.go @@ -39,11 +39,17 @@ const ( // Config for the connector type Config struct { - Spans map[string]MetricInfo `mapstructure:"spans"` - SpanEvents map[string]MetricInfo `mapstructure:"spanevents"` - Metrics map[string]MetricInfo `mapstructure:"metrics"` - DataPoints map[string]MetricInfo `mapstructure:"datapoints"` - Logs map[string]MetricInfo `mapstructure:"logs"` + Spans map[string]MetricInfoWithAttributes `mapstructure:"spans"` + SpanEvents map[string]MetricInfoWithAttributes `mapstructure:"spanevents"` + Metrics map[string]MetricInfo `mapstructure:"metrics"` + DataPoints map[string]MetricInfoWithAttributes `mapstructure:"datapoints"` + Logs map[string]MetricInfoWithAttributes `mapstructure:"logs"` +} + +// MetricInfoWithAttributes for a data type +type MetricInfoWithAttributes struct { + MetricInfo `mapstructure:",squash"` + Attributes []AttributeConfig `mapstructure:"attributes"` } // MetricInfo for a data type @@ -52,6 +58,11 @@ type MetricInfo struct { Conditions []string `mapstructure:"conditions"` } +type AttributeConfig struct { + Key string `mapstructure:"key"` + DefaultValue string `mapstructure:"default_value"` +} + func (c *Config) Validate() error { for name, info := range c.Spans { if name == "" { @@ -64,6 +75,9 @@ func (c *Config) Validate() error { if _, err = parseConditions(parser, info.Conditions); 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) + } } for name, info := range c.SpanEvents { if name == "" { @@ -76,6 +90,9 @@ func (c *Config) Validate() error { if _, err = parseConditions(parser, info.Conditions); err != nil { return fmt.Errorf("spanevents condition: metric %q: %w", name, err) } + if err := info.validateAttributes(); err != nil { + return fmt.Errorf("spans attributes: metric %q: %w", name, err) + } } for name, info := range c.Metrics { if name == "" { @@ -101,6 +118,9 @@ func (c *Config) Validate() error { if _, err = parseConditions(parser, info.Conditions); 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) + } } for name, info := range c.Logs { if name == "" { @@ -113,6 +133,18 @@ func (c *Config) Validate() error { if _, err = parseConditions(parser, info.Conditions); err != nil { return fmt.Errorf("logs condition: metric %q: %w", name, err) } + if err := info.validateAttributes(); err != nil { + return fmt.Errorf("spans attributes: metric %q: %w", name, err) + } + } + return nil +} + +func (i *MetricInfoWithAttributes) validateAttributes() error { + for _, attr := range i.Attributes { + if attr.Key == "" { + return fmt.Errorf("attribute key missing") + } } return nil } @@ -148,18 +180,22 @@ func (c *Config) Unmarshal(componentParser *confmap.Conf) error { return nil } -func defaultSpansConfig() map[string]MetricInfo { - return map[string]MetricInfo{ +func defaultSpansConfig() map[string]MetricInfoWithAttributes { + return map[string]MetricInfoWithAttributes{ defaultMetricNameSpans: { - Description: defaultMetricDescSpans, + MetricInfo: MetricInfo{ + Description: defaultMetricDescSpans, + }, }, } } -func defaultSpanEventsConfig() map[string]MetricInfo { - return map[string]MetricInfo{ +func defaultSpanEventsConfig() map[string]MetricInfoWithAttributes { + return map[string]MetricInfoWithAttributes{ defaultMetricNameSpanEvents: { - Description: defaultMetricDescSpanEvents, + MetricInfo: MetricInfo{ + Description: defaultMetricDescSpanEvents, + }, }, } } @@ -172,18 +208,22 @@ func defaultMetricsConfig() map[string]MetricInfo { } } -func defaultDataPointsConfig() map[string]MetricInfo { - return map[string]MetricInfo{ +func defaultDataPointsConfig() map[string]MetricInfoWithAttributes { + return map[string]MetricInfoWithAttributes{ defaultMetricNameDataPoints: { - Description: defaultMetricDescDataPoints, + MetricInfo: MetricInfo{ + Description: defaultMetricDescDataPoints, + }, }, } } -func defaultLogsConfig() map[string]MetricInfo { - return map[string]MetricInfo{ +func defaultLogsConfig() map[string]MetricInfoWithAttributes { + return map[string]MetricInfoWithAttributes{ defaultMetricNameLogs: { - Description: defaultMetricDescLogs, + MetricInfo: MetricInfo{ + Description: defaultMetricDescLogs, + }, }, } } diff --git a/connector/countconnector/config_test.go b/connector/countconnector/config_test.go index a68b2fb79de1..825c029bfb70 100644 --- a/connector/countconnector/config_test.go +++ b/connector/countconnector/config_test.go @@ -33,14 +33,18 @@ func TestLoadConfig(t *testing.T) { { name: "", expect: &Config{ - Spans: map[string]MetricInfo{ + Spans: map[string]MetricInfoWithAttributes{ defaultMetricNameSpans: { - Description: defaultMetricDescSpans, + MetricInfo: MetricInfo{ + Description: defaultMetricDescSpans, + }, }, }, - SpanEvents: map[string]MetricInfo{ + SpanEvents: map[string]MetricInfoWithAttributes{ defaultMetricNameSpanEvents: { - Description: defaultMetricDescSpanEvents, + MetricInfo: MetricInfo{ + Description: defaultMetricDescSpanEvents, + }, }, }, Metrics: map[string]MetricInfo{ @@ -48,14 +52,18 @@ func TestLoadConfig(t *testing.T) { Description: defaultMetricDescMetrics, }, }, - DataPoints: map[string]MetricInfo{ + DataPoints: map[string]MetricInfoWithAttributes{ defaultMetricNameDataPoints: { - Description: defaultMetricDescDataPoints, + MetricInfo: MetricInfo{ + Description: defaultMetricDescDataPoints, + }, }, }, - Logs: map[string]MetricInfo{ + Logs: map[string]MetricInfoWithAttributes{ defaultMetricNameLogs: { - Description: defaultMetricDescLogs, + MetricInfo: MetricInfo{ + Description: defaultMetricDescLogs, + }, }, }, }, @@ -63,14 +71,18 @@ func TestLoadConfig(t *testing.T) { { name: "custom_description", expect: &Config{ - Spans: map[string]MetricInfo{ + Spans: map[string]MetricInfoWithAttributes{ defaultMetricNameSpans: { - Description: "My description for default span count metric.", + MetricInfo: MetricInfo{ + Description: "My description for default span count metric.", + }, }, }, - SpanEvents: map[string]MetricInfo{ + SpanEvents: map[string]MetricInfoWithAttributes{ defaultMetricNameSpanEvents: { - Description: "My description for default span event count metric.", + MetricInfo: MetricInfo{ + Description: "My description for default span event count metric.", + }, }, }, Metrics: map[string]MetricInfo{ @@ -78,14 +90,18 @@ func TestLoadConfig(t *testing.T) { Description: "My description for default metric count metric.", }, }, - DataPoints: map[string]MetricInfo{ + DataPoints: map[string]MetricInfoWithAttributes{ defaultMetricNameDataPoints: { - Description: "My description for default datapoint count metric.", + MetricInfo: MetricInfo{ + Description: "My description for default datapoint count metric.", + }, }, }, - Logs: map[string]MetricInfo{ + Logs: map[string]MetricInfoWithAttributes{ defaultMetricNameLogs: { - Description: "My description for default log count metric.", + MetricInfo: MetricInfo{ + Description: "My description for default log count metric.", + }, }, }, }, @@ -93,14 +109,18 @@ func TestLoadConfig(t *testing.T) { { name: "custom_metric", expect: &Config{ - Spans: map[string]MetricInfo{ + Spans: map[string]MetricInfoWithAttributes{ "my.span.count": { - Description: "My span count.", + MetricInfo: MetricInfo{ + Description: "My span count.", + }, }, }, - SpanEvents: map[string]MetricInfo{ + SpanEvents: map[string]MetricInfoWithAttributes{ "my.spanevent.count": { - Description: "My span event count.", + MetricInfo: MetricInfo{ + Description: "My span event count.", + }, }, }, Metrics: map[string]MetricInfo{ @@ -108,14 +128,18 @@ func TestLoadConfig(t *testing.T) { Description: "My metric count.", }, }, - DataPoints: map[string]MetricInfo{ + DataPoints: map[string]MetricInfoWithAttributes{ "my.datapoint.count": { - Description: "My data point count.", + MetricInfo: MetricInfo{ + Description: "My data point count.", + }, }, }, - Logs: map[string]MetricInfo{ + Logs: map[string]MetricInfoWithAttributes{ "my.logrecord.count": { - Description: "My log record count.", + MetricInfo: MetricInfo{ + Description: "My log record count.", + }, }, }, }, @@ -123,16 +147,20 @@ func TestLoadConfig(t *testing.T) { { name: "condition", expect: &Config{ - Spans: map[string]MetricInfo{ + Spans: map[string]MetricInfoWithAttributes{ "my.span.count": { - Description: "My span count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s") == true`}, + MetricInfo: MetricInfo{ + Description: "My span count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s") == true`}, + }, }, }, - SpanEvents: map[string]MetricInfo{ + SpanEvents: map[string]MetricInfoWithAttributes{ "my.spanevent.count": { - Description: "My span event count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e") == true`}, + MetricInfo: MetricInfo{ + Description: "My span event count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e") == true`}, + }, }, }, Metrics: map[string]MetricInfo{ @@ -141,16 +169,20 @@ func TestLoadConfig(t *testing.T) { Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-m") == true`}, }, }, - DataPoints: map[string]MetricInfo{ + DataPoints: map[string]MetricInfoWithAttributes{ "my.datapoint.count": { - Description: "My data point count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d") == true`}, + MetricInfo: MetricInfo{ + Description: "My data point count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d") == true`}, + }, }, }, - Logs: map[string]MetricInfo{ + Logs: map[string]MetricInfoWithAttributes{ "my.logrecord.count": { - Description: "My log record count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l") == true`}, + MetricInfo: MetricInfo{ + Description: "My log record count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l") == true`}, + }, }, }, }, @@ -158,21 +190,25 @@ func TestLoadConfig(t *testing.T) { { name: "multiple_condition", expect: &Config{ - Spans: map[string]MetricInfo{ + Spans: map[string]MetricInfoWithAttributes{ "my.span.count": { - Description: "My span count.", - Conditions: []string{ - `IsMatch(resource.attributes["host.name"], "pod-s") == true`, - `IsMatch(resource.attributes["foo"], "bar-s") == true`, + MetricInfo: MetricInfo{ + Description: "My span count.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-s") == true`, + `IsMatch(resource.attributes["foo"], "bar-s") == true`, + }, }, }, }, - SpanEvents: map[string]MetricInfo{ + SpanEvents: map[string]MetricInfoWithAttributes{ "my.spanevent.count": { - Description: "My span event count.", - Conditions: []string{ - `IsMatch(resource.attributes["host.name"], "pod-e") == true`, - `IsMatch(resource.attributes["foo"], "bar-e") == true`, + MetricInfo: MetricInfo{ + Description: "My span event count.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-e") == true`, + `IsMatch(resource.attributes["foo"], "bar-e") == true`, + }, }, }, }, @@ -185,21 +221,75 @@ func TestLoadConfig(t *testing.T) { }, }, }, - DataPoints: map[string]MetricInfo{ + DataPoints: map[string]MetricInfoWithAttributes{ "my.datapoint.count": { - Description: "My data point count.", - Conditions: []string{ - `IsMatch(resource.attributes["host.name"], "pod-d") == true`, - `IsMatch(resource.attributes["foo"], "bar-d") == true`, + MetricInfo: MetricInfo{ + Description: "My data point count.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-d") == true`, + `IsMatch(resource.attributes["foo"], "bar-d") == true`, + }, }, }, }, - Logs: map[string]MetricInfo{ + Logs: map[string]MetricInfoWithAttributes{ "my.logrecord.count": { - Description: "My log record count.", - Conditions: []string{ - `IsMatch(resource.attributes["host.name"], "pod-l") == true`, - `IsMatch(resource.attributes["foo"], "bar-l") == true`, + MetricInfo: MetricInfo{ + Description: "My log record count.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-l") == true`, + `IsMatch(resource.attributes["foo"], "bar-l") == true`, + }, + }, + }, + }, + }, + }, + { + name: "attribute", + expect: &Config{ + Spans: map[string]MetricInfoWithAttributes{ + "my.span.count": { + MetricInfo: MetricInfo{ + Description: "My span count by environment.", + }, + Attributes: []AttributeConfig{ + {Key: "env"}, + }, + }, + }, + SpanEvents: map[string]MetricInfoWithAttributes{ + "my.spanevent.count": { + MetricInfo: MetricInfo{ + Description: "My span event count by environment.", + }, + Attributes: []AttributeConfig{ + {Key: "env"}, + }, + }, + }, + Metrics: map[string]MetricInfo{ + "my.metric.count": { + Description: "My metric count.", + }, + }, + DataPoints: map[string]MetricInfoWithAttributes{ + "my.datapoint.count": { + MetricInfo: MetricInfo{ + Description: "My data point count by environment.", + }, + Attributes: []AttributeConfig{ + {Key: "env"}, + }, + }, + }, + Logs: map[string]MetricInfoWithAttributes{ + "my.logrecord.count": { + MetricInfo: MetricInfo{ + Description: "My log record count by environment.", + }, + Attributes: []AttributeConfig{ + {Key: "env"}, }, }, }, @@ -208,20 +298,48 @@ func TestLoadConfig(t *testing.T) { { name: "multiple_metrics", expect: &Config{ - Spans: map[string]MetricInfo{ + Spans: map[string]MetricInfoWithAttributes{ "my.span.count": { - Description: "My span count."}, + MetricInfo: MetricInfo{ + Description: "My span count.", + }, + }, "limited.span.count": { - Description: "Limited span count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s") == true`}, + MetricInfo: MetricInfo{ + Description: "Limited span count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s") == true`}, + }, + Attributes: []AttributeConfig{ + { + Key: "env", + }, + { + Key: "component", + DefaultValue: "other", + }, + }, }, }, - SpanEvents: map[string]MetricInfo{ + SpanEvents: map[string]MetricInfoWithAttributes{ "my.spanevent.count": { - Description: "My span event count."}, + MetricInfo: MetricInfo{ + Description: "My span event count.", + }, + }, "limited.spanevent.count": { - Description: "Limited span event count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e") == true`}, + MetricInfo: MetricInfo{ + Description: "Limited span event count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e") == true`}, + }, + Attributes: []AttributeConfig{ + { + Key: "env", + }, + { + Key: "component", + DefaultValue: "other", + }, + }, }, }, Metrics: map[string]MetricInfo{ @@ -232,22 +350,48 @@ func TestLoadConfig(t *testing.T) { Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-m") == true`}, }, }, - DataPoints: map[string]MetricInfo{ + DataPoints: map[string]MetricInfoWithAttributes{ "my.datapoint.count": { - Description: "My data point count.", + MetricInfo: MetricInfo{ + Description: "My data point count.", + }, }, "limited.datapoint.count": { - Description: "Limited data point count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d") == true`}, + MetricInfo: MetricInfo{ + Description: "Limited data point count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d") == true`}, + }, + Attributes: []AttributeConfig{ + { + Key: "env", + }, + { + Key: "component", + DefaultValue: "other", + }, + }, }, }, - Logs: map[string]MetricInfo{ + Logs: map[string]MetricInfoWithAttributes{ "my.logrecord.count": { - Description: "My log record count.", + MetricInfo: MetricInfo{ + Description: "My log record count.", + }, }, "limited.logrecord.count": { - Description: "Limited log record count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l") == true`}, + MetricInfo: MetricInfo{ + Description: "Limited log record count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l") == true`}, + }, + Attributes: []AttributeConfig{ + { + Key: "env", + }, + { + Key: "component", + DefaultValue: "other", + }, + }, }, }, }, @@ -280,9 +424,11 @@ func TestConfigErrors(t *testing.T) { { name: "missing_metric_name_span", input: &Config{ - Spans: map[string]MetricInfo{ + Spans: map[string]MetricInfoWithAttributes{ "": { - Description: defaultMetricDescSpans, + MetricInfo: MetricInfo{ + Description: defaultMetricDescSpans, + }, }, }, }, @@ -291,9 +437,11 @@ func TestConfigErrors(t *testing.T) { { name: "missing_metric_name_spanevent", input: &Config{ - SpanEvents: map[string]MetricInfo{ + SpanEvents: map[string]MetricInfoWithAttributes{ "": { - Description: defaultMetricDescSpans, + MetricInfo: MetricInfo{ + Description: defaultMetricDescSpans, + }, }, }, }, @@ -313,9 +461,11 @@ func TestConfigErrors(t *testing.T) { { name: "missing_metric_name_datapoint", input: &Config{ - DataPoints: map[string]MetricInfo{ + DataPoints: map[string]MetricInfoWithAttributes{ "": { - Description: defaultMetricDescSpans, + MetricInfo: MetricInfo{ + Description: defaultMetricDescSpans, + }, }, }, }, @@ -324,9 +474,11 @@ func TestConfigErrors(t *testing.T) { { name: "missing_metric_name_log", input: &Config{ - Logs: map[string]MetricInfo{ + Logs: map[string]MetricInfoWithAttributes{ "": { - Description: defaultMetricDescSpans, + MetricInfo: MetricInfo{ + Description: defaultMetricDescSpans, + }, }, }, }, @@ -335,10 +487,12 @@ func TestConfigErrors(t *testing.T) { { name: "invalid_condition_span", input: &Config{ - Spans: map[string]MetricInfo{ + Spans: map[string]MetricInfoWithAttributes{ defaultMetricNameSpans: { - Description: defaultMetricDescSpans, - Conditions: []string{"invalid condition"}, + MetricInfo: MetricInfo{ + Description: defaultMetricDescSpans, + Conditions: []string{"invalid condition"}, + }, }, }, }, @@ -347,10 +501,12 @@ func TestConfigErrors(t *testing.T) { { name: "invalid_condition_spanevent", input: &Config{ - SpanEvents: map[string]MetricInfo{ + SpanEvents: map[string]MetricInfoWithAttributes{ defaultMetricNameSpanEvents: { - Description: defaultMetricDescSpans, - Conditions: []string{"invalid condition"}, + MetricInfo: MetricInfo{ + Description: defaultMetricDescSpans, + Conditions: []string{"invalid condition"}, + }, }, }, }, @@ -371,10 +527,12 @@ func TestConfigErrors(t *testing.T) { { name: "invalid_condition_datapoint", input: &Config{ - DataPoints: map[string]MetricInfo{ + DataPoints: map[string]MetricInfoWithAttributes{ defaultMetricNameDataPoints: { - Description: defaultMetricDescSpans, - Conditions: []string{"invalid condition"}, + MetricInfo: MetricInfo{ + Description: defaultMetricDescSpans, + Conditions: []string{"invalid condition"}, + }, }, }, }, @@ -383,10 +541,12 @@ func TestConfigErrors(t *testing.T) { { name: "invalid_condition_log", input: &Config{ - Logs: map[string]MetricInfo{ + Logs: map[string]MetricInfoWithAttributes{ defaultMetricNameLogs: { - Description: defaultMetricDescSpans, - Conditions: []string{"invalid condition"}, + MetricInfo: MetricInfo{ + Description: defaultMetricDescSpans, + Conditions: []string{"invalid condition"}, + }, }, }, }, diff --git a/connector/countconnector/connector.go b/connector/countconnector/connector.go index 7d3dfc98f882..086b9919fd1f 100644 --- a/connector/countconnector/connector.go +++ b/connector/countconnector/connector.go @@ -41,11 +41,11 @@ type count struct { component.StartFunc component.ShutdownFunc - spansCounterFactory *counterFactory[ottlspan.TransformContext] - spanEventsCounterFactory *counterFactory[ottlspanevent.TransformContext] - metricsCounterFactory *counterFactory[ottlmetric.TransformContext] - dataPointsCounterFactory *counterFactory[ottldatapoint.TransformContext] - logsCounterFactory *counterFactory[ottllog.TransformContext] + spansMetricDefs map[string]metricDef[ottlspan.TransformContext] + spanEventsMetricDefs map[string]metricDef[ottlspanevent.TransformContext] + metricsMetricDefs map[string]metricDef[ottlmetric.TransformContext] + dataPointsMetricDefs map[string]metricDef[ottldatapoint.TransformContext] + logsMetricDefs map[string]metricDef[ottllog.TransformContext] } func (c *count) Capabilities() consumer.Capabilities { @@ -58,31 +58,36 @@ func (c *count) ConsumeTraces(ctx context.Context, td ptrace.Traces) error { countMetrics.ResourceMetrics().EnsureCapacity(td.ResourceSpans().Len()) for i := 0; i < td.ResourceSpans().Len(); i++ { resourceSpan := td.ResourceSpans().At(i) + spansCounter := newCounter[ottlspan.TransformContext](c.spansMetricDefs) + spanEventsCounter := newCounter[ottlspanevent.TransformContext](c.spanEventsMetricDefs) - countResource := countMetrics.ResourceMetrics().AppendEmpty() - resourceSpan.Resource().Attributes().CopyTo(countResource.Resource().Attributes()) - - countResource.ScopeMetrics().EnsureCapacity(resourceSpan.ScopeSpans().Len()) - countScope := countResource.ScopeMetrics().AppendEmpty() - countScope.Scope().SetName(scopeName) - - spansCounter := c.spansCounterFactory.newCounter() - spanEventsCounter := c.spanEventsCounterFactory.newCounter() for j := 0; j < resourceSpan.ScopeSpans().Len(); j++ { scopeSpan := resourceSpan.ScopeSpans().At(j) for k := 0; k < scopeSpan.Spans().Len(); k++ { span := scopeSpan.Spans().At(k) sCtx := ottlspan.NewTransformContext(span, scopeSpan.Scope(), resourceSpan.Resource()) - errors = multierr.Append(errors, spansCounter.update(ctx, sCtx)) + errors = multierr.Append(errors, spansCounter.update(ctx, span.Attributes(), sCtx)) for l := 0; l < span.Events().Len(); l++ { event := span.Events().At(l) eCtx := ottlspanevent.NewTransformContext(event, span, scopeSpan.Scope(), resourceSpan.Resource()) - errors = multierr.Append(errors, spanEventsCounter.update(ctx, eCtx)) + errors = multierr.Append(errors, spanEventsCounter.update(ctx, event.Attributes(), eCtx)) } } } + + if len(spansCounter.counts)+len(spanEventsCounter.counts) == 0 { + continue // don't add an empty resource + } + + countResource := countMetrics.ResourceMetrics().AppendEmpty() + resourceSpan.Resource().Attributes().CopyTo(countResource.Resource().Attributes()) + + countResource.ScopeMetrics().EnsureCapacity(resourceSpan.ScopeSpans().Len()) + countScope := countResource.ScopeMetrics().AppendEmpty() + countScope.Scope().SetName(scopeName) + spansCounter.appendMetricsTo(countScope.Metrics()) spanEventsCounter.appendMetricsTo(countScope.Metrics()) } @@ -98,32 +103,65 @@ func (c *count) ConsumeMetrics(ctx context.Context, md pmetric.Metrics) error { countMetrics.ResourceMetrics().EnsureCapacity(md.ResourceMetrics().Len()) for i := 0; i < md.ResourceMetrics().Len(); i++ { resourceMetric := md.ResourceMetrics().At(i) + metricsCounter := newCounter[ottlmetric.TransformContext](c.metricsMetricDefs) + dataPointsCounter := newCounter[ottldatapoint.TransformContext](c.dataPointsMetricDefs) - countResource := countMetrics.ResourceMetrics().AppendEmpty() - resourceMetric.Resource().Attributes().CopyTo(countResource.Resource().Attributes()) - - countResource.ScopeMetrics().EnsureCapacity(resourceMetric.ScopeMetrics().Len()) - countScope := countResource.ScopeMetrics().AppendEmpty() - countScope.Scope().SetName(scopeName) - - metricsCounter := c.metricsCounterFactory.newCounter() - datapointsCounter := c.dataPointsCounterFactory.newCounter() for j := 0; j < resourceMetric.ScopeMetrics().Len(); j++ { scopeMetrics := resourceMetric.ScopeMetrics().At(j) for k := 0; k < scopeMetrics.Metrics().Len(); k++ { metric := scopeMetrics.Metrics().At(k) mCtx := ottlmetric.NewTransformContext(metric, scopeMetrics.Scope(), resourceMetric.Resource()) - errors = multierr.Append(errors, metricsCounter.update(ctx, mCtx)) - - dCtxs := dataPointContexts(metric, scopeMetrics.Metrics(), scopeMetrics.Scope(), resourceMetric.Resource()) - for l := 0; l < len(dCtxs); l++ { - errors = multierr.Append(errors, datapointsCounter.update(ctx, dCtxs[l])) + errors = multierr.Append(errors, metricsCounter.update(ctx, pcommon.NewMap(), mCtx)) + + switch metric.Type() { + case pmetric.MetricTypeGauge: + dps := metric.Gauge().DataPoints() + for i := 0; i < dps.Len(); i++ { + dCtx := ottldatapoint.NewTransformContext(dps.At(i), metric, scopeMetrics.Metrics(), scopeMetrics.Scope(), resourceMetric.Resource()) + errors = multierr.Append(errors, dataPointsCounter.update(ctx, dps.At(i).Attributes(), dCtx)) + } + case pmetric.MetricTypeSum: + dps := metric.Sum().DataPoints() + for i := 0; i < dps.Len(); i++ { + dCtx := ottldatapoint.NewTransformContext(dps.At(i), metric, scopeMetrics.Metrics(), scopeMetrics.Scope(), resourceMetric.Resource()) + errors = multierr.Append(errors, dataPointsCounter.update(ctx, dps.At(i).Attributes(), dCtx)) + } + case pmetric.MetricTypeSummary: + dps := metric.Summary().DataPoints() + for i := 0; i < dps.Len(); i++ { + dCtx := ottldatapoint.NewTransformContext(dps.At(i), metric, scopeMetrics.Metrics(), scopeMetrics.Scope(), resourceMetric.Resource()) + errors = multierr.Append(errors, dataPointsCounter.update(ctx, dps.At(i).Attributes(), dCtx)) + } + case pmetric.MetricTypeHistogram: + dps := metric.Histogram().DataPoints() + for i := 0; i < dps.Len(); i++ { + dCtx := ottldatapoint.NewTransformContext(dps.At(i), metric, scopeMetrics.Metrics(), scopeMetrics.Scope(), resourceMetric.Resource()) + errors = multierr.Append(errors, dataPointsCounter.update(ctx, dps.At(i).Attributes(), dCtx)) + } + case pmetric.MetricTypeExponentialHistogram: + dps := metric.ExponentialHistogram().DataPoints() + for i := 0; i < dps.Len(); i++ { + dCtx := ottldatapoint.NewTransformContext(dps.At(i), metric, scopeMetrics.Metrics(), scopeMetrics.Scope(), resourceMetric.Resource()) + errors = multierr.Append(errors, dataPointsCounter.update(ctx, dps.At(i).Attributes(), dCtx)) + } } } } + + if len(metricsCounter.counts)+len(dataPointsCounter.counts) == 0 { + continue // don't add an empty resource + } + + countResource := countMetrics.ResourceMetrics().AppendEmpty() + resourceMetric.Resource().Attributes().CopyTo(countResource.Resource().Attributes()) + + countResource.ScopeMetrics().EnsureCapacity(resourceMetric.ScopeMetrics().Len()) + countScope := countResource.ScopeMetrics().AppendEmpty() + countScope.Scope().SetName(scopeName) + metricsCounter.appendMetricsTo(countScope.Metrics()) - datapointsCounter.appendMetricsTo(countScope.Metrics()) + dataPointsCounter.appendMetricsTo(countScope.Metrics()) } if errors != nil { return errors @@ -131,62 +169,36 @@ func (c *count) ConsumeMetrics(ctx context.Context, md pmetric.Metrics) error { return c.metricsConsumer.ConsumeMetrics(ctx, countMetrics) } -func dataPointContexts(metric pmetric.Metric, metrics pmetric.MetricSlice, scope pcommon.InstrumentationScope, resource pcommon.Resource) []ottldatapoint.TransformContext { - dCtxs := []ottldatapoint.TransformContext{} - switch metric.Type() { - case pmetric.MetricTypeGauge: - dps := metric.Gauge().DataPoints() - for i := 0; i < dps.Len(); i++ { - dCtxs = append(dCtxs, ottldatapoint.NewTransformContext(dps.At(i), metric, metrics, scope, resource)) - } - case pmetric.MetricTypeSum: - dps := metric.Sum().DataPoints() - for i := 0; i < dps.Len(); i++ { - dCtxs = append(dCtxs, ottldatapoint.NewTransformContext(dps.At(i), metric, metrics, scope, resource)) - } - case pmetric.MetricTypeSummary: - dps := metric.Summary().DataPoints() - for i := 0; i < dps.Len(); i++ { - dCtxs = append(dCtxs, ottldatapoint.NewTransformContext(dps.At(i), metric, metrics, scope, resource)) - } - case pmetric.MetricTypeHistogram: - dps := metric.Histogram().DataPoints() - for i := 0; i < dps.Len(); i++ { - dCtxs = append(dCtxs, ottldatapoint.NewTransformContext(dps.At(i), metric, metrics, scope, resource)) - } - case pmetric.MetricTypeExponentialHistogram: - dps := metric.ExponentialHistogram().DataPoints() - for i := 0; i < dps.Len(); i++ { - dCtxs = append(dCtxs, ottldatapoint.NewTransformContext(dps.At(i), metric, metrics, scope, resource)) - } - } - return dCtxs -} - func (c *count) ConsumeLogs(ctx context.Context, ld plog.Logs) error { var errors error countMetrics := pmetric.NewMetrics() countMetrics.ResourceMetrics().EnsureCapacity(ld.ResourceLogs().Len()) for i := 0; i < ld.ResourceLogs().Len(); i++ { resourceLog := ld.ResourceLogs().At(i) + counter := newCounter[ottllog.TransformContext](c.logsMetricDefs) - countResource := countMetrics.ResourceMetrics().AppendEmpty() - resourceLog.Resource().Attributes().CopyTo(countResource.Resource().Attributes()) - - countResource.ScopeMetrics().EnsureCapacity(resourceLog.ScopeLogs().Len()) - countScope := countResource.ScopeMetrics().AppendEmpty() - countScope.Scope().SetName(scopeName) - - counter := c.logsCounterFactory.newCounter() for j := 0; j < resourceLog.ScopeLogs().Len(); j++ { scopeLogs := resourceLog.ScopeLogs().At(j) for k := 0; k < scopeLogs.LogRecords().Len(); k++ { logRecord := scopeLogs.LogRecords().At(k) + lCtx := ottllog.NewTransformContext(logRecord, scopeLogs.Scope(), resourceLog.Resource()) - errors = multierr.Append(errors, counter.update(ctx, lCtx)) + errors = multierr.Append(errors, counter.update(ctx, logRecord.Attributes(), lCtx)) } } + + if len(counter.counts) == 0 { + continue // don't add an empty resource + } + + countResource := countMetrics.ResourceMetrics().AppendEmpty() + resourceLog.Resource().Attributes().CopyTo(countResource.Resource().Attributes()) + + countResource.ScopeMetrics().EnsureCapacity(resourceLog.ScopeLogs().Len()) + countScope := countResource.ScopeMetrics().AppendEmpty() + countScope.Scope().SetName(scopeName) + counter.appendMetricsTo(countScope.Metrics()) } if errors != nil { diff --git a/connector/countconnector/connector_test.go b/connector/countconnector/connector_test.go index e517dc139239..62aeff8e4d36 100644 --- a/connector/countconnector/connector_test.go +++ b/connector/countconnector/connector_test.go @@ -44,19 +44,23 @@ func TestTracesToMetrics(t *testing.T) { { name: "one_condition", cfg: &Config{ - Spans: map[string]MetricInfo{ + Spans: map[string]MetricInfoWithAttributes{ "span.count.if": { - Description: "Span count if ...", - Conditions: []string{ - `resource.attributes["resource-attr"] != "resource-attr-val-1"`, + MetricInfo: MetricInfo{ + Description: "Span count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + }, }, }, }, - SpanEvents: map[string]MetricInfo{ + SpanEvents: map[string]MetricInfoWithAttributes{ "spanevent.count.if": { - Description: "Span event count if ...", - Conditions: []string{ - `resource.attributes["resource-attr"] == "resource-attr-val-1"`, + MetricInfo: MetricInfo{ + Description: "Span event count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + }, }, }, }, @@ -65,21 +69,25 @@ func TestTracesToMetrics(t *testing.T) { { name: "multiple_conditions", cfg: &Config{ - Spans: map[string]MetricInfo{ + Spans: map[string]MetricInfoWithAttributes{ "span.count.if": { - Description: "Span count if ...", - Conditions: []string{ - `resource.attributes["resource-attr"] != "resource-attr-val-1"`, - `name == "operationB"`, + MetricInfo: MetricInfo{ + Description: "Span count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["span.optional"] != nil`, + }, }, }, }, - SpanEvents: map[string]MetricInfo{ + SpanEvents: map[string]MetricInfoWithAttributes{ "spanevent.count.if": { - Description: "Span event count if ...", - Conditions: []string{ - `resource.attributes["resource-attr"] != "resource-attr-val-1"`, - `name == "event-with-attr"`, + MetricInfo: MetricInfo{ + Description: "Span event count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["event.optional"] != nil`, + }, }, }, }, @@ -88,27 +96,171 @@ func TestTracesToMetrics(t *testing.T) { { name: "multiple_metrics", cfg: &Config{ - Spans: map[string]MetricInfo{ + Spans: map[string]MetricInfoWithAttributes{ "span.count.all": { - Description: "All spans count", + MetricInfo: MetricInfo{ + Description: "All spans count", + }, }, "span.count.if": { - Description: "Span count if ...", - Conditions: []string{ - `resource.attributes["resource-attr"] != "resource-attr-val-1"`, - `name == "operationB"`, + MetricInfo: MetricInfo{ + Description: "Span count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["span.optional"] != nil`, + }, }, }, }, - SpanEvents: map[string]MetricInfo{ + SpanEvents: map[string]MetricInfoWithAttributes{ "spanevent.count.all": { - Description: "All span events count", + MetricInfo: MetricInfo{ + Description: "All span events count", + }, }, "spanevent.count.if": { - Description: "Span event count if ...", - Conditions: []string{ - `resource.attributes["resource-attr"] != "resource-attr-val-1"`, - `name == "event-with-attr"`, + MetricInfo: MetricInfo{ + Description: "Span event count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["event.optional"] != nil`, + }, + }, + }, + }, + }, + }, + { + name: "one_attribute", + cfg: &Config{ + Spans: map[string]MetricInfoWithAttributes{ + "span.count.by_attr": { + MetricInfo: MetricInfo{ + Description: "Span count by attribute", + }, + Attributes: []AttributeConfig{ + { + Key: "span.required", + }, + }, + }, + }, + SpanEvents: map[string]MetricInfoWithAttributes{ + "spanevent.count.by_attr": { + MetricInfo: MetricInfo{ + Description: "Span event count by attribute", + }, + Attributes: []AttributeConfig{ + { + Key: "event.required", + }, + }, + }, + }, + }, + }, + { + name: "multiple_attributes", + cfg: &Config{ + Spans: map[string]MetricInfoWithAttributes{ + "span.count.by_attr": { + MetricInfo: MetricInfo{ + Description: "Span count by attributes", + }, + Attributes: []AttributeConfig{ + { + Key: "span.required", + }, + { + Key: "span.optional", + }, + }, + }, + }, + SpanEvents: map[string]MetricInfoWithAttributes{ + "spanevent.count.by_attr": { + MetricInfo: MetricInfo{ + Description: "Span event count by attributes", + }, + Attributes: []AttributeConfig{ + { + Key: "event.required", + }, + { + Key: "event.optional", + }, + }, + }, + }, + }, + }, + { + name: "default_attribute_value", + cfg: &Config{ + Spans: map[string]MetricInfoWithAttributes{ + "span.count.by_attr": { + MetricInfo: MetricInfo{ + Description: "Span count by attribute with default", + }, + Attributes: []AttributeConfig{ + { + Key: "span.required", + }, + { + Key: "span.optional", + DefaultValue: "other", + }, + }, + }, + }, + SpanEvents: map[string]MetricInfoWithAttributes{ + "spanevent.count.by_attr": { + MetricInfo: MetricInfo{ + Description: "Span event count by attribute with default", + }, + Attributes: []AttributeConfig{ + { + Key: "event.required", + }, + { + Key: "event.optional", + DefaultValue: "other", + }, + }, + }, + }, + }, + }, + { + name: "condition_and_attribute", + cfg: &Config{ + Spans: map[string]MetricInfoWithAttributes{ + "span.count.if.by_attr": { + MetricInfo: MetricInfo{ + Description: "Span count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + }, + }, + Attributes: []AttributeConfig{ + { + Key: "span.required", + }, + }, + }, + }, + SpanEvents: map[string]MetricInfoWithAttributes{ + "spanevent.count.if.by_attr": { + MetricInfo: MetricInfo{ + Description: "Span event count by attribute if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + }, + }, + Attributes: []AttributeConfig{ + { + Key: "event.required", + }, }, }, }, @@ -143,7 +295,10 @@ func TestTracesToMetrics(t *testing.T) { expected, err := golden.ReadMetrics(filepath.Join("testdata", "traces", tc.name+".json")) assert.NoError(t, err) assert.NoError(t, pmetrictest.CompareMetrics(expected, allMetrics[0], - pmetrictest.IgnoreTimestamp(), pmetrictest.IgnoreMetricsOrder())) + pmetrictest.IgnoreTimestamp(), + pmetrictest.IgnoreResourceMetricsOrder(), + pmetrictest.IgnoreMetricsOrder(), + pmetrictest.IgnoreMetricDataPointsOrder())) }) } } @@ -167,15 +322,17 @@ func TestMetricsToMetrics(t *testing.T) { "metric.count.if": { Description: "Metric count if ...", Conditions: []string{ - `resource.attributes["resource-attr-2"] != nil`, + `resource.attributes["resource.optional"] != nil`, }, }, }, - DataPoints: map[string]MetricInfo{ + DataPoints: map[string]MetricInfoWithAttributes{ "datapoint.count.if": { - Description: "Data point count if ...", - Conditions: []string{ - `resource.attributes["resource-attr-2"] == nil`, + MetricInfo: MetricInfo{ + Description: "Data point count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + }, }, }, }, @@ -188,17 +345,19 @@ func TestMetricsToMetrics(t *testing.T) { "metric.count.if": { Description: "Metric count if ...", Conditions: []string{ - `resource.attributes["resource-attr-2"] != nil`, + `resource.attributes["resource.optional"] != nil`, `type == METRIC_DATA_TYPE_HISTOGRAM`, }, }, }, - DataPoints: map[string]MetricInfo{ + DataPoints: map[string]MetricInfoWithAttributes{ "datapoint.count.if": { - Description: "Data point count if ...", - Conditions: []string{ - `resource.attributes["resource-attr-2"] == nil`, - `value_int == 123`, + MetricInfo: MetricInfo{ + Description: "Data point count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["datapoint.optional"] != nil`, + }, }, }, }, @@ -214,20 +373,102 @@ func TestMetricsToMetrics(t *testing.T) { "metric.count.if": { Description: "Metric count if ...", Conditions: []string{ - `resource.attributes["resource-attr-2"] != nil`, + `resource.attributes["resource.optional"] != nil`, `type == METRIC_DATA_TYPE_HISTOGRAM`, }, }, }, - DataPoints: map[string]MetricInfo{ + DataPoints: map[string]MetricInfoWithAttributes{ "datapoint.count.all": { - Description: "All data points count", + MetricInfo: MetricInfo{ + Description: "All data points count", + }, }, "datapoint.count.if": { - Description: "Data point count if ...", - Conditions: []string{ - `resource.attributes["resource-attr-2"] == nil`, - `value_int == 123`, + MetricInfo: MetricInfo{ + Description: "Data point count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["datapoint.optional"] != nil`, + }, + }, + }, + }, + }, + }, + { + name: "one_attribute", + cfg: &Config{ + DataPoints: map[string]MetricInfoWithAttributes{ + "datapoint.count.by_attr": { + MetricInfo: MetricInfo{ + Description: "Data point count by attribute", + }, + Attributes: []AttributeConfig{ + { + Key: "datapoint.required", + }, + }, + }, + }, + }, + }, + { + name: "multiple_attributes", + cfg: &Config{ + DataPoints: map[string]MetricInfoWithAttributes{ + "datapoint.count.by_attr": { + MetricInfo: MetricInfo{ + Description: "Data point count by attributes", + }, + Attributes: []AttributeConfig{ + { + Key: "datapoint.required", + }, + { + Key: "datapoint.optional", + }, + }, + }, + }, + }, + }, + { + name: "default_attribute_value", + cfg: &Config{ + DataPoints: map[string]MetricInfoWithAttributes{ + "datapoint.count.by_attr": { + MetricInfo: MetricInfo{ + Description: "Data point count by attribute with default", + }, + Attributes: []AttributeConfig{ + { + Key: "datapoint.required", + }, + { + Key: "datapoint.optional", + DefaultValue: "other", + }, + }, + }, + }, + }, + }, + { + name: "condition_and_attribute", + cfg: &Config{ + DataPoints: map[string]MetricInfoWithAttributes{ + "datapoint.count.if.by_attr": { + MetricInfo: MetricInfo{ + Description: "Data point count by attribute if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + }, + }, + Attributes: []AttributeConfig{ + { + Key: "datapoint.required", + }, }, }, }, @@ -262,7 +503,10 @@ func TestMetricsToMetrics(t *testing.T) { expected, err := golden.ReadMetrics(filepath.Join("testdata", "metrics", tc.name+".json")) assert.NoError(t, err) assert.NoError(t, pmetrictest.CompareMetrics(expected, allMetrics[0], - pmetrictest.IgnoreTimestamp(), pmetrictest.IgnoreMetricsOrder())) + pmetrictest.IgnoreTimestamp(), + pmetrictest.IgnoreResourceMetricsOrder(), + pmetrictest.IgnoreMetricsOrder(), + pmetrictest.IgnoreMetricDataPointsOrder())) }) } } @@ -279,11 +523,13 @@ func TestLogsToMetrics(t *testing.T) { { name: "one_condition", cfg: &Config{ - Logs: map[string]MetricInfo{ + Logs: map[string]MetricInfoWithAttributes{ "count.if": { - Description: "Count if ...", - Conditions: []string{ - `resource.attributes["resource-attr-2"] != nil`, + MetricInfo: MetricInfo{ + Description: "Count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + }, }, }, }, @@ -292,12 +538,14 @@ func TestLogsToMetrics(t *testing.T) { { name: "multiple_conditions", cfg: &Config{ - Logs: map[string]MetricInfo{ + Logs: map[string]MetricInfoWithAttributes{ "count.if": { - Description: "Count if ...", - Conditions: []string{ - `resource.attributes["resource-attr-2"] != nil`, - `attributes["customer"] == "acme"`, + MetricInfo: MetricInfo{ + Description: "Count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["log.optional"] != nil`, + }, }, }, }, @@ -306,14 +554,96 @@ func TestLogsToMetrics(t *testing.T) { { name: "multiple_metrics", cfg: &Config{ - Logs: map[string]MetricInfo{ + Logs: map[string]MetricInfoWithAttributes{ "count.all": { - Description: "All logs count", + MetricInfo: MetricInfo{ + Description: "All logs count", + }, }, "count.if": { - Description: "Count if ...", - Conditions: []string{ - `resource.attributes["resource-attr-2"] != nil`, + MetricInfo: MetricInfo{ + Description: "Count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + }, + }, + }, + }, + }, + }, + { + name: "one_attribute", + cfg: &Config{ + Logs: map[string]MetricInfoWithAttributes{ + "log.count.by_attr": { + MetricInfo: MetricInfo{ + Description: "Log count by attribute", + }, + Attributes: []AttributeConfig{ + { + Key: "log.required", + }, + }, + }, + }, + }, + }, + { + name: "multiple_attributes", + cfg: &Config{ + Logs: map[string]MetricInfoWithAttributes{ + "log.count.by_attr": { + MetricInfo: MetricInfo{ + Description: "Log count by attributes", + }, + Attributes: []AttributeConfig{ + { + Key: "log.required", + }, + { + Key: "log.optional", + }, + }, + }, + }, + }, + }, + { + name: "default_attribute_value", + cfg: &Config{ + Logs: map[string]MetricInfoWithAttributes{ + "log.count.by_attr": { + MetricInfo: MetricInfo{ + Description: "Log count by attribute with default", + }, + Attributes: []AttributeConfig{ + { + Key: "log.required", + }, + { + Key: "log.optional", + DefaultValue: "other", + }, + }, + }, + }, + }, + }, + { + name: "condition_and_attribute", + cfg: &Config{ + Logs: map[string]MetricInfoWithAttributes{ + "log.count.if.by_attr": { + MetricInfo: MetricInfo{ + Description: "Log count by attribute if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + }, + }, + Attributes: []AttributeConfig{ + { + Key: "log.required", + }, }, }, }, @@ -348,7 +678,10 @@ func TestLogsToMetrics(t *testing.T) { expected, err := golden.ReadMetrics(filepath.Join("testdata", "logs", tc.name+".json")) assert.NoError(t, err) assert.NoError(t, pmetrictest.CompareMetrics(expected, allMetrics[0], - pmetrictest.IgnoreTimestamp(), pmetrictest.IgnoreMetricsOrder())) + pmetrictest.IgnoreTimestamp(), + pmetrictest.IgnoreResourceMetricsOrder(), + pmetrictest.IgnoreMetricsOrder(), + pmetrictest.IgnoreMetricDataPointsOrder())) }) } } diff --git a/connector/countconnector/counter.go b/connector/countconnector/counter.go index 8bd12bacbbfb..a66ef9c72404 100644 --- a/connector/countconnector/counter.go +++ b/connector/countconnector/counter.go @@ -22,60 +22,98 @@ import ( "go.opentelemetry.io/collector/pdata/pmetric" "go.uber.org/multierr" - "github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter/expr" + "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil" ) -type counterFactory[K any] struct { - matchExprs map[string]expr.BoolExpr[K] - metricInfos map[string]MetricInfo -} +var noAttributes [16]byte = [16]byte{} -func (f *counterFactory[K]) newCounter() *counter[K] { +func newCounter[K any](metricDefs map[string]metricDef[K]) *counter[K] { return &counter[K]{ - matchExprs: f.matchExprs, - metricInfos: f.metricInfos, - counts: make(map[string]uint64, len(f.metricInfos)), - timestamp: time.Now(), + metricDefs: metricDefs, + counts: make(map[string]map[[16]byte]*attrCounter, len(metricDefs)), + timestamp: time.Now(), } } type counter[K any] struct { - matchExprs map[string]expr.BoolExpr[K] - metricInfos map[string]MetricInfo - counts map[string]uint64 - timestamp time.Time + metricDefs map[string]metricDef[K] + counts map[string]map[[16]byte]*attrCounter + timestamp time.Time +} + +type attrCounter struct { + attrs pcommon.Map + count uint64 } -func (c *counter[K]) update(ctx context.Context, tCtx K) error { +func (c *counter[K]) update(ctx context.Context, attrs pcommon.Map, tCtx K) error { var errors error - for name := range c.metricInfos { + for name, md := range c.metricDefs { + countAttrs := pcommon.NewMap() + for _, attr := range md.attrs { + if attrVal, ok := attrs.Get(attr.Key); ok { + countAttrs.PutStr(attr.Key, attrVal.Str()) + } else if attr.DefaultValue != "" { + countAttrs.PutStr(attr.Key, attr.DefaultValue) + } + } + + // Missing necessary attributes to be counted + if countAttrs.Len() != len(md.attrs) { + continue + } + // No conditions, so match all. - if c.matchExprs[name] == nil { - c.counts[name]++ + if md.condition == nil { + c.increment(name, countAttrs) continue } - if match, err := c.matchExprs[name].Eval(ctx, tCtx); err != nil { + if match, err := md.condition.Eval(ctx, tCtx); err != nil { errors = multierr.Append(errors, err) } else if match { - c.counts[name]++ + c.increment(name, countAttrs) } } return errors } +func (c *counter[K]) increment(metricName string, attrs pcommon.Map) error { + if _, ok := c.counts[metricName]; !ok { + c.counts[metricName] = make(map[[16]byte]*attrCounter) + } + + key := noAttributes + if attrs.Len() > 0 { + key = pdatautil.MapHash(attrs) + } + + if _, ok := c.counts[metricName][key]; !ok { + c.counts[metricName][key] = &attrCounter{attrs: attrs} + } + + c.counts[metricName][key].count++ + return nil +} + func (c *counter[K]) appendMetricsTo(metricSlice pmetric.MetricSlice) { - for name, info := range c.metricInfos { + for name, md := range c.metricDefs { + if len(c.counts[name]) == 0 { + continue + } countMetric := metricSlice.AppendEmpty() countMetric.SetName(name) - countMetric.SetDescription(info.Description) + countMetric.SetDescription(md.desc) sum := countMetric.SetEmptySum() // The delta value is always positive, so a value accumulated downstream is monotonic sum.SetIsMonotonic(true) sum.SetAggregationTemporality(pmetric.AggregationTemporalityDelta) - dp := sum.DataPoints().AppendEmpty() - dp.SetIntValue(int64(c.counts[name])) - // TODO determine appropriate start time - dp.SetTimestamp(pcommon.NewTimestampFromTime(c.timestamp)) + for _, dpCount := range c.counts[name] { + dp := sum.DataPoints().AppendEmpty() + dpCount.attrs.CopyTo(dp.Attributes()) + dp.SetIntValue(int64(dpCount.count)) + // TODO determine appropriate start time + dp.SetTimestamp(pcommon.NewTimestampFromTime(c.timestamp)) + } } } diff --git a/connector/countconnector/factory.go b/connector/countconnector/factory.go index 98e6918d9b43..eef4d6149acd 100644 --- a/connector/countconnector/factory.go +++ b/connector/countconnector/factory.go @@ -59,42 +59,46 @@ func createTracesToMetrics( ) (connector.Traces, error) { c := cfg.(*Config) - spanMatchExprs := make(map[string]expr.BoolExpr[ottlspan.TransformContext], len(c.Spans)) + spanMetricDefs := make(map[string]metricDef[ottlspan.TransformContext], len(c.Spans)) spanParser, err := newSpanParser(set.TelemetrySettings.Logger) if err != nil { return nil, err } for name, info := range c.Spans { - if len(info.Conditions) == 0 { - continue + md := metricDef[ottlspan.TransformContext]{ + desc: info.MetricInfo.Description, + attrs: info.Attributes, } - // Error checked in Config.Validate() - spanMatchExprs[name], _ = parseConditions(spanParser, info.Conditions) + if len(info.Conditions) > 0 { + // Error checked in Config.Validate() + condition, _ := parseConditions(spanParser, info.Conditions) + md.condition = condition + } + spanMetricDefs[name] = md } - spanEventMatchExprs := make(map[string]expr.BoolExpr[ottlspanevent.TransformContext], len(c.SpanEvents)) + spanEventMetricDefs := make(map[string]metricDef[ottlspanevent.TransformContext], len(c.SpanEvents)) spanEventParser, err := newSpanEventParser(set.TelemetrySettings.Logger) if err != nil { return nil, err } for name, info := range c.SpanEvents { - if len(info.Conditions) == 0 { - continue + md := metricDef[ottlspanevent.TransformContext]{ + desc: info.MetricInfo.Description, + attrs: info.Attributes, + } + if len(info.Conditions) > 0 { + // Error checked in Config.Validate() + condition, _ := parseConditions(spanEventParser, info.Conditions) + md.condition = condition } - // Error checked in Config.Validate() - spanEventMatchExprs[name], _ = parseConditions(spanEventParser, info.Conditions) + spanEventMetricDefs[name] = md } return &count{ - metricsConsumer: nextConsumer, - spansCounterFactory: &counterFactory[ottlspan.TransformContext]{ - matchExprs: spanMatchExprs, - metricInfos: c.Spans, - }, - spanEventsCounterFactory: &counterFactory[ottlspanevent.TransformContext]{ - matchExprs: spanEventMatchExprs, - metricInfos: c.SpanEvents, - }, + metricsConsumer: nextConsumer, + spansMetricDefs: spanMetricDefs, + spanEventsMetricDefs: spanEventMetricDefs, }, nil } @@ -107,42 +111,45 @@ func createMetricsToMetrics( ) (connector.Metrics, error) { c := cfg.(*Config) - metricMatchExprs := make(map[string]expr.BoolExpr[ottlmetric.TransformContext], len(c.Metrics)) + metricMetricDefs := make(map[string]metricDef[ottlmetric.TransformContext], len(c.Metrics)) metricParser, err := newMetricParser(set.TelemetrySettings.Logger) if err != nil { return nil, err } for name, info := range c.Metrics { - if len(info.Conditions) == 0 { - continue + md := metricDef[ottlmetric.TransformContext]{ + desc: info.Description, } - // Error checked in Config.Validate() - metricMatchExprs[name], _ = parseConditions(metricParser, info.Conditions) + if len(info.Conditions) > 0 { + // Error checked in Config.Validate() + condition, _ := parseConditions(metricParser, info.Conditions) + md.condition = condition + } + metricMetricDefs[name] = md } - dataPointMatchExprs := make(map[string]expr.BoolExpr[ottldatapoint.TransformContext], len(c.DataPoints)) + dataPointMetricDefs := make(map[string]metricDef[ottldatapoint.TransformContext], len(c.DataPoints)) dataPointParser, err := newDataPointParser(set.TelemetrySettings.Logger) if err != nil { return nil, err } for name, info := range c.DataPoints { - if len(info.Conditions) == 0 { - continue + md := metricDef[ottldatapoint.TransformContext]{ + desc: info.MetricInfo.Description, + attrs: info.Attributes, + } + if len(info.Conditions) > 0 { + // Error checked in Config.Validate() + condition, _ := parseConditions(dataPointParser, info.Conditions) + md.condition = condition } - // Error checked in Config.Validate() - dataPointMatchExprs[name], _ = parseConditions(dataPointParser, info.Conditions) + dataPointMetricDefs[name] = md } return &count{ - metricsConsumer: nextConsumer, - metricsCounterFactory: &counterFactory[ottlmetric.TransformContext]{ - matchExprs: metricMatchExprs, - metricInfos: c.Metrics, - }, - dataPointsCounterFactory: &counterFactory[ottldatapoint.TransformContext]{ - matchExprs: dataPointMatchExprs, - metricInfos: c.DataPoints, - }, + metricsConsumer: nextConsumer, + metricsMetricDefs: metricMetricDefs, + dataPointsMetricDefs: dataPointMetricDefs, }, nil } @@ -155,24 +162,32 @@ func createLogsToMetrics( ) (connector.Logs, error) { c := cfg.(*Config) - matchExprs := make(map[string]expr.BoolExpr[ottllog.TransformContext], len(c.Logs)) + metricDefs := make(map[string]metricDef[ottllog.TransformContext], len(c.Logs)) logParser, err := newLogParser(set.TelemetrySettings.Logger) if err != nil { return nil, err } for name, info := range c.Logs { - if len(info.Conditions) == 0 { - continue + md := metricDef[ottllog.TransformContext]{ + desc: info.MetricInfo.Description, + attrs: info.Attributes, + } + if len(info.Conditions) > 0 { + // Error checked in Config.Validate() + condition, _ := parseConditions(logParser, info.Conditions) + md.condition = condition } - // Error checked in Config.Validate() - matchExprs[name], _ = parseConditions(logParser, info.Conditions) + metricDefs[name] = md } return &count{ metricsConsumer: nextConsumer, - logsCounterFactory: &counterFactory[ottllog.TransformContext]{ - matchExprs: matchExprs, - metricInfos: c.Logs, - }, + logsMetricDefs: metricDefs, }, nil } + +type metricDef[K any] struct { + condition expr.BoolExpr[K] + desc string + attrs []AttributeConfig +} diff --git a/connector/countconnector/testdata/config.yaml b/connector/countconnector/testdata/config.yaml index 6eebe44bea56..51accc8b4e48 100644 --- a/connector/countconnector/testdata/config.yaml +++ b/connector/countconnector/testdata/config.yaml @@ -88,6 +88,31 @@ conditions: - IsMatch(resource.attributes["host.name"], "pod-l") == true - IsMatch(resource.attributes["foo"], "bar-l") == true + count/attribute: + spans: + my.span.count: + description: My span count by environment. + attributes: + - key: env + spanevents: + my.spanevent.count: + description: My span event count by environment. + attributes: + - key: env + metrics: + my.metric.count: + description: My metric count. + # Metrics do not have attributes. + datapoints: + my.datapoint.count: + description: My data point count by environment. + attributes: + - key: env + logs: + my.logrecord.count: + description: My log record count by environment. + attributes: + - key: env count/multiple_metrics: spans: my.span.count: @@ -96,6 +121,10 @@ description: Limited span count. conditions: - IsMatch(resource.attributes["host.name"], "pod-s") == true + attributes: + - key: env + - key: component + default_value: other spanevents: my.spanevent.count: description: My span event count. @@ -103,6 +132,10 @@ description: Limited span event count. conditions: - IsMatch(resource.attributes["host.name"], "pod-e") == true + attributes: + - key: env + - key: component + default_value: other metrics: my.metric.count: description: My metric count. @@ -117,6 +150,10 @@ description: Limited data point count. conditions: - IsMatch(resource.attributes["host.name"], "pod-d") == true + attributes: + - key: env + - key: component + default_value: other logs: my.logrecord.count: description: My log record count. @@ -124,3 +161,7 @@ description: Limited log record count. conditions: - IsMatch(resource.attributes["host.name"], "pod-l") == true + attributes: + - key: env + - key: component + default_value: other diff --git a/connector/countconnector/testdata/logs/condition_and_attribute.json b/connector/countconnector/testdata/logs/condition_and_attribute.json new file mode 100644 index 000000000000..115e78a4ac21 --- /dev/null +++ b/connector/countconnector/testdata/logs/condition_and_attribute.json @@ -0,0 +1,126 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attribute if ...", + "name": "log.count.if.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678390948399018000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678390948399018000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attribute if ...", + "name": "log.count.if.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678390948399021000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678390948399021000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + } + ] +} diff --git a/connector/countconnector/testdata/logs/default_attribute_value.json b/connector/countconnector/testdata/logs/default_attribute_value.json new file mode 100644 index 000000000000..37dfadd67980 --- /dev/null +++ b/connector/countconnector/testdata/logs/default_attribute_value.json @@ -0,0 +1,347 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attribute with default", + "name": "log.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678390948398365000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678390948398365000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678390948398365000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attribute with default", + "name": "log.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678390948398368000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678390948398368000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678390948398368000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "notfoo" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attribute with default", + "name": "log.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678390948398371000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678390948398371000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678390948398371000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attribute with default", + "name": "log.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678390948398373000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678390948398373000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678390948398373000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + } + ] +} diff --git a/connector/countconnector/testdata/logs/input.json b/connector/countconnector/testdata/logs/input.json index e032a51968eb..58585af94caa 100644 --- a/connector/countconnector/testdata/logs/input.json +++ b/connector/countconnector/testdata/logs/input.json @@ -1,37 +1,86 @@ { "resourceLogs": [ { - "resource": {}, + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, "scopeLogs": [ { "logRecords": [ { "attributes": [ { - "key": "app", + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "bar" + } + } + ], + "body": { + "stringValue": "This is a log message" + }, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "log.required", "value": { - "stringValue": "server" + "stringValue": "foo" } }, { - "key": "instance_num", + "key": "log.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "body": { + "stringValue": "This is a log message" + }, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "log.required", "value": { - "intValue": "1" + "stringValue": "notfoo" } } ], "body": { "stringValue": "This is a log message" }, - "droppedAttributesCount": 1, - "severityNumber": 9, - "severityText": "Info", - "spanId": "0102040800000000", - "timeUnixNano": "1581452773000000789", - "traceId": "08040201000000000000000000000000" + "timeUnixNano": "1581452773000000789" + }, + { + "body": { + "stringValue": "This is a log message" + }, + "timeUnixNano": "1581452773000000789" } - ], - "scope": {} + ] } ] }, @@ -39,9 +88,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "notbar" } } ] @@ -52,55 +107,64 @@ { "attributes": [ { - "key": "app", + "key": "log.required", "value": { - "stringValue": "server" + "stringValue": "foo" } }, { - "key": "instance_num", + "key": "log.optional", "value": { - "intValue": "1" + "stringValue": "bar" } } ], "body": { "stringValue": "This is a log message" }, - "droppedAttributesCount": 1, - "severityNumber": 9, - "severityText": "Info", - "spanId": "0102040800000000", - "timeUnixNano": "1581452773000000789", - "traceId": "08040201000000000000000000000000" + "timeUnixNano": "1581452773000000789" }, { "attributes": [ { - "key": "customer", + "key": "log.required", "value": { - "stringValue": "acme" + "stringValue": "foo" } }, { - "key": "env", + "key": "log.optional", "value": { - "stringValue": "dev" + "stringValue": "notbar" } } ], "body": { - "stringValue": "something happened" + "stringValue": "This is a log message" + }, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "body": { + "stringValue": "This is a log message" + }, + "timeUnixNano": "1581452773000000789" + }, + { + "body": { + "stringValue": "This is a log message" }, - "droppedAttributesCount": 1, - "severityNumber": 9, - "severityText": "Info", - "spanId": "", - "timeUnixNano": "1581452773000000789", - "traceId": "" + "timeUnixNano": "1581452773000000789" } - ], - "scope": {} + ] } ] }, @@ -108,15 +172,9 @@ "resource": { "attributes": [ { - "key": "resource-attr", - "value": { - "stringValue": "resource-attr-val-1" - } - } - ,{ - "key": "resource-attr-2", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notfoo" } } ] @@ -127,80 +185,132 @@ { "attributes": [ { - "key": "app", + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "bar" + } + } + ], + "body": { + "stringValue": "This is a log message" + }, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "log.required", "value": { - "stringValue": "server" + "stringValue": "foo" } }, { - "key": "instance_num", + "key": "log.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "body": { + "stringValue": "This is a log message" + }, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "log.required", "value": { - "intValue": "1" + "stringValue": "notfoo" } } ], "body": { "stringValue": "This is a log message" }, - "droppedAttributesCount": 1, - "severityNumber": 9, - "severityText": "Info", - "spanId": "0102040800000000", - "timeUnixNano": "1581452773000000789", - "traceId": "08040201000000000000000000000000" + "timeUnixNano": "1581452773000000789" }, + { + "body": { + "stringValue": "This is a log message" + }, + "timeUnixNano": "1581452773000000789" + } + ] + } + ] + }, + { + "scopeLogs": [ + { + "logRecords": [ { "attributes": [ { - "key": "customer", + "key": "log.required", "value": { - "stringValue": "acme" + "stringValue": "foo" } }, { - "key": "env", + "key": "log.optional", "value": { - "stringValue": "dev" + "stringValue": "bar" } } ], "body": { - "stringValue": "something happened" + "stringValue": "This is a log message" }, - "droppedAttributesCount": 1, - "severityNumber": 9, - "severityText": "Info", - "spanId": "", - "timeUnixNano": "1581452773000000789", - "traceId": "" + "timeUnixNano": "1581452773000000789" }, { "attributes": [ { - "key": "app", + "key": "log.required", "value": { - "stringValue": "server" + "stringValue": "foo" } }, { - "key": "instance_num", + "key": "log.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "body": { + "stringValue": "This is a log message" + }, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "log.required", "value": { - "intValue": "1" + "stringValue": "notfoo" } } ], "body": { "stringValue": "This is a log message" }, - "droppedAttributesCount": 1, - "severityNumber": 9, - "severityText": "Info", - "spanId": "0102040800000000", - "timeUnixNano": "1581452773000000789", - "traceId": "08040201000000000000000000000000" + "timeUnixNano": "1581452773000000789" + }, + { + "body": { + "stringValue": "This is a log message" + }, + "timeUnixNano": "1581452773000000789" } - ], - "scope": {} + ] } ] } diff --git a/connector/countconnector/testdata/logs/multiple_attributes.json b/connector/countconnector/testdata/logs/multiple_attributes.json new file mode 100644 index 000000000000..4a5083b5510f --- /dev/null +++ b/connector/countconnector/testdata/logs/multiple_attributes.json @@ -0,0 +1,275 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attributes", + "name": "log.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678390948397879000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678390948397879000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attributes", + "name": "log.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678390948397882000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678390948397882000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "notfoo" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attributes", + "name": "log.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678390948397884000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678390948397884000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attributes", + "name": "log.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678390948397886000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "log.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678390948397886000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + } + ] +} diff --git a/connector/countconnector/testdata/logs/multiple_conditions.json b/connector/countconnector/testdata/logs/multiple_conditions.json index b16d7670b9fc..f8245473a1cb 100644 --- a/connector/countconnector/testdata/logs/multiple_conditions.json +++ b/connector/countconnector/testdata/logs/multiple_conditions.json @@ -1,7 +1,22 @@ { "resourceMetrics": [ { - "resource": {}, + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, "scopeMetrics": [ { "metrics": [ @@ -12,8 +27,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "0", - "timeUnixNano": "1676478602841747000" + "asInt": "4", + "timeUnixNano": "1678390948395853000" } ], "isMonotonic": true @@ -30,9 +45,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "notbar" } } ] @@ -47,8 +68,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676478602841748000" + "asInt": "4", + "timeUnixNano": "1678390948395856000" } ], "isMonotonic": true @@ -65,15 +86,9 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" - } - }, - { - "key": "resource-attr-2", - "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notfoo" } } ] @@ -88,8 +103,34 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "3", - "timeUnixNano": "1676478602841749000" + "asInt": "2", + "timeUnixNano": "1678390948395858000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Count if ...", + "name": "count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "timeUnixNano": "1678390948395859000" } ], "isMonotonic": true diff --git a/connector/countconnector/testdata/logs/multiple_metrics.json b/connector/countconnector/testdata/logs/multiple_metrics.json index 536858d7f1c1..852b256871d7 100644 --- a/connector/countconnector/testdata/logs/multiple_metrics.json +++ b/connector/countconnector/testdata/logs/multiple_metrics.json @@ -1,7 +1,22 @@ { "resourceMetrics": [ { - "resource": {}, + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, "scopeMetrics": [ { "metrics": [ @@ -12,8 +27,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676487453564804000" + "asInt": "4", + "timeUnixNano": "1678390948396984000" } ], "isMonotonic": true @@ -26,8 +41,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "0", - "timeUnixNano": "1676487453564804000" + "asInt": "4", + "timeUnixNano": "1678390948396984000" } ], "isMonotonic": true @@ -44,9 +59,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "notbar" } } ] @@ -61,8 +82,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "2", - "timeUnixNano": "1676487453564838000" + "asInt": "4", + "timeUnixNano": "1678390948396988000" } ], "isMonotonic": true @@ -75,8 +96,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "0", - "timeUnixNano": "1676487453564838000" + "asInt": "4", + "timeUnixNano": "1678390948396988000" } ], "isMonotonic": true @@ -93,15 +114,9 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" - } - }, - { - "key": "resource-attr-2", - "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notfoo" } } ] @@ -116,22 +131,34 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "3", - "timeUnixNano": "1676487453564839000" + "asInt": "4", + "timeUnixNano": "1678390948396990000" } ], "isMonotonic": true } - }, + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ { - "description": "Count if ...", - "name": "count.if", + "description": "All logs count", + "name": "count.all", "sum": { "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "3", - "timeUnixNano": "1676487453564839000" + "asInt": "4", + "timeUnixNano": "1678390948396992000" } ], "isMonotonic": true diff --git a/connector/countconnector/testdata/logs/one_attribute.json b/connector/countconnector/testdata/logs/one_attribute.json new file mode 100644 index 000000000000..6ecaae7645ca --- /dev/null +++ b/connector/countconnector/testdata/logs/one_attribute.json @@ -0,0 +1,227 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attribute", + "name": "log.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678390948397419000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678390948397419000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attribute", + "name": "log.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678390948397423000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678390948397423000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "notfoo" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attribute", + "name": "log.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678390948397425000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678390948397425000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Log count by attribute", + "name": "log.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678390948397427000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "log.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678390948397427000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + } + ] +} diff --git a/connector/countconnector/testdata/logs/one_condition.json b/connector/countconnector/testdata/logs/one_condition.json index f725a8c19dc5..640f8d795aba 100644 --- a/connector/countconnector/testdata/logs/one_condition.json +++ b/connector/countconnector/testdata/logs/one_condition.json @@ -1,38 +1,18 @@ { "resourceMetrics": [ - { - "resource": {}, - "scopeMetrics": [ - { - "metrics": [ - { - "description": "Count if ...", - "name": "count.if", - "sum": { - "aggregationTemporality": 1, - "dataPoints": [ - { - "asInt": "0", - "timeUnixNano": "1676478602841143000" - } - ], - "isMonotonic": true - } - } - ], - "scope": { - "name": "otelcol/countconnector" - } - } - ] - }, { "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "bar" } } ] @@ -47,8 +27,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "0", - "timeUnixNano": "1676478602841165000" + "asInt": "4", + "timeUnixNano": "1678390948395244000" } ], "isMonotonic": true @@ -65,15 +45,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" } }, { - "key": "resource-attr-2", + "key": "resource.optional", "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notbar" } } ] @@ -88,8 +68,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "3", - "timeUnixNano": "1676478602841165000" + "asInt": "4", + "timeUnixNano": "1678390948395279000" } ], "isMonotonic": true diff --git a/connector/countconnector/testdata/logs/zero_conditions.json b/connector/countconnector/testdata/logs/zero_conditions.json index b0be7a3d5537..701de1b7cafb 100644 --- a/connector/countconnector/testdata/logs/zero_conditions.json +++ b/connector/countconnector/testdata/logs/zero_conditions.json @@ -1,7 +1,22 @@ { "resourceMetrics": [ { - "resource": {}, + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, "scopeMetrics": [ { "metrics": [ @@ -12,8 +27,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676478602839825000" + "asInt": "4", + "timeUnixNano": "1678390948393725000" } ], "isMonotonic": true @@ -30,9 +45,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "notbar" } } ] @@ -47,8 +68,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "2", - "timeUnixNano": "1676478602839836000" + "asInt": "4", + "timeUnixNano": "1678390948393759000" } ], "isMonotonic": true @@ -65,15 +86,9 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" - } - }, - { - "key": "resource-attr-2", - "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notfoo" } } ] @@ -88,8 +103,34 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "3", - "timeUnixNano": "1676478602839837000" + "asInt": "4", + "timeUnixNano": "1678390948393760000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "The number of log records observed.", + "name": "log.record.count", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "timeUnixNano": "1678390948393761000" } ], "isMonotonic": true diff --git a/connector/countconnector/testdata/metrics/condition_and_attribute.json b/connector/countconnector/testdata/metrics/condition_and_attribute.json new file mode 100644 index 000000000000..186af97509f2 --- /dev/null +++ b/connector/countconnector/testdata/metrics/condition_and_attribute.json @@ -0,0 +1,126 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attribute if ...", + "name": "datapoint.count.if.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "12", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678391923823222000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678391923823222000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attribute if ...", + "name": "datapoint.count.if.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678391923823233000" + }, + { + "asInt": "12", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678391923823233000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + } + ] +} diff --git a/connector/countconnector/testdata/metrics/default_attribute_value.json b/connector/countconnector/testdata/metrics/default_attribute_value.json new file mode 100644 index 000000000000..aa288e011ebf --- /dev/null +++ b/connector/countconnector/testdata/metrics/default_attribute_value.json @@ -0,0 +1,347 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attribute with default", + "name": "datapoint.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678391923822404000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678391923822404000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678391923822404000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attribute with default", + "name": "datapoint.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678391923822416000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678391923822416000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678391923822416000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "notfoo" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attribute with default", + "name": "datapoint.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678391923822426000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678391923822426000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678391923822426000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attribute with default", + "name": "datapoint.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678391923822435000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678391923822435000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678391923822435000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + } + ] +} diff --git a/connector/countconnector/testdata/metrics/input.json b/connector/countconnector/testdata/metrics/input.json index ce436905bcff..dbaad63f6e7a 100644 --- a/connector/countconnector/testdata/metrics/input.json +++ b/connector/countconnector/testdata/metrics/input.json @@ -2,14 +2,20 @@ "resourceMetrics": [ { "resource": { - "attributes": [ - { - "key": "resource-attr", - "value": { - "stringValue": "resource-attr-val-1" - } - } - ] + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] }, "scopeMetrics": [ { @@ -21,12 +27,18 @@ "asInt": "123", "attributes": [ { - "key": "label-1", - "value": { - "stringValue": "label-value-1" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } } - ], + ], "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" }, @@ -34,12 +46,36 @@ "asInt": "456", "attributes": [ { - "key": "label-2", - "value": { - "stringValue": "label-value-2" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "789", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } } - ], + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "0", "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" } @@ -55,18 +91,18 @@ "asDouble": 1.23, "attributes": [ { - "key": "label-1", - "value": { - "stringValue": "label-value-1" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } }, { - "key": "label-2", - "value": { - "stringValue": "label-value-2" - } + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } } - ], + ], "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" }, @@ -74,18 +110,36 @@ "asDouble": 4.56, "attributes": [ { - "key": "label-1", - "value": { - "stringValue": "label-value-1" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } }, { - "key": "label-3", - "value": { - "stringValue": "label-value-3" - } + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } } - ], + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 7.89, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 0.00, "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" } @@ -103,12 +157,18 @@ "asInt": "123", "attributes": [ { - "key": "label-1", - "value": { - "stringValue": "label-value-1" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } } - ], + ], "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" }, @@ -116,12 +176,36 @@ "asInt": "456", "attributes": [ { - "key": "label-2", - "value": { - "stringValue": "label-value-2" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "789", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } } - ], + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "0", "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" } @@ -139,18 +223,18 @@ "asDouble": 1.23, "attributes": [ { - "key": "label-1", - "value": { - "stringValue": "label-value-1" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } }, { - "key": "label-2", - "value": { - "stringValue": "label-value-2" - } + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } } - ], + ], "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" }, @@ -158,18 +242,36 @@ "asDouble": 4.56, "attributes": [ { - "key": "label-1", - "value": { - "stringValue": "label-value-1" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } }, { - "key": "label-3", - "value": { - "stringValue": "label-value-3" - } + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 4.56, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } } - ], + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 0.00, "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" } @@ -185,18 +287,18 @@ { "attributes": [ { - "key": "label-1", - "value": { - "stringValue": "label-value-1" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } }, { - "key": "label-3", - "value": { - "stringValue": "label-value-3" - } + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } } - ], + ], "count": "1", "startTimeUnixNano": "1581452772000000321", "sum": 15, @@ -205,38 +307,41 @@ { "attributes": [ { - "key": "label-2", - "value": { - "stringValue": "label-value-2" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } } - ], - "bucketCounts": [ - "0", - "1" - ], - "count": "1", - "exemplars": [ - { - "asDouble": 15, - "filteredAttributes": [ - { - "key": "exemplar-attachment", - "value": { - "stringValue": "exemplar-attachment-value" - } - } - ], - "spanId": "", - "timeUnixNano": "1581452773000000123", - "traceId": "" - } - ], - "explicitBounds": [ - 1 - ], + ], + "count": "2", "startTimeUnixNano": "1581452772000000321", - "sum": 15, + "sum": 30, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "count": "3", + "startTimeUnixNano": "1581452772000000321", + "sum": 45, + "timeUnixNano": "1581452773000000789" + }, + { + "count": "0", + "startTimeUnixNano": "1581452772000000321", + "sum": 0, "timeUnixNano": "1581452773000000789" } ] @@ -251,18 +356,18 @@ { "attributes": [ { - "key": "label-1", - "value": { - "stringValue": "label-value-1" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } }, { - "key": "label-3", - "value": { - "stringValue": "label-value-3" - } + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } } - ], + ], "count": "1", "startTimeUnixNano": "1581452772000000321", "sum": 15, @@ -271,21 +376,41 @@ { "attributes": [ { - "key": "label-2", - "value": { - "stringValue": "label-value-2" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } } - ], - "count": "1", - "quantileValues": [ + ], + "count": "2", + "startTimeUnixNano": "1581452772000000321", + "sum": 30, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ { - "quantile": 0.01, - "value": 15 + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } } - ], + ], + "count": "3", "startTimeUnixNano": "1581452772000000321", - "sum": 15, + "sum": 45, + "timeUnixNano": "1581452773000000789" + }, + { + "count": "0", + "startTimeUnixNano": "1581452772000000321", + "sum": 0, "timeUnixNano": "1581452773000000789" } ] @@ -299,39 +424,43 @@ }, { "resource": { - "attributes": [ - { - "key": "resource-attr", - "value": { - "stringValue": "resource-attr-val-1" - } - } - ,{ - "key": "resource-attr-2", - "value": { - "stringValue": "resource-attr-val-2" - } - } - ] + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] }, "scopeMetrics": [ { "metrics": [ { - "name": "counter-int", - "sum": { - "aggregationTemporality": 2, + "gauge": { "dataPoints": [ { "asInt": "123", "attributes": [ { - "key": "label-1", - "value": { - "stringValue": "label-value-1" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } } - ], + ], "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" }, @@ -339,18 +468,106 @@ "asInt": "456", "attributes": [ { - "key": "label-2", - "value": { - "stringValue": "label-value-2" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "789", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } } - ], + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "0", "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" } - ], - "isMonotonic": true + ] + }, + "name": "gauge-int", + "unit": "1" + }, + { + "gauge": { + "dataPoints": [ + { + "asDouble": 1.23, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 4.56, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 7.89, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 0.00, + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + } + ] }, + "name": "gauge-double", "unit": "1" }, { @@ -362,12 +579,18 @@ "asInt": "123", "attributes": [ { - "key": "label-1", - "value": { - "stringValue": "label-value-1" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } } - ], + ], "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" }, @@ -375,12 +598,36 @@ "asInt": "456", "attributes": [ { - "key": "label-2", - "value": { - "stringValue": "label-value-2" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "789", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } } - ], + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "0", "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" } @@ -390,33 +637,63 @@ "unit": "1" }, { - "name": "counter-int", + "name": "counter-double", "sum": { "aggregationTemporality": 2, "dataPoints": [ { - "asInt": "123", + "asDouble": 1.23, "attributes": [ { - "key": "label-1", - "value": { - "stringValue": "label-value-1" - } + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } } - ], + ], "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" }, { - "asInt": "456", + "asDouble": 4.56, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 4.56, "attributes": [ { - "key": "label-2", - "value": { - "stringValue": "label-value-2" - } + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } } - ], + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 0.00, "startTimeUnixNano": "1581452772000000321", "timeUnixNano": "1581452773000000789" } @@ -424,11 +701,971 @@ "isMonotonic": true }, "unit": "1" + }, + { + "histogram": { + "aggregationTemporality": 2, + "dataPoints": [ + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "count": "1", + "startTimeUnixNano": "1581452772000000321", + "sum": 15, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "count": "2", + "startTimeUnixNano": "1581452772000000321", + "sum": 30, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "count": "3", + "startTimeUnixNano": "1581452772000000321", + "sum": 45, + "timeUnixNano": "1581452773000000789" + }, + { + "count": "0", + "startTimeUnixNano": "1581452772000000321", + "sum": 0, + "timeUnixNano": "1581452773000000789" + } + ] + }, + "name": "double-histogram", + "unit": "1" + }, + { + "name": "double-summary", + "summary": { + "dataPoints": [ + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "count": "1", + "startTimeUnixNano": "1581452772000000321", + "sum": 15, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "count": "2", + "startTimeUnixNano": "1581452772000000321", + "sum": 30, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "count": "3", + "startTimeUnixNano": "1581452772000000321", + "sum": 45, + "timeUnixNano": "1581452773000000789" + }, + { + "count": "0", + "startTimeUnixNano": "1581452772000000321", + "sum": 0, + "timeUnixNano": "1581452773000000789" + } + ] + }, + "unit": "1" + } + ], + "scope": {} + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "notfoo" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "gauge": { + "dataPoints": [ + { + "asInt": "123", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "456", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "789", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "0", + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + } + ] + }, + "name": "gauge-int", + "unit": "1" + }, + { + "gauge": { + "dataPoints": [ + { + "asDouble": 1.23, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 4.56, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 7.89, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 0.00, + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + } + ] + }, + "name": "gauge-double", + "unit": "1" + }, + { + "name": "counter-int", + "sum": { + "aggregationTemporality": 2, + "dataPoints": [ + { + "asInt": "123", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "456", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "789", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "0", + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + } + ], + "isMonotonic": true + }, + "unit": "1" + }, + { + "name": "counter-double", + "sum": { + "aggregationTemporality": 2, + "dataPoints": [ + { + "asDouble": 1.23, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 4.56, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 4.56, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 0.00, + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + } + ], + "isMonotonic": true + }, + "unit": "1" + }, + { + "histogram": { + "aggregationTemporality": 2, + "dataPoints": [ + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "count": "1", + "startTimeUnixNano": "1581452772000000321", + "sum": 15, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "count": "2", + "startTimeUnixNano": "1581452772000000321", + "sum": 30, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "count": "3", + "startTimeUnixNano": "1581452772000000321", + "sum": 45, + "timeUnixNano": "1581452773000000789" + }, + { + "count": "0", + "startTimeUnixNano": "1581452772000000321", + "sum": 0, + "timeUnixNano": "1581452773000000789" + } + ] + }, + "name": "double-histogram", + "unit": "1" + }, + { + "name": "double-summary", + "summary": { + "dataPoints": [ + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "count": "1", + "startTimeUnixNano": "1581452772000000321", + "sum": 15, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "count": "2", + "startTimeUnixNano": "1581452772000000321", + "sum": 30, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "count": "3", + "startTimeUnixNano": "1581452772000000321", + "sum": 45, + "timeUnixNano": "1581452773000000789" + }, + { + "count": "0", + "startTimeUnixNano": "1581452772000000321", + "sum": 0, + "timeUnixNano": "1581452773000000789" + } + ] + }, + "unit": "1" + } + ], + "scope": {} + } + ] + }, + { + "scopeMetrics": [ + { + "metrics": [ + { + "gauge": { + "dataPoints": [ + { + "asInt": "123", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "456", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "789", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "0", + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + } + ] + }, + "name": "gauge-int", + "unit": "1" + }, + { + "gauge": { + "dataPoints": [ + { + "asDouble": 1.23, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 4.56, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 7.89, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 0.00, + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + } + ] + }, + "name": "gauge-double", + "unit": "1" + }, + { + "name": "counter-int", + "sum": { + "aggregationTemporality": 2, + "dataPoints": [ + { + "asInt": "123", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "456", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "789", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asInt": "0", + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + } + ], + "isMonotonic": true + }, + "unit": "1" + }, + { + "name": "counter-double", + "sum": { + "aggregationTemporality": 2, + "dataPoints": [ + { + "asDouble": 1.23, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 4.56, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 4.56, + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + }, + { + "asDouble": 0.00, + "startTimeUnixNano": "1581452772000000321", + "timeUnixNano": "1581452773000000789" + } + ], + "isMonotonic": true + }, + "unit": "1" + }, + { + "histogram": { + "aggregationTemporality": 2, + "dataPoints": [ + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "count": "1", + "startTimeUnixNano": "1581452772000000321", + "sum": 15, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "count": "2", + "startTimeUnixNano": "1581452772000000321", + "sum": 30, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "count": "3", + "startTimeUnixNano": "1581452772000000321", + "sum": 45, + "timeUnixNano": "1581452773000000789" + }, + { + "count": "0", + "startTimeUnixNano": "1581452772000000321", + "sum": 0, + "timeUnixNano": "1581452773000000789" + } + ] + }, + "name": "double-histogram", + "unit": "1" + }, + { + "name": "double-summary", + "summary": { + "dataPoints": [ + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "count": "1", + "startTimeUnixNano": "1581452772000000321", + "sum": 15, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "count": "2", + "startTimeUnixNano": "1581452772000000321", + "sum": 30, + "timeUnixNano": "1581452773000000789" + }, + { + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "count": "3", + "startTimeUnixNano": "1581452772000000321", + "sum": 45, + "timeUnixNano": "1581452773000000789" + }, + { + "count": "0", + "startTimeUnixNano": "1581452772000000321", + "sum": 0, + "timeUnixNano": "1581452773000000789" + } + ] + }, + "unit": "1" } ], "scope": {} } ] } + ] } diff --git a/connector/countconnector/testdata/metrics/multiple_attributes.json b/connector/countconnector/testdata/metrics/multiple_attributes.json new file mode 100644 index 000000000000..8d7e242b570a --- /dev/null +++ b/connector/countconnector/testdata/metrics/multiple_attributes.json @@ -0,0 +1,275 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attributes", + "name": "datapoint.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678391923821783000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678391923821783000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attributes", + "name": "datapoint.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678391923821792000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678391923821792000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "notfoo" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attributes", + "name": "datapoint.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678391923821800000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678391923821800000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attributes", + "name": "datapoint.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678391923821807000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "datapoint.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678391923821807000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + } + ] +} diff --git a/connector/countconnector/testdata/metrics/multiple_conditions.json b/connector/countconnector/testdata/metrics/multiple_conditions.json index 5a89982bde0a..613dfeb0a45e 100644 --- a/connector/countconnector/testdata/metrics/multiple_conditions.json +++ b/connector/countconnector/testdata/metrics/multiple_conditions.json @@ -4,9 +4,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" } } ] @@ -21,8 +27,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676486442344224000" + "asInt": "6", + "timeUnixNano": "1678391923819487000" } ], "isMonotonic": true @@ -35,8 +41,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "12", - "timeUnixNano": "1676486442344225000" + "asInt": "24", + "timeUnixNano": "1678391923819487000" } ], "isMonotonic": true @@ -53,15 +59,64 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" } }, { - "key": "resource-attr-2", + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Metric count if ...", + "name": "metric.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "6", + "timeUnixNano": "1678391923819499000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Data point count if ...", + "name": "datapoint.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "24", + "timeUnixNano": "1678391923819499000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notfoo" } } ] @@ -76,8 +131,48 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "3", - "timeUnixNano": "1676486442344232000" + "asInt": "1", + "timeUnixNano": "1678391923819509000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Data point count if ...", + "name": "datapoint.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "12", + "timeUnixNano": "1678391923819510000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Metric count if ...", + "name": "metric.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "timeUnixNano": "1678391923819529000" } ], "isMonotonic": true @@ -90,8 +185,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "3", - "timeUnixNano": "1676486442344233000" + "asInt": "12", + "timeUnixNano": "1678391923819529000" } ], "isMonotonic": true diff --git a/connector/countconnector/testdata/metrics/multiple_metrics.json b/connector/countconnector/testdata/metrics/multiple_metrics.json index 6868e1d7d8e0..06ece3cb190f 100644 --- a/connector/countconnector/testdata/metrics/multiple_metrics.json +++ b/connector/countconnector/testdata/metrics/multiple_metrics.json @@ -4,9 +4,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" } } ] @@ -22,7 +28,7 @@ "dataPoints": [ { "asInt": "6", - "timeUnixNano": "1676487324648839000" + "timeUnixNano": "1678391923820453000" } ], "isMonotonic": true @@ -35,8 +41,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676487324648839000" + "asInt": "6", + "timeUnixNano": "1678391923820453000" } ], "isMonotonic": true @@ -49,8 +55,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "12", - "timeUnixNano": "1676487324648839000" + "asInt": "24", + "timeUnixNano": "1678391923820453000" } ], "isMonotonic": true @@ -63,8 +69,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "12", - "timeUnixNano": "1676487324648839000" + "asInt": "24", + "timeUnixNano": "1678391923820453000" } ], "isMonotonic": true @@ -81,15 +87,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" } }, { - "key": "resource-attr-2", + "key": "resource.optional", "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notbar" } } ] @@ -104,8 +110,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "3", - "timeUnixNano": "1676487324648901000" + "asInt": "6", + "timeUnixNano": "1678391923820468000" } ], "isMonotonic": true @@ -118,8 +124,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "3", - "timeUnixNano": "1676487324648901000" + "asInt": "6", + "timeUnixNano": "1678391923820468000" } ], "isMonotonic": true @@ -128,12 +134,157 @@ { "description": "All data points count", "name": "datapoint.count.all", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "24", + "timeUnixNano": "1678391923820468000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Data point count if ...", + "name": "datapoint.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "24", + "timeUnixNano": "1678391923820468000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "notfoo" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "All metrics count", + "name": "metric.count.all", "sum": { "aggregationTemporality": 1, "dataPoints": [ { "asInt": "6", - "timeUnixNano": "1676487324648901000" + "timeUnixNano": "1678391923820480000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Metric count if ...", + "name": "metric.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "timeUnixNano": "1678391923820480000" + } + ], + "isMonotonic": true + } + }, + { + "description": "All data points count", + "name": "datapoint.count.all", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "24", + "timeUnixNano": "1678391923820480000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Data point count if ...", + "name": "datapoint.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "12", + "timeUnixNano": "1678391923820480000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "All metrics count", + "name": "metric.count.all", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "6", + "timeUnixNano": "1678391923820491000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Metric count if ...", + "name": "metric.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "timeUnixNano": "1678391923820491000" + } + ], + "isMonotonic": true + } + }, + { + "description": "All data points count", + "name": "datapoint.count.all", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "24", + "timeUnixNano": "1678391923820491000" } ], "isMonotonic": true @@ -146,8 +297,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "3", - "timeUnixNano": "1676487324648901000" + "asInt": "12", + "timeUnixNano": "1678391923820491000" } ], "isMonotonic": true diff --git a/connector/countconnector/testdata/metrics/one_attribute.json b/connector/countconnector/testdata/metrics/one_attribute.json new file mode 100644 index 000000000000..73188402ee8a --- /dev/null +++ b/connector/countconnector/testdata/metrics/one_attribute.json @@ -0,0 +1,227 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attribute", + "name": "datapoint.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "12", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678391923821179000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678391923821179000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attribute", + "name": "datapoint.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "12", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678391923821189000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678391923821189000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "notfoo" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attribute", + "name": "datapoint.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "12", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678391923821196000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678391923821196000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Data point count by attribute", + "name": "datapoint.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "12", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678391923821203000" + }, + { + "asInt": "6", + "attributes": [ + { + "key": "datapoint.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678391923821203000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + } + ] +} diff --git a/connector/countconnector/testdata/metrics/one_condition.json b/connector/countconnector/testdata/metrics/one_condition.json index 51007a07becd..f50b780054b8 100644 --- a/connector/countconnector/testdata/metrics/one_condition.json +++ b/connector/countconnector/testdata/metrics/one_condition.json @@ -4,9 +4,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" } } ] @@ -21,8 +27,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "0", - "timeUnixNano": "1676486442342597000" + "asInt": "6", + "timeUnixNano": "1678391923818482000" } ], "isMonotonic": true @@ -35,8 +41,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "12", - "timeUnixNano": "1676486442342600000" + "asInt": "24", + "timeUnixNano": "1678391923818482000" } ], "isMonotonic": true @@ -53,15 +59,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" } }, { - "key": "resource-attr-2", + "key": "resource.optional", "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notbar" } } ] @@ -76,8 +82,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "3", - "timeUnixNano": "1676486442342652000" + "asInt": "6", + "timeUnixNano": "1678391923818549000" } ], "isMonotonic": true @@ -90,8 +96,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "0", - "timeUnixNano": "1676486442342652000" + "asInt": "24", + "timeUnixNano": "1678391923818549000" } ], "isMonotonic": true diff --git a/connector/countconnector/testdata/metrics/zero_conditions.json b/connector/countconnector/testdata/metrics/zero_conditions.json index 2f796b472d56..93aa96473da8 100644 --- a/connector/countconnector/testdata/metrics/zero_conditions.json +++ b/connector/countconnector/testdata/metrics/zero_conditions.json @@ -4,9 +4,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" } } ] @@ -22,7 +28,7 @@ "dataPoints": [ { "asInt": "6", - "timeUnixNano": "1676486442340664000" + "timeUnixNano": "1678391923815881000" } ], "isMonotonic": true @@ -35,8 +41,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "12", - "timeUnixNano": "1676486442340664000" + "asInt": "24", + "timeUnixNano": "1678391923815881000" } ], "isMonotonic": true @@ -53,15 +59,64 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" } }, { - "key": "resource-attr-2", + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "The number of metrics observed.", + "name": "metric.count", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "6", + "timeUnixNano": "1678391923815923000" + } + ], + "isMonotonic": true + } + }, + { + "description": "The number of data points observed.", + "name": "metric.datapoint.count", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "24", + "timeUnixNano": "1678391923815923000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notfoo" } } ] @@ -76,8 +131,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "3", - "timeUnixNano": "1676486442340670000" + "asInt": "6", + "timeUnixNano": "1678391923815929000" } ], "isMonotonic": true @@ -86,12 +141,52 @@ { "description": "The number of data points observed.", "name": "metric.datapoint.count", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "24", + "timeUnixNano": "1678391923815929000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "The number of metrics observed.", + "name": "metric.count", "sum": { "aggregationTemporality": 1, "dataPoints": [ { "asInt": "6", - "timeUnixNano": "1676486442340670000" + "timeUnixNano": "1678391923815933000" + } + ], + "isMonotonic": true + } + }, + { + "description": "The number of data points observed.", + "name": "metric.datapoint.count", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "24", + "timeUnixNano": "1678391923815933000" } ], "isMonotonic": true diff --git a/connector/countconnector/testdata/traces/condition_and_attribute.json b/connector/countconnector/testdata/traces/condition_and_attribute.json new file mode 100644 index 000000000000..fb0e8cfe202c --- /dev/null +++ b/connector/countconnector/testdata/traces/condition_and_attribute.json @@ -0,0 +1,194 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count if ...", + "name": "span.count.if.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678392127929005000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678392127929005000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attribute if ...", + "name": "spanevent.count.if.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "8", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678392127929006000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678392127929006000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count if ...", + "name": "span.count.if.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678392127929018000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678392127929018000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attribute if ...", + "name": "spanevent.count.if.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "8", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678392127929018000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678392127929018000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + } + ] +} diff --git a/connector/countconnector/testdata/traces/default_attribute_value.json b/connector/countconnector/testdata/traces/default_attribute_value.json new file mode 100644 index 000000000000..02d8ae3ae6e7 --- /dev/null +++ b/connector/countconnector/testdata/traces/default_attribute_value.json @@ -0,0 +1,603 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count by attribute with default", + "name": "span.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678392127927843000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127927843000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127927843000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attribute with default", + "name": "spanevent.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127927843000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127927843000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678392127927843000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count by attribute with default", + "name": "span.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127927856000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127927856000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678392127927856000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attribute with default", + "name": "spanevent.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127927856000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127927856000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678392127927856000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "notfoo" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count by attribute with default", + "name": "span.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127927865000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127927865000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678392127927865000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attribute with default", + "name": "spanevent.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127927865000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127927865000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678392127927865000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count by attribute with default", + "name": "span.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127927874000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127927874000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678392127927874000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attribute with default", + "name": "spanevent.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127927874000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127927874000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "other" + } + } + ], + "timeUnixNano": "1678392127927874000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + } + ] +} diff --git a/connector/countconnector/testdata/traces/input.json b/connector/countconnector/testdata/traces/input.json index 0d79c70256bf..aeb2529be179 100644 --- a/connector/countconnector/testdata/traces/input.json +++ b/connector/countconnector/testdata/traces/input.json @@ -4,80 +4,293 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" } } ] }, "scopeSpans": [ { - "scope": {}, "spans": [ { - "droppedAttributesCount": 1, - "droppedEventsCount": 1, + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "span-with-attrs-foo-bar", + "startTimeUnixNano": "1581452772000000321", "endTimeUnixNano": "1581452773000000789", "events": [ { "attributes": [ { - "key": "span-event-attr", + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", "value": { - "stringValue": "span-event-attr-val" + "stringValue": "notfoo" } } ], - "droppedAttributesCount": 2, - "name": "event-with-attr", + "name": "event-with-attr-notfoo", "timeUnixNano": "1581452773000000123" }, { - "droppedAttributesCount": 2, - "name": "event", + "name": "event-with-no-attrs", "timeUnixNano": "1581452773000000123" } - ], - "name": "operationA", - "parentSpanId": "", - "spanId": "", - "startTimeUnixNano": "1581452772000000321", - "status": { - "code": 2, - "message": "status-cancelled" - }, - "traceId": "" + ] }, { - "droppedLinksCount": 3, + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "span-with-attrs-foo-notbar", + "startTimeUnixNano": "1581452772000000321", "endTimeUnixNano": "1581452773000000789", - "links": [ + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, { "attributes": [ { - "key": "span-link-attr", + "key": "event.required", "value": { - "stringValue": "span-link-attr-val" + "stringValue": "notfoo" } } ], - "droppedAttributesCount": 4, - "spanId": "", - "traceId": "" + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" }, { - "droppedAttributesCount": 4, - "spanId": "", - "traceId": "" + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + }, + { + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } } ], - "name": "operationB", - "parentSpanId": "", - "spanId": "", + "name": "span-with-attr-notfoo", + "startTimeUnixNano": "1581452772000000321", + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + }, + { + "name": "span-with-no-attrs", "startTimeUnixNano": "1581452772000000321", - "status": {}, - "traceId": "" + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] } ] } @@ -87,34 +300,863 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notbar" } } ] }, "scopeSpans": [ { - "scope": {}, "spans": [ { "attributes": [ { - "key": "span-attr", + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", "value": { - "stringValue": "span-attr-val" + "stringValue": "bar" } } ], - "droppedAttributesCount": 5, + "name": "span-with-attrs-foo-bar", + "startTimeUnixNano": "1581452772000000321", "endTimeUnixNano": "1581452773000000789", - "name": "operationC", - "parentSpanId": "", - "spanId": "", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + }, + { + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "span-with-attrs-foo-notbar", "startTimeUnixNano": "1581452772000000321", - "status": {}, - "traceId": "" + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + }, + { + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "span-with-attr-notfoo", + "startTimeUnixNano": "1581452772000000321", + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + }, + { + "name": "span-with-no-attrs", + "startTimeUnixNano": "1581452772000000321", + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + } + ] + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "notfoo" + } + } + ] + }, + "scopeSpans": [ + { + "spans": [ + { + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "span-with-attrs-foo-bar", + "startTimeUnixNano": "1581452772000000321", + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + }, + { + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "span-with-attrs-foo-notbar", + "startTimeUnixNano": "1581452772000000321", + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + }, + { + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "span-with-attr-notfoo", + "startTimeUnixNano": "1581452772000000321", + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + }, + { + "name": "span-with-no-attrs", + "startTimeUnixNano": "1581452772000000321", + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + } + ] + } + ] + }, + { + "scopeSpans": [ + { + "spans": [ + { + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "span-with-attrs-foo-bar", + "startTimeUnixNano": "1581452772000000321", + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + }, + { + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "span-with-attrs-foo-notbar", + "startTimeUnixNano": "1581452772000000321", + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + }, + { + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "span-with-attr-notfoo", + "startTimeUnixNano": "1581452772000000321", + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] + }, + { + "name": "span-with-no-attrs", + "startTimeUnixNano": "1581452772000000321", + "endTimeUnixNano": "1581452773000000789", + "events": [ + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "name": "event-with-attrs-foo-bar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "name": "event-with-attrs-foo-notbar", + "timeUnixNano": "1581452773000000123" + }, + { + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "name": "event-with-attr-notfoo", + "timeUnixNano": "1581452773000000123" + }, + { + "name": "event-with-no-attrs", + "timeUnixNano": "1581452773000000123" + } + ] } ] } diff --git a/connector/countconnector/testdata/traces/multiple_attributes.json b/connector/countconnector/testdata/traces/multiple_attributes.json new file mode 100644 index 000000000000..8c939a60f721 --- /dev/null +++ b/connector/countconnector/testdata/traces/multiple_attributes.json @@ -0,0 +1,459 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count by attributes", + "name": "span.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127926637000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127926637000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attributes", + "name": "spanevent.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127926637000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127926637000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count by attributes", + "name": "span.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127926647000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127926647000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attributes", + "name": "spanevent.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127926647000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127926647000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "notfoo" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count by attributes", + "name": "span.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127926654000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127926654000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attributes", + "name": "spanevent.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127926654000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127926654000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count by attributes", + "name": "span.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127926661000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "span.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127926661000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attributes", + "name": "spanevent.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "bar" + } + } + ], + "timeUnixNano": "1678392127926661000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "event.optional", + "value": { + "stringValue": "notbar" + } + } + ], + "timeUnixNano": "1678392127926661000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + } + ] +} diff --git a/connector/countconnector/testdata/traces/multiple_conditions.json b/connector/countconnector/testdata/traces/multiple_conditions.json index 39bd05966756..24f7319f7127 100644 --- a/connector/countconnector/testdata/traces/multiple_conditions.json +++ b/connector/countconnector/testdata/traces/multiple_conditions.json @@ -4,9 +4,70 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count if ...", + "name": "span.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "timeUnixNano": "1678392127923826000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count if ...", + "name": "spanevent.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "16", + "timeUnixNano": "1678392127923826000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" } } ] @@ -21,8 +82,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676490033223790000" + "asInt": "4", + "timeUnixNano": "1678392127923836000" } ], "isMonotonic": true @@ -35,8 +96,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676490033223791000" + "asInt": "16", + "timeUnixNano": "1678392127923836000" } ], "isMonotonic": true @@ -53,9 +114,9 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notfoo" } } ] @@ -70,8 +131,48 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676490033223796000" + "asInt": "2", + "timeUnixNano": "1678392127923843000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count if ...", + "name": "spanevent.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "8", + "timeUnixNano": "1678392127923843000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count if ...", + "name": "span.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "timeUnixNano": "1678392127923849000" } ], "isMonotonic": true @@ -84,8 +185,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "0", - "timeUnixNano": "1676490033223796000" + "asInt": "8", + "timeUnixNano": "1678392127923849000" } ], "isMonotonic": true diff --git a/connector/countconnector/testdata/traces/multiple_metrics.json b/connector/countconnector/testdata/traces/multiple_metrics.json index 0506849a1624..11bbaf80441f 100644 --- a/connector/countconnector/testdata/traces/multiple_metrics.json +++ b/connector/countconnector/testdata/traces/multiple_metrics.json @@ -4,9 +4,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" } } ] @@ -14,6 +20,20 @@ "scopeMetrics": [ { "metrics": [ + { + "description": "All spans count", + "name": "span.count.all", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "timeUnixNano": "1678392127924753000" + } + ], + "isMonotonic": true + } + }, { "description": "Span count if ...", "name": "span.count.if", @@ -21,13 +41,68 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676490033225036000" + "asInt": "4", + "timeUnixNano": "1678392127924753000" + } + ], + "isMonotonic": true + } + }, + { + "description": "All span events count", + "name": "spanevent.count.all", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "16", + "timeUnixNano": "1678392127924753000" } ], "isMonotonic": true } }, + { + "description": "Span event count if ...", + "name": "spanevent.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "16", + "timeUnixNano": "1678392127924753000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ { "description": "All spans count", "name": "span.count.all", @@ -35,8 +110,22 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "2", - "timeUnixNano": "1676490033225036000" + "asInt": "4", + "timeUnixNano": "1678392127924764000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span count if ...", + "name": "span.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "timeUnixNano": "1678392127924764000" } ], "isMonotonic": true @@ -49,8 +138,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "2", - "timeUnixNano": "1676490033225037000" + "asInt": "16", + "timeUnixNano": "1678392127924764000" } ], "isMonotonic": true @@ -63,8 +152,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676490033225037000" + "asInt": "16", + "timeUnixNano": "1678392127924764000" } ], "isMonotonic": true @@ -81,9 +170,9 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notfoo" } } ] @@ -98,8 +187,76 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676490033225041000" + "asInt": "4", + "timeUnixNano": "1678392127924772000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span count if ...", + "name": "span.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "timeUnixNano": "1678392127924772000" + } + ], + "isMonotonic": true + } + }, + { + "description": "All span events count", + "name": "spanevent.count.all", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "16", + "timeUnixNano": "1678392127924772000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count if ...", + "name": "spanevent.count.if", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "8", + "timeUnixNano": "1678392127924772000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "All spans count", + "name": "span.count.all", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "timeUnixNano": "1678392127924780000" } ], "isMonotonic": true @@ -112,8 +269,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676490033225041000" + "asInt": "2", + "timeUnixNano": "1678392127924780000" } ], "isMonotonic": true @@ -126,8 +283,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "0", - "timeUnixNano": "1676490033225041000" + "asInt": "16", + "timeUnixNano": "1678392127924780000" } ], "isMonotonic": true @@ -140,8 +297,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "0", - "timeUnixNano": "1676490033225041000" + "asInt": "8", + "timeUnixNano": "1678392127924780000" } ], "isMonotonic": true diff --git a/connector/countconnector/testdata/traces/one_attribute.json b/connector/countconnector/testdata/traces/one_attribute.json new file mode 100644 index 000000000000..3dac18ace4b0 --- /dev/null +++ b/connector/countconnector/testdata/traces/one_attribute.json @@ -0,0 +1,363 @@ +{ + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count by attribute", + "name": "span.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678392127925459000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678392127925459000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attribute", + "name": "spanevent.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "8", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678392127925459000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678392127925459000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count by attribute", + "name": "span.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678392127925468000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678392127925468000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attribute", + "name": "spanevent.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "8", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678392127925468000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678392127925468000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "notfoo" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count by attribute", + "name": "span.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678392127925474000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678392127925474000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attribute", + "name": "spanevent.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "8", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678392127925474000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678392127925474000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "Span count by attribute", + "name": "span.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "2", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678392127925497000" + }, + { + "asInt": "1", + "attributes": [ + { + "key": "span.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678392127925497000" + } + ], + "isMonotonic": true + } + }, + { + "description": "Span event count by attribute", + "name": "spanevent.count.by_attr", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "8", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "foo" + } + } + ], + "timeUnixNano": "1678392127925497000" + }, + { + "asInt": "4", + "attributes": [ + { + "key": "event.required", + "value": { + "stringValue": "notfoo" + } + } + ], + "timeUnixNano": "1678392127925497000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + } + ] +} diff --git a/connector/countconnector/testdata/traces/one_condition.json b/connector/countconnector/testdata/traces/one_condition.json index 2e011bb4bd3c..5b6999b93d0e 100644 --- a/connector/countconnector/testdata/traces/one_condition.json +++ b/connector/countconnector/testdata/traces/one_condition.json @@ -4,9 +4,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" } } ] @@ -21,8 +27,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "0", - "timeUnixNano": "1676490033222958000" + "asInt": "4", + "timeUnixNano": "1678392127922309000" } ], "isMonotonic": true @@ -35,8 +41,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "2", - "timeUnixNano": "1676490033222959000" + "asInt": "16", + "timeUnixNano": "1678392127922310000" } ], "isMonotonic": true @@ -53,9 +59,15 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notbar" } } ] @@ -70,8 +82,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676490033222979000" + "asInt": "4", + "timeUnixNano": "1678392127922363000" } ], "isMonotonic": true @@ -84,8 +96,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "0", - "timeUnixNano": "1676490033222979000" + "asInt": "16", + "timeUnixNano": "1678392127922364000" } ], "isMonotonic": true diff --git a/connector/countconnector/testdata/traces/zero_conditions.json b/connector/countconnector/testdata/traces/zero_conditions.json index 8287ee504681..4012430381f8 100644 --- a/connector/countconnector/testdata/traces/zero_conditions.json +++ b/connector/countconnector/testdata/traces/zero_conditions.json @@ -4,9 +4,70 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-1" + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "bar" + } + } + ] + }, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "The number of spans observed.", + "name": "trace.span.count", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "timeUnixNano": "1678392127920605000" + } + ], + "isMonotonic": true + } + }, + { + "description": "The number of span events observed.", + "name": "trace.span.event.count", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "16", + "timeUnixNano": "1678392127920605000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "resource.required", + "value": { + "stringValue": "foo" + } + }, + { + "key": "resource.optional", + "value": { + "stringValue": "notbar" } } ] @@ -21,8 +82,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "2", - "timeUnixNano": "1676490033221242000" + "asInt": "4", + "timeUnixNano": "1678392127920632000" } ], "isMonotonic": true @@ -35,8 +96,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "2", - "timeUnixNano": "1676490033221242000" + "asInt": "16", + "timeUnixNano": "1678392127920632000" } ], "isMonotonic": true @@ -53,9 +114,9 @@ "resource": { "attributes": [ { - "key": "resource-attr", + "key": "resource.required", "value": { - "stringValue": "resource-attr-val-2" + "stringValue": "notfoo" } } ] @@ -70,8 +131,48 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "1", - "timeUnixNano": "1676490033221245000" + "asInt": "4", + "timeUnixNano": "1678392127920635000" + } + ], + "isMonotonic": true + } + }, + { + "description": "The number of span events observed.", + "name": "trace.span.event.count", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "16", + "timeUnixNano": "1678392127920635000" + } + ], + "isMonotonic": true + } + } + ], + "scope": { + "name": "otelcol/countconnector" + } + } + ] + }, + { + "resource": {}, + "scopeMetrics": [ + { + "metrics": [ + { + "description": "The number of spans observed.", + "name": "trace.span.count", + "sum": { + "aggregationTemporality": 1, + "dataPoints": [ + { + "asInt": "4", + "timeUnixNano": "1678392127920638000" } ], "isMonotonic": true @@ -84,8 +185,8 @@ "aggregationTemporality": 1, "dataPoints": [ { - "asInt": "0", - "timeUnixNano": "1676490033221245000" + "asInt": "16", + "timeUnixNano": "1678392127920638000" } ], "isMonotonic": true From 89d3ee133fbd44d4216a22e48946b940a24c3f15 Mon Sep 17 00:00:00 2001 From: Dan Jaglowski Date: Thu, 9 Mar 2023 15:50:40 -0500 Subject: [PATCH 2/5] Remove MetricInfoWithAttributes, and instead just ensure no attributes configured for metrics --- connector/countconnector/config.go | 58 ++--- connector/countconnector/config_test.go | 280 ++++++++------------- connector/countconnector/connector_test.go | 262 ++++++++----------- connector/countconnector/factory.go | 8 +- 4 files changed, 227 insertions(+), 381 deletions(-) diff --git a/connector/countconnector/config.go b/connector/countconnector/config.go index df23b3005292..bfdf3df6e3dd 100644 --- a/connector/countconnector/config.go +++ b/connector/countconnector/config.go @@ -39,23 +39,18 @@ const ( // Config for the connector type Config struct { - Spans map[string]MetricInfoWithAttributes `mapstructure:"spans"` - SpanEvents map[string]MetricInfoWithAttributes `mapstructure:"spanevents"` - Metrics map[string]MetricInfo `mapstructure:"metrics"` - DataPoints map[string]MetricInfoWithAttributes `mapstructure:"datapoints"` - Logs map[string]MetricInfoWithAttributes `mapstructure:"logs"` -} - -// MetricInfoWithAttributes for a data type -type MetricInfoWithAttributes struct { - MetricInfo `mapstructure:",squash"` - Attributes []AttributeConfig `mapstructure:"attributes"` + Spans map[string]MetricInfo `mapstructure:"spans"` + SpanEvents map[string]MetricInfo `mapstructure:"spanevents"` + Metrics map[string]MetricInfo `mapstructure:"metrics"` + DataPoints map[string]MetricInfo `mapstructure:"datapoints"` + Logs map[string]MetricInfo `mapstructure:"logs"` } // MetricInfo for a data type type MetricInfo struct { - Description string `mapstructure:"description"` - Conditions []string `mapstructure:"conditions"` + Description string `mapstructure:"description"` + Conditions []string `mapstructure:"conditions"` + Attributes []AttributeConfig `mapstructure:"attributes"` } type AttributeConfig struct { @@ -105,6 +100,9 @@ func (c *Config) Validate() error { if _, err = parseConditions(parser, info.Conditions); 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) + } } for name, info := range c.DataPoints { @@ -140,7 +138,7 @@ func (c *Config) Validate() error { return nil } -func (i *MetricInfoWithAttributes) validateAttributes() error { +func (i *MetricInfo) validateAttributes() error { for _, attr := range i.Attributes { if attr.Key == "" { return fmt.Errorf("attribute key missing") @@ -180,22 +178,18 @@ func (c *Config) Unmarshal(componentParser *confmap.Conf) error { return nil } -func defaultSpansConfig() map[string]MetricInfoWithAttributes { - return map[string]MetricInfoWithAttributes{ +func defaultSpansConfig() map[string]MetricInfo { + return map[string]MetricInfo{ defaultMetricNameSpans: { - MetricInfo: MetricInfo{ - Description: defaultMetricDescSpans, - }, + Description: defaultMetricDescSpans, }, } } -func defaultSpanEventsConfig() map[string]MetricInfoWithAttributes { - return map[string]MetricInfoWithAttributes{ +func defaultSpanEventsConfig() map[string]MetricInfo { + return map[string]MetricInfo{ defaultMetricNameSpanEvents: { - MetricInfo: MetricInfo{ - Description: defaultMetricDescSpanEvents, - }, + Description: defaultMetricDescSpanEvents, }, } } @@ -208,22 +202,18 @@ func defaultMetricsConfig() map[string]MetricInfo { } } -func defaultDataPointsConfig() map[string]MetricInfoWithAttributes { - return map[string]MetricInfoWithAttributes{ +func defaultDataPointsConfig() map[string]MetricInfo { + return map[string]MetricInfo{ defaultMetricNameDataPoints: { - MetricInfo: MetricInfo{ - Description: defaultMetricDescDataPoints, - }, + Description: defaultMetricDescDataPoints, }, } } -func defaultLogsConfig() map[string]MetricInfoWithAttributes { - return map[string]MetricInfoWithAttributes{ +func defaultLogsConfig() map[string]MetricInfo { + return map[string]MetricInfo{ defaultMetricNameLogs: { - MetricInfo: MetricInfo{ - Description: defaultMetricDescLogs, - }, + Description: defaultMetricDescLogs, }, } } diff --git a/connector/countconnector/config_test.go b/connector/countconnector/config_test.go index 825c029bfb70..f8d9cdeaa953 100644 --- a/connector/countconnector/config_test.go +++ b/connector/countconnector/config_test.go @@ -33,18 +33,14 @@ func TestLoadConfig(t *testing.T) { { name: "", expect: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ defaultMetricNameSpans: { - MetricInfo: MetricInfo{ - Description: defaultMetricDescSpans, - }, + Description: defaultMetricDescSpans, }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ defaultMetricNameSpanEvents: { - MetricInfo: MetricInfo{ - Description: defaultMetricDescSpanEvents, - }, + Description: defaultMetricDescSpanEvents, }, }, Metrics: map[string]MetricInfo{ @@ -52,18 +48,14 @@ func TestLoadConfig(t *testing.T) { Description: defaultMetricDescMetrics, }, }, - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ defaultMetricNameDataPoints: { - MetricInfo: MetricInfo{ - Description: defaultMetricDescDataPoints, - }, + Description: defaultMetricDescDataPoints, }, }, - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ defaultMetricNameLogs: { - MetricInfo: MetricInfo{ - Description: defaultMetricDescLogs, - }, + Description: defaultMetricDescLogs, }, }, }, @@ -71,18 +63,14 @@ func TestLoadConfig(t *testing.T) { { name: "custom_description", expect: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ defaultMetricNameSpans: { - MetricInfo: MetricInfo{ - Description: "My description for default span count metric.", - }, + Description: "My description for default span count metric.", }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ defaultMetricNameSpanEvents: { - MetricInfo: MetricInfo{ - Description: "My description for default span event count metric.", - }, + Description: "My description for default span event count metric.", }, }, Metrics: map[string]MetricInfo{ @@ -90,18 +78,14 @@ func TestLoadConfig(t *testing.T) { Description: "My description for default metric count metric.", }, }, - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ defaultMetricNameDataPoints: { - MetricInfo: MetricInfo{ - Description: "My description for default datapoint count metric.", - }, + Description: "My description for default datapoint count metric.", }, }, - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ defaultMetricNameLogs: { - MetricInfo: MetricInfo{ - Description: "My description for default log count metric.", - }, + Description: "My description for default log count metric.", }, }, }, @@ -109,18 +93,14 @@ func TestLoadConfig(t *testing.T) { { name: "custom_metric", expect: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "my.span.count": { - MetricInfo: MetricInfo{ - Description: "My span count.", - }, + Description: "My span count.", }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "my.spanevent.count": { - MetricInfo: MetricInfo{ - Description: "My span event count.", - }, + Description: "My span event count.", }, }, Metrics: map[string]MetricInfo{ @@ -128,18 +108,14 @@ func TestLoadConfig(t *testing.T) { Description: "My metric count.", }, }, - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "my.datapoint.count": { - MetricInfo: MetricInfo{ - Description: "My data point count.", - }, + Description: "My data point count.", }, }, - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "my.logrecord.count": { - MetricInfo: MetricInfo{ - Description: "My log record count.", - }, + Description: "My log record count.", }, }, }, @@ -147,20 +123,16 @@ func TestLoadConfig(t *testing.T) { { name: "condition", expect: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "my.span.count": { - MetricInfo: MetricInfo{ - Description: "My span count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s") == true`}, - }, + Description: "My span count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s") == true`}, }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "my.spanevent.count": { - MetricInfo: MetricInfo{ - Description: "My span event count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e") == true`}, - }, + Description: "My span event count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e") == true`}, }, }, Metrics: map[string]MetricInfo{ @@ -169,20 +141,16 @@ func TestLoadConfig(t *testing.T) { Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-m") == true`}, }, }, - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "my.datapoint.count": { - MetricInfo: MetricInfo{ - Description: "My data point count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d") == true`}, - }, + Description: "My data point count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d") == true`}, }, }, - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "my.logrecord.count": { - MetricInfo: MetricInfo{ - Description: "My log record count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l") == true`}, - }, + Description: "My log record count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l") == true`}, }, }, }, @@ -190,25 +158,21 @@ func TestLoadConfig(t *testing.T) { { name: "multiple_condition", expect: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "my.span.count": { - MetricInfo: MetricInfo{ - Description: "My span count.", - Conditions: []string{ - `IsMatch(resource.attributes["host.name"], "pod-s") == true`, - `IsMatch(resource.attributes["foo"], "bar-s") == true`, - }, + Description: "My span count.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-s") == true`, + `IsMatch(resource.attributes["foo"], "bar-s") == true`, }, }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "my.spanevent.count": { - MetricInfo: MetricInfo{ - Description: "My span event count.", - Conditions: []string{ - `IsMatch(resource.attributes["host.name"], "pod-e") == true`, - `IsMatch(resource.attributes["foo"], "bar-e") == true`, - }, + Description: "My span event count.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-e") == true`, + `IsMatch(resource.attributes["foo"], "bar-e") == true`, }, }, }, @@ -221,25 +185,21 @@ func TestLoadConfig(t *testing.T) { }, }, }, - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "my.datapoint.count": { - MetricInfo: MetricInfo{ - Description: "My data point count.", - Conditions: []string{ - `IsMatch(resource.attributes["host.name"], "pod-d") == true`, - `IsMatch(resource.attributes["foo"], "bar-d") == true`, - }, + Description: "My data point count.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-d") == true`, + `IsMatch(resource.attributes["foo"], "bar-d") == true`, }, }, }, - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "my.logrecord.count": { - MetricInfo: MetricInfo{ - Description: "My log record count.", - Conditions: []string{ - `IsMatch(resource.attributes["host.name"], "pod-l") == true`, - `IsMatch(resource.attributes["foo"], "bar-l") == true`, - }, + Description: "My log record count.", + Conditions: []string{ + `IsMatch(resource.attributes["host.name"], "pod-l") == true`, + `IsMatch(resource.attributes["foo"], "bar-l") == true`, }, }, }, @@ -248,21 +208,17 @@ func TestLoadConfig(t *testing.T) { { name: "attribute", expect: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "my.span.count": { - MetricInfo: MetricInfo{ - Description: "My span count by environment.", - }, + Description: "My span count by environment.", Attributes: []AttributeConfig{ {Key: "env"}, }, }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "my.spanevent.count": { - MetricInfo: MetricInfo{ - Description: "My span event count by environment.", - }, + Description: "My span event count by environment.", Attributes: []AttributeConfig{ {Key: "env"}, }, @@ -273,21 +229,17 @@ func TestLoadConfig(t *testing.T) { Description: "My metric count.", }, }, - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "my.datapoint.count": { - MetricInfo: MetricInfo{ - Description: "My data point count by environment.", - }, + Description: "My data point count by environment.", Attributes: []AttributeConfig{ {Key: "env"}, }, }, }, - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "my.logrecord.count": { - MetricInfo: MetricInfo{ - Description: "My log record count by environment.", - }, + Description: "My log record count by environment.", Attributes: []AttributeConfig{ {Key: "env"}, }, @@ -298,17 +250,13 @@ func TestLoadConfig(t *testing.T) { { name: "multiple_metrics", expect: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "my.span.count": { - MetricInfo: MetricInfo{ - Description: "My span count.", - }, + Description: "My span count.", }, "limited.span.count": { - MetricInfo: MetricInfo{ - Description: "Limited span count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s") == true`}, - }, + Description: "Limited span count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-s") == true`}, Attributes: []AttributeConfig{ { Key: "env", @@ -320,17 +268,13 @@ func TestLoadConfig(t *testing.T) { }, }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "my.spanevent.count": { - MetricInfo: MetricInfo{ - Description: "My span event count.", - }, + Description: "My span event count.", }, "limited.spanevent.count": { - MetricInfo: MetricInfo{ - Description: "Limited span event count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e") == true`}, - }, + Description: "Limited span event count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-e") == true`}, Attributes: []AttributeConfig{ { Key: "env", @@ -350,17 +294,13 @@ func TestLoadConfig(t *testing.T) { Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-m") == true`}, }, }, - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "my.datapoint.count": { - MetricInfo: MetricInfo{ - Description: "My data point count.", - }, + Description: "My data point count.", }, "limited.datapoint.count": { - MetricInfo: MetricInfo{ - Description: "Limited data point count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d") == true`}, - }, + Description: "Limited data point count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-d") == true`}, Attributes: []AttributeConfig{ { Key: "env", @@ -372,17 +312,13 @@ func TestLoadConfig(t *testing.T) { }, }, }, - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "my.logrecord.count": { - MetricInfo: MetricInfo{ - Description: "My log record count.", - }, + Description: "My log record count.", }, "limited.logrecord.count": { - MetricInfo: MetricInfo{ - Description: "Limited log record count.", - Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l") == true`}, - }, + Description: "Limited log record count.", + Conditions: []string{`IsMatch(resource.attributes["host.name"], "pod-l") == true`}, Attributes: []AttributeConfig{ { Key: "env", @@ -424,11 +360,9 @@ func TestConfigErrors(t *testing.T) { { name: "missing_metric_name_span", input: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "": { - MetricInfo: MetricInfo{ - Description: defaultMetricDescSpans, - }, + Description: defaultMetricDescSpans, }, }, }, @@ -437,11 +371,9 @@ func TestConfigErrors(t *testing.T) { { name: "missing_metric_name_spanevent", input: &Config{ - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "": { - MetricInfo: MetricInfo{ - Description: defaultMetricDescSpans, - }, + Description: defaultMetricDescSpans, }, }, }, @@ -461,11 +393,9 @@ func TestConfigErrors(t *testing.T) { { name: "missing_metric_name_datapoint", input: &Config{ - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "": { - MetricInfo: MetricInfo{ - Description: defaultMetricDescSpans, - }, + Description: defaultMetricDescSpans, }, }, }, @@ -474,11 +404,9 @@ func TestConfigErrors(t *testing.T) { { name: "missing_metric_name_log", input: &Config{ - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "": { - MetricInfo: MetricInfo{ - Description: defaultMetricDescSpans, - }, + Description: defaultMetricDescSpans, }, }, }, @@ -487,12 +415,10 @@ func TestConfigErrors(t *testing.T) { { name: "invalid_condition_span", input: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ defaultMetricNameSpans: { - MetricInfo: MetricInfo{ - Description: defaultMetricDescSpans, - Conditions: []string{"invalid condition"}, - }, + Description: defaultMetricDescSpans, + Conditions: []string{"invalid condition"}, }, }, }, @@ -501,12 +427,10 @@ func TestConfigErrors(t *testing.T) { { name: "invalid_condition_spanevent", input: &Config{ - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ defaultMetricNameSpanEvents: { - MetricInfo: MetricInfo{ - Description: defaultMetricDescSpans, - Conditions: []string{"invalid condition"}, - }, + Description: defaultMetricDescSpans, + Conditions: []string{"invalid condition"}, }, }, }, @@ -527,12 +451,10 @@ func TestConfigErrors(t *testing.T) { { name: "invalid_condition_datapoint", input: &Config{ - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ defaultMetricNameDataPoints: { - MetricInfo: MetricInfo{ - Description: defaultMetricDescSpans, - Conditions: []string{"invalid condition"}, - }, + Description: defaultMetricDescSpans, + Conditions: []string{"invalid condition"}, }, }, }, @@ -541,12 +463,10 @@ func TestConfigErrors(t *testing.T) { { name: "invalid_condition_log", input: &Config{ - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ defaultMetricNameLogs: { - MetricInfo: MetricInfo{ - Description: defaultMetricDescSpans, - Conditions: []string{"invalid condition"}, - }, + Description: defaultMetricDescSpans, + Conditions: []string{"invalid condition"}, }, }, }, diff --git a/connector/countconnector/connector_test.go b/connector/countconnector/connector_test.go index 62aeff8e4d36..5528122b0183 100644 --- a/connector/countconnector/connector_test.go +++ b/connector/countconnector/connector_test.go @@ -44,23 +44,19 @@ func TestTracesToMetrics(t *testing.T) { { name: "one_condition", cfg: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "span.count.if": { - MetricInfo: MetricInfo{ - Description: "Span count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - }, + Description: "Span count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, }, }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "spanevent.count.if": { - MetricInfo: MetricInfo{ - Description: "Span event count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - }, + Description: "Span event count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, }, }, }, @@ -69,25 +65,21 @@ func TestTracesToMetrics(t *testing.T) { { name: "multiple_conditions", cfg: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "span.count.if": { - MetricInfo: MetricInfo{ - Description: "Span count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - `attributes["span.optional"] != nil`, - }, + Description: "Span count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["span.optional"] != nil`, }, }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "spanevent.count.if": { - MetricInfo: MetricInfo{ - Description: "Span event count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - `attributes["event.optional"] != nil`, - }, + Description: "Span event count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["event.optional"] != nil`, }, }, }, @@ -96,35 +88,27 @@ func TestTracesToMetrics(t *testing.T) { { name: "multiple_metrics", cfg: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "span.count.all": { - MetricInfo: MetricInfo{ - Description: "All spans count", - }, + Description: "All spans count", }, "span.count.if": { - MetricInfo: MetricInfo{ - Description: "Span count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - `attributes["span.optional"] != nil`, - }, + Description: "Span count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["span.optional"] != nil`, }, }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "spanevent.count.all": { - MetricInfo: MetricInfo{ - Description: "All span events count", - }, + Description: "All span events count", }, "spanevent.count.if": { - MetricInfo: MetricInfo{ - Description: "Span event count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - `attributes["event.optional"] != nil`, - }, + Description: "Span event count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["event.optional"] != nil`, }, }, }, @@ -133,11 +117,9 @@ func TestTracesToMetrics(t *testing.T) { { name: "one_attribute", cfg: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "span.count.by_attr": { - MetricInfo: MetricInfo{ - Description: "Span count by attribute", - }, + Description: "Span count by attribute", Attributes: []AttributeConfig{ { Key: "span.required", @@ -145,11 +127,9 @@ func TestTracesToMetrics(t *testing.T) { }, }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "spanevent.count.by_attr": { - MetricInfo: MetricInfo{ - Description: "Span event count by attribute", - }, + Description: "Span event count by attribute", Attributes: []AttributeConfig{ { Key: "event.required", @@ -162,11 +142,9 @@ func TestTracesToMetrics(t *testing.T) { { name: "multiple_attributes", cfg: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "span.count.by_attr": { - MetricInfo: MetricInfo{ - Description: "Span count by attributes", - }, + Description: "Span count by attributes", Attributes: []AttributeConfig{ { Key: "span.required", @@ -177,11 +155,9 @@ func TestTracesToMetrics(t *testing.T) { }, }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "spanevent.count.by_attr": { - MetricInfo: MetricInfo{ - Description: "Span event count by attributes", - }, + Description: "Span event count by attributes", Attributes: []AttributeConfig{ { Key: "event.required", @@ -197,11 +173,9 @@ func TestTracesToMetrics(t *testing.T) { { name: "default_attribute_value", cfg: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "span.count.by_attr": { - MetricInfo: MetricInfo{ - Description: "Span count by attribute with default", - }, + Description: "Span count by attribute with default", Attributes: []AttributeConfig{ { Key: "span.required", @@ -213,11 +187,9 @@ func TestTracesToMetrics(t *testing.T) { }, }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "spanevent.count.by_attr": { - MetricInfo: MetricInfo{ - Description: "Span event count by attribute with default", - }, + Description: "Span event count by attribute with default", Attributes: []AttributeConfig{ { Key: "event.required", @@ -234,13 +206,11 @@ func TestTracesToMetrics(t *testing.T) { { name: "condition_and_attribute", cfg: &Config{ - Spans: map[string]MetricInfoWithAttributes{ + Spans: map[string]MetricInfo{ "span.count.if.by_attr": { - MetricInfo: MetricInfo{ - Description: "Span count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - }, + Description: "Span count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, }, Attributes: []AttributeConfig{ { @@ -249,13 +219,11 @@ func TestTracesToMetrics(t *testing.T) { }, }, }, - SpanEvents: map[string]MetricInfoWithAttributes{ + SpanEvents: map[string]MetricInfo{ "spanevent.count.if.by_attr": { - MetricInfo: MetricInfo{ - Description: "Span event count by attribute if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - }, + Description: "Span event count by attribute if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, }, Attributes: []AttributeConfig{ { @@ -326,13 +294,11 @@ func TestMetricsToMetrics(t *testing.T) { }, }, }, - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "datapoint.count.if": { - MetricInfo: MetricInfo{ - Description: "Data point count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - }, + Description: "Data point count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, }, }, }, @@ -350,14 +316,12 @@ func TestMetricsToMetrics(t *testing.T) { }, }, }, - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "datapoint.count.if": { - MetricInfo: MetricInfo{ - Description: "Data point count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - `attributes["datapoint.optional"] != nil`, - }, + Description: "Data point count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["datapoint.optional"] != nil`, }, }, }, @@ -378,19 +342,15 @@ func TestMetricsToMetrics(t *testing.T) { }, }, }, - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "datapoint.count.all": { - MetricInfo: MetricInfo{ - Description: "All data points count", - }, + Description: "All data points count", }, "datapoint.count.if": { - MetricInfo: MetricInfo{ - Description: "Data point count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - `attributes["datapoint.optional"] != nil`, - }, + Description: "Data point count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["datapoint.optional"] != nil`, }, }, }, @@ -399,11 +359,9 @@ func TestMetricsToMetrics(t *testing.T) { { name: "one_attribute", cfg: &Config{ - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "datapoint.count.by_attr": { - MetricInfo: MetricInfo{ - Description: "Data point count by attribute", - }, + Description: "Data point count by attribute", Attributes: []AttributeConfig{ { Key: "datapoint.required", @@ -416,11 +374,9 @@ func TestMetricsToMetrics(t *testing.T) { { name: "multiple_attributes", cfg: &Config{ - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "datapoint.count.by_attr": { - MetricInfo: MetricInfo{ - Description: "Data point count by attributes", - }, + Description: "Data point count by attributes", Attributes: []AttributeConfig{ { Key: "datapoint.required", @@ -436,11 +392,9 @@ func TestMetricsToMetrics(t *testing.T) { { name: "default_attribute_value", cfg: &Config{ - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "datapoint.count.by_attr": { - MetricInfo: MetricInfo{ - Description: "Data point count by attribute with default", - }, + Description: "Data point count by attribute with default", Attributes: []AttributeConfig{ { Key: "datapoint.required", @@ -457,13 +411,11 @@ func TestMetricsToMetrics(t *testing.T) { { name: "condition_and_attribute", cfg: &Config{ - DataPoints: map[string]MetricInfoWithAttributes{ + DataPoints: map[string]MetricInfo{ "datapoint.count.if.by_attr": { - MetricInfo: MetricInfo{ - Description: "Data point count by attribute if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - }, + Description: "Data point count by attribute if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, }, Attributes: []AttributeConfig{ { @@ -523,13 +475,11 @@ func TestLogsToMetrics(t *testing.T) { { name: "one_condition", cfg: &Config{ - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "count.if": { - MetricInfo: MetricInfo{ - Description: "Count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - }, + Description: "Count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, }, }, }, @@ -538,14 +488,12 @@ func TestLogsToMetrics(t *testing.T) { { name: "multiple_conditions", cfg: &Config{ - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "count.if": { - MetricInfo: MetricInfo{ - Description: "Count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - `attributes["log.optional"] != nil`, - }, + Description: "Count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, + `attributes["log.optional"] != nil`, }, }, }, @@ -554,18 +502,14 @@ func TestLogsToMetrics(t *testing.T) { { name: "multiple_metrics", cfg: &Config{ - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "count.all": { - MetricInfo: MetricInfo{ - Description: "All logs count", - }, + Description: "All logs count", }, "count.if": { - MetricInfo: MetricInfo{ - Description: "Count if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - }, + Description: "Count if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, }, }, }, @@ -574,11 +518,9 @@ func TestLogsToMetrics(t *testing.T) { { name: "one_attribute", cfg: &Config{ - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "log.count.by_attr": { - MetricInfo: MetricInfo{ - Description: "Log count by attribute", - }, + Description: "Log count by attribute", Attributes: []AttributeConfig{ { Key: "log.required", @@ -591,11 +533,9 @@ func TestLogsToMetrics(t *testing.T) { { name: "multiple_attributes", cfg: &Config{ - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "log.count.by_attr": { - MetricInfo: MetricInfo{ - Description: "Log count by attributes", - }, + Description: "Log count by attributes", Attributes: []AttributeConfig{ { Key: "log.required", @@ -611,11 +551,9 @@ func TestLogsToMetrics(t *testing.T) { { name: "default_attribute_value", cfg: &Config{ - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "log.count.by_attr": { - MetricInfo: MetricInfo{ - Description: "Log count by attribute with default", - }, + Description: "Log count by attribute with default", Attributes: []AttributeConfig{ { Key: "log.required", @@ -632,13 +570,11 @@ func TestLogsToMetrics(t *testing.T) { { name: "condition_and_attribute", cfg: &Config{ - Logs: map[string]MetricInfoWithAttributes{ + Logs: map[string]MetricInfo{ "log.count.if.by_attr": { - MetricInfo: MetricInfo{ - Description: "Log count by attribute if ...", - Conditions: []string{ - `resource.attributes["resource.optional"] != nil`, - }, + Description: "Log count by attribute if ...", + Conditions: []string{ + `resource.attributes["resource.optional"] != nil`, }, Attributes: []AttributeConfig{ { diff --git a/connector/countconnector/factory.go b/connector/countconnector/factory.go index eef4d6149acd..159e34addf4f 100644 --- a/connector/countconnector/factory.go +++ b/connector/countconnector/factory.go @@ -66,7 +66,7 @@ func createTracesToMetrics( } for name, info := range c.Spans { md := metricDef[ottlspan.TransformContext]{ - desc: info.MetricInfo.Description, + desc: info.Description, attrs: info.Attributes, } if len(info.Conditions) > 0 { @@ -84,7 +84,7 @@ func createTracesToMetrics( } for name, info := range c.SpanEvents { md := metricDef[ottlspanevent.TransformContext]{ - desc: info.MetricInfo.Description, + desc: info.Description, attrs: info.Attributes, } if len(info.Conditions) > 0 { @@ -135,7 +135,7 @@ func createMetricsToMetrics( } for name, info := range c.DataPoints { md := metricDef[ottldatapoint.TransformContext]{ - desc: info.MetricInfo.Description, + desc: info.Description, attrs: info.Attributes, } if len(info.Conditions) > 0 { @@ -169,7 +169,7 @@ func createLogsToMetrics( } for name, info := range c.Logs { md := metricDef[ottllog.TransformContext]{ - desc: info.MetricInfo.Description, + desc: info.Description, attrs: info.Attributes, } if len(info.Conditions) > 0 { From c8403320ef3e55ad62cd9f870e13c57b0e2add94 Mon Sep 17 00:00:00 2001 From: Dan Jaglowski Date: Thu, 9 Mar 2023 15:52:13 -0500 Subject: [PATCH 3/5] lint --- connector/countconnector/counter.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/connector/countconnector/counter.go b/connector/countconnector/counter.go index a66ef9c72404..19df0d3b8e16 100644 --- a/connector/countconnector/counter.go +++ b/connector/countconnector/counter.go @@ -25,7 +25,7 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil" ) -var noAttributes [16]byte = [16]byte{} +var noAttributes = [16]byte{} func newCounter[K any](metricDefs map[string]metricDef[K]) *counter[K] { return &counter[K]{ @@ -65,14 +65,14 @@ func (c *counter[K]) update(ctx context.Context, attrs pcommon.Map, tCtx K) erro // No conditions, so match all. if md.condition == nil { - c.increment(name, countAttrs) + errors = multierr.Append(errors, c.increment(name, countAttrs)) continue } if match, err := md.condition.Eval(ctx, tCtx); err != nil { errors = multierr.Append(errors, err) } else if match { - c.increment(name, countAttrs) + errors = multierr.Append(errors, c.increment(name, countAttrs)) } } return errors From 122c129a81ad3f3e41976c38f7f839aeae28ed19 Mon Sep 17 00:00:00 2001 From: Dan Jaglowski Date: Thu, 9 Mar 2023 16:00:12 -0500 Subject: [PATCH 4/5] Add detailed comments about test inputs --- connector/countconnector/connector_test.go | 48 ++++++++++++++++++++++ connector/countconnector/go.mod | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/connector/countconnector/connector_test.go b/connector/countconnector/connector_test.go index 5528122b0183..4cff17fac227 100644 --- a/connector/countconnector/connector_test.go +++ b/connector/countconnector/connector_test.go @@ -29,6 +29,25 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest/pmetrictest" ) +// The test input file has a repetitive structure: +// - There are four resources, each with four spans, each with four span events. +// - The four resources have the following sets of attributes: +// - resource.required: foo, resource.optional: bar +// - resource.required: foo, resource.optional: notbar +// - resource.required: notfoo +// - (no attributes) +// +// - The four spans on each resource have the following sets of attributes: +// - span.required: foo, span.optional: bar +// - span.required: foo, span.optional: notbar +// - span.required: notfoo +// - (no attributes) +// +// - The four span events on each span have the following sets of attributes: +// - event.required: foo, event.optional: bar +// - event.required: foo, event.optional: notbar +// - event.required: notfoo +// - (no attributes) func TestTracesToMetrics(t *testing.T) { testCases := []struct { name string @@ -271,6 +290,22 @@ func TestTracesToMetrics(t *testing.T) { } } +// The test input file has a repetitive structure: +// - There are four resources, each with six metrics, each with four data point. +// - The four resources have the following sets of attributes: +// - resource.required: foo, resource.optional: bar +// - resource.required: foo, resource.optional: notbar +// - resource.required: notfoo +// - (no attributes) +// +// - The size metrics have the following sets of types: +// - int gauge, double gauge, int sum, double sum, historgram, summary +// +// - The four data points on each metric have the following sets of attributes: +// - datapoint.required: foo, datapoint.optional: bar +// - datapoint.required: foo, datapoint.optional: notbar +// - datapoint.required: notfoo +// - (no attributes) func TestMetricsToMetrics(t *testing.T) { testCases := []struct { name string @@ -463,6 +498,19 @@ func TestMetricsToMetrics(t *testing.T) { } } +// The test input file has a repetitive structure: +// - There are four resources, each with four logs. +// - The four resources have the following sets of attributes: +// - resource.required: foo, resource.optional: bar +// - resource.required: foo, resource.optional: notbar +// - resource.required: notfoo +// - (no attributes) +// +// - The four logs on each resource have the following sets of attributes: +// - log.required: foo, log.optional: bar +// - log.required: foo, log.optional: notbar +// - log.required: notfoo +// - (no attributes) func TestLogsToMetrics(t *testing.T) { testCases := []struct { name string diff --git a/connector/countconnector/go.mod b/connector/countconnector/go.mod index 533bb8ee3500..be81cb9a2cb4 100644 --- a/connector/countconnector/go.mod +++ b/connector/countconnector/go.mod @@ -7,6 +7,7 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.73.0 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/ottl v0.73.0 github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.73.0 + github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.73.0 github.com/stretchr/testify v1.8.2 go.opentelemetry.io/collector v0.73.0 go.opentelemetry.io/collector/component v0.73.0 @@ -32,7 +33,6 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.73.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/collector/featuregate v0.73.0 // indirect go.opentelemetry.io/otel v1.14.0 // indirect From cdfc845bc36aa39b7a8f6f8e196e9ce29103c17d Mon Sep 17 00:00:00 2001 From: Daniel Jaglowski Date: Fri, 10 Mar 2023 22:00:02 -0500 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: Antoine Toulme --- connector/countconnector/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/connector/countconnector/config.go b/connector/countconnector/config.go index bfdf3df6e3dd..7afb367b9373 100644 --- a/connector/countconnector/config.go +++ b/connector/countconnector/config.go @@ -86,7 +86,7 @@ func (c *Config) Validate() error { return fmt.Errorf("spanevents condition: metric %q: %w", name, err) } if err := info.validateAttributes(); err != nil { - return fmt.Errorf("spans attributes: metric %q: %w", name, err) + return fmt.Errorf("spanevents attributes: metric %q: %w", name, err) } } for name, info := range c.Metrics { @@ -132,7 +132,7 @@ func (c *Config) Validate() error { return fmt.Errorf("logs condition: metric %q: %w", name, err) } if err := info.validateAttributes(); err != nil { - return fmt.Errorf("spans attributes: metric %q: %w", name, err) + return fmt.Errorf("logs attributes: metric %q: %w", name, err) } } return nil