Skip to content

[small bug fix] [metrics transform processor] check all data points for matching metric label values #3435

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 8, 2021

Conversation

hossain-rayhan
Copy link
Contributor

Description:
This change fixes a small bug for newly added experimental_match_label feature in the metricstransform processor. Earlier we used to check only the first datapoint while matching the metric label values. But that case is not always true and the feature is not working to support our use case. This change checks all the data points and search for proper metric label value match.

Testing:
Unit tests added.
Manually tested.

Documentation:
README

@hossain-rayhan hossain-rayhan requested a review from a team May 20, 2021 01:25
@@ -92,9 +93,13 @@ func (f internalFilterStrict) getSubexpNames() []string {
return nil
}

func (f internalFilterStrict) labelMatched(metric *metricspb.Metric) bool {
func (f internalFilterStrict) labelMatched(metric *metricspb.Metric) *metricspb.Metric {
metricWithMatchedLabel := proto.Clone(metric).(*metricspb.Metric)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need to clone? Can you avoid it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than cloning the whole metric object, now I am copying the Resource and MetricDescriptor. We don't want to modify the incoming pdata.Metric, thats way generating a new Metric and returning it. Pushed an update.

Copy link

@sfc-gh-rnishant sfc-gh-rnishant Mar 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hossain-rayhan Was there any specific reasons to clone the objects. Like were you seeing an error or test failures ?
I am asking because cloning seems to be reason for why updates are not working with experimental_match_label.
cc @anuraaga @Aneurysm9

My observation is as follows - When we returns a cloned "MetricDescriptor" object, the update at this point fails -
https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/processor/metricstransformprocessor/metrics_transform_processor.go#L423

This is because, the above line is updating a cloned object rather than updating the original "MetricDescriptor" object.
one such example is here - #7071

Please let me know what do you think ?

}

for _, timeseries := range metric.Timeseries {
allValuesMatched := true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a lot of duplicated code, can you clean it up?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I think much of this commonality could be extracted by defining a StringMatcher interface:

type StringMatcher interface {
	MatchString(string) bool
}

All of the values in internalFilterRegexp will already satisfy it since Regexp has a MatchString(string) method. internalFilterStrict can be made to utilize it by defining a value type:

type strictMatcher string
func (s strictMatcher) MatchString(cmp string) bool {
	return string(s) == cmp
)

At that point the labelMatched() logic can be extracted and updated to this signature:

labelMatched(labelMatchers []StringMatcher, metric *metricspb.Metric) *metricspb.Metric {...}

Since the only value used from the receiver in either of the labelMatched implementations is the list of match targets, this should neatly eliminate the duplication.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried to follow your suggestion. Pushed an update.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copied your suggested code @Aneurysm9 . Please check.

}

for _, timeseries := range metric.Timeseries {
allValuesMatched := true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I think much of this commonality could be extracted by defining a StringMatcher interface:

type StringMatcher interface {
	MatchString(string) bool
}

All of the values in internalFilterRegexp will already satisfy it since Regexp has a MatchString(string) method. internalFilterStrict can be made to utilize it by defining a value type:

type strictMatcher string
func (s strictMatcher) MatchString(cmp string) bool {
	return string(s) == cmp
)

At that point the labelMatched() logic can be extracted and updated to this signature:

labelMatched(labelMatchers []StringMatcher, metric *metricspb.Metric) *metricspb.Metric {...}

Since the only value used from the receiver in either of the labelMatched implementations is the list of match targets, this should neatly eliminate the duplication.

@github-actions
Copy link
Contributor

github-actions bot commented Jun 1, 2021

This PR was marked stale due to lack of activity. It will be closed in 7 days.

@github-actions github-actions bot added the Stale label Jun 1, 2021
@hossain-rayhan
Copy link
Contributor Author

Will address the PR feedbacks.

@github-actions github-actions bot removed the Stale label Jun 2, 2021
@hossain-rayhan
Copy link
Contributor Author

Hi @Aneurysm9 thanks for your suggestion. I copied your code to update the map conversion and used regex.Compile() instead of regex.MustCompile(). Please have another look.

@hossain-rayhan
Copy link
Contributor Author

Hi @tigrannajaryan and @bogdandrutu can we get this small bug fix merged?

@tigrannajaryan tigrannajaryan merged commit c167034 into open-telemetry:main Jun 8, 2021
alexperez52 referenced this pull request in open-o11y/opentelemetry-collector-contrib Aug 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants