ROX-32449: include and exclude custom metric label filters#18327
ROX-32449: include and exclude custom metric label filters#18327parametalol merged 13 commits intomasterfrom
Conversation
|
Images are ready for the commit at aaf5871. To use with deploy scripts, first |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #18327 +/- ##
==========================================
+ Coverage 48.92% 48.96% +0.03%
==========================================
Files 2633 2639 +6
Lines 197986 198355 +369
==========================================
+ Hits 96870 97128 +258
- Misses 93727 93811 +84
- Partials 7389 7416 +27
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- In
formatMetricHelp, the include/exclude filter descriptions are built by iterating over maps, so the order of filters in the HELP string will be nondeterministic; consider sorting the label keys first to keep the help output stable and easier to read/debug.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `formatMetricHelp`, the include/exclude filter descriptions are built by iterating over maps, so the order of filters in the HELP string will be nondeterministic; consider sorting the label keys first to keep the help output stable and easier to read/debug.
## Individual Comments
### Comment 1
<location> `central/metrics/custom/tracker/aggregator_test.go:205-156` </location>
<code_context>
+func Test_includeAndExcludeFilter(t *testing.T) {
</code_context>
<issue_to_address>
**suggestion (testing):** Add a test where the same label has both include and exclude filters to verify precedence and semantics
`Test_includeAndExcludeFilter` currently covers interaction across different labels (`Severity` vs `Cluster`). It would be useful to also cover the case where the *same* label has both include and exclude filters (e.g., include `Severity` = `CRITICAL|HIGH`, exclude `Severity` = `CRITICAL`). This would verify the intended precedence (include first, then exclude) and guard against regressions. Consider adding a `Test_includeAndExcludeFilterSameLabel` that asserts the exclude filter wins when patterns overlap.
Suggested implementation:
```golang
func Test_includeAndExcludeFilter(t *testing.T) {
// Include filter to keep only CRITICAL and HIGH severity.
severityInclude := make(map[Label]*regexp.Regexp)
severityInclude[Label("Severity")] = regexp.MustCompile("^CRITICAL|HIGH$")
// Exclude filter to drop cluster 1 findings.
clusterExclude := make(map[Label]*regexp.Regexp)
clusterExclude[Label("Cluster")] = regexp.MustCompile("^cluster 1$")
incFilters := make(LabelFilters)
incFilters[MetricName("test_Test_includeAndExcludeFilter_metric1")] = severityInclude
}
func Test_includeAndExcludeFilterSameLabel(t *testing.T) {
// Include filter to keep only CRITICAL and HIGH severity.
severityInclude := make(map[Label]*regexp.Regexp)
severityInclude[Label("Severity")] = regexp.MustCompile("^CRITICAL|HIGH$")
// Exclude filter on the same label to drop CRITICAL.
severityExclude := make(map[Label]*regexp.Regexp)
severityExclude[Label("Severity")] = regexp.MustCompile("^CRITICAL$")
incFilters := make(LabelFilters)
incFilters[MetricName("test_Test_includeAndExcludeFilterSameLabel_metric1")] = severityInclude
excFilters := make(LabelFilters)
excFilters[MetricName("test_Test_includeAndExcludeFilterSameLabel_metric1")] = severityExclude
a := &aggregator{
includeFilters: incFilters,
excludeFilters: excFilters,
result: make(map[string]*aggregatedRecord),
}
// Record with Severity=CRITICAL should be excluded because exclude wins.
a.aggregate("test_Test_includeAndExcludeFilterSameLabel_metric1", prometheus.Labels{
"Severity": "CRITICAL",
})
// Record with Severity=HIGH should be included.
a.aggregate("test_Test_includeAndExcludeFilterSameLabel_metric1", prometheus.Labels{
"Severity": "HIGH",
})
// We expect only the HIGH record to be present.
require.Len(t, a.result, 1)
record, ok := a.result["test_Test_includeAndExcludeFilterSameLabel_metric1"]
require.True(t, ok)
require.Equal(t, prometheus.Labels{"Severity": "HIGH"}, record.labels)
require.Equal(t, 1, record.total)
```
Because I only see part of the file, please verify and, if needed, adjust the following to match existing patterns in `aggregator_test.go`:
1. **Tracker construction pattern**: If existing tests construct the `aggregator` (or tracker) through a helper (e.g., `newAggregator(...)` or `newTracker(...)`) rather than instantiating `aggregator` directly, mirror that pattern in `Test_includeAndExcludeFilterSameLabel` instead of using the inline struct literal.
2. **Metric keying pattern**: If `a.result` is keyed by something other than the metric name string (e.g., a composite key or namespace), adapt the lookup and expected key accordingly.
3. **Expectation helpers**: If the file consistently uses `assert` instead of `require` (or uses `t.Helper()` wrappers), adjust the new test’s assertions to use the same assertion style and helpers.
4. **Label set shape**: If `aggregatedRecord.labels` in other tests includes additional fixed labels besides `Severity`, extend the expected `prometheus.Labels` map in the new test to include those labels as well.
</issue_to_address>
### Comment 2
<location> `central/metrics/custom/tracker/validator_test.go:93-102` </location>
<code_context>
+ config = map[string]*storage.PrometheusMetrics_Group_Labels{
</code_context>
<issue_to_address>
**suggestion (testing):** Add tests covering exclude_filter parsing errors and messaging for translateStorageConfiguration/parseFilters
The new tests cover invalid include filter labels and patterns, but `translateStorageConfiguration` also uses `parseFilters` for `ExcludeFilters` with a different error prefix. Please add analogous `ExcludeFilters` cases: one with an unknown label (validated via `validateLabel`, asserting the label/metric appear in the error) and one with an invalid regex (asserting the `bad exclude_filter expression` message). This will exercise the new `filterType` argument and protect against regressions in exclude filter error handling.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
sachaudh
left a comment
There was a problem hiding this comment.
Thanks for taking this on @parametalol. I have a few comments/suggestions for you on the UI code. Let me know if you have any questions.
ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx
Outdated
Show resolved
Hide resolved
ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx
Outdated
Show resolved
Hide resolved
ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx
Show resolved
Hide resolved
ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx
Outdated
Show resolved
Hide resolved
ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx
Show resolved
Hide resolved
3d0daf8 to
74c7c53
Compare
ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx
Show resolved
Hide resolved
sachaudh
left a comment
There was a problem hiding this comment.
I think converting relevant functions to components in the next PR would be highly encouraged, and I believe you intend to do so. So LGTM 👍🏼
Description
User-facing documentation
Testing and quality
Automated testing
How I validated my change
CI, manual.
Updated filters column