From 4a2ed0da2d092d952ef3bf41e12689d6632ad2e4 Mon Sep 17 00:00:00 2001 From: Curtis Robert Date: Thu, 30 Jan 2025 20:11:49 -0800 Subject: [PATCH] [processor/metricsgeneration] Add config validation for generated metric names (#37599) #### Description If a generated metric name matched the metric being scaled an infinite loop is hit. Since this action is not supported by this processor, and is supported by the metrics transform processor, the fix here is to add config validation to enforce metric names are different. #### Link to tracking issue Fixes #37474 #### Testing Added a test to ensure enforcement is done properly. --- .chloggen/metricsgeneration_loop.yaml | 27 +++++++++++++++++++ .../metricsgenerationprocessor/config.go | 6 +++++ .../metricsgenerationprocessor/config_test.go | 8 ++++++ .../testdata/config.yaml | 16 +++++++++++ 4 files changed, 57 insertions(+) create mode 100644 .chloggen/metricsgeneration_loop.yaml diff --git a/.chloggen/metricsgeneration_loop.yaml b/.chloggen/metricsgeneration_loop.yaml new file mode 100644 index 000000000000..95e2fb84f1be --- /dev/null +++ b/.chloggen/metricsgeneration_loop.yaml @@ -0,0 +1,27 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: bug_fix + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: metricsgenerationprocessor + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: Generated metric name may not match metric being scaled + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [37474] + +# (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: + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [] diff --git a/processor/metricsgenerationprocessor/config.go b/processor/metricsgenerationprocessor/config.go index 54c857c5604b..7cf6cfd7d26b 100644 --- a/processor/metricsgenerationprocessor/config.go +++ b/processor/metricsgenerationprocessor/config.go @@ -161,6 +161,12 @@ func (config *Config) Validate() error { if rule.Operation != "" && !rule.Operation.isValid() { return fmt.Errorf("%q must be in %q", operationFieldName, operationTypeKeys()) } + + if rule.Name == rule.Metric1 { + return fmt.Errorf("value of field %q may not match value of field %q", nameFieldName, metric1FieldName) + } else if rule.Name == rule.Metric2 { + return fmt.Errorf("value of field %q may not match value of field %q", nameFieldName, metric2FieldName) + } } return nil } diff --git a/processor/metricsgenerationprocessor/config_test.go b/processor/metricsgenerationprocessor/config_test.go index 04e98ab7a433..f40b0cdda319 100644 --- a/processor/metricsgenerationprocessor/config_test.go +++ b/processor/metricsgenerationprocessor/config_test.go @@ -75,6 +75,14 @@ func TestLoadConfig(t *testing.T) { id: component.NewIDWithName(metadata.Type, "invalid_operation"), errorMessage: fmt.Sprintf("%q must be in %q", operationFieldName, operationTypeKeys()), }, + { + id: component.NewIDWithName(metadata.Type, "matching_metric1"), + errorMessage: fmt.Sprintf("value of field %q may not match value of field %q", nameFieldName, metric1FieldName), + }, + { + id: component.NewIDWithName(metadata.Type, "matching_metric2"), + errorMessage: fmt.Sprintf("value of field %q may not match value of field %q", nameFieldName, metric2FieldName), + }, } for _, tt := range tests { diff --git a/processor/metricsgenerationprocessor/testdata/config.yaml b/processor/metricsgenerationprocessor/testdata/config.yaml index b19bbf716046..1d72af8f4775 100644 --- a/processor/metricsgenerationprocessor/testdata/config.yaml +++ b/processor/metricsgenerationprocessor/testdata/config.yaml @@ -68,3 +68,19 @@ metricsgeneration/missing_type: metric1: metric1 metric2: metric2 operation: percent + +metricsgeneration/matching_metric1: + rules: + - name: new_metric + type: scale + metric1: new_metric + operation: multiply + scale_by: 100 + +metricsgeneration/matching_metric2: + rules: + - name: new_metric + type: calculate + metric1: original + metric2: new_metric + operation: multiply