mirror of
https://github.com/grafana/grafana.git
synced 2025-07-30 21:02:45 +08:00
Scopes: Merge scopes filters with OR condition in case they overlap. (#97276)
Signed-off-by: bergquist <carl.bergquist@gmail.com>
This commit is contained in:
@ -73,11 +73,31 @@ func ApplyFiltersAndGroupBy(rawExpr string, scopeFilters, adHocFilters []ScopeFi
|
||||
func FiltersToMatchers(scopeFilters, adhocFilters []ScopeFilter) ([]*labels.Matcher, error) {
|
||||
filterMap := make(map[string]*labels.Matcher)
|
||||
|
||||
for _, filter := range append(scopeFilters, adhocFilters...) {
|
||||
// scope filters are applied first
|
||||
for _, filter := range scopeFilters {
|
||||
matcher, err := filterToMatcher(filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// when scopes have the same key, both values should be matched
|
||||
// in prometheus that means using an regex with both values
|
||||
if _, ok := filterMap[filter.Key]; ok {
|
||||
filterMap[filter.Key].Value = filterMap[filter.Key].Value + "|" + matcher.Value
|
||||
filterMap[filter.Key].Type = labels.MatchRegexp
|
||||
} else {
|
||||
filterMap[filter.Key] = matcher
|
||||
}
|
||||
}
|
||||
|
||||
// ad hoc filters are applied after scope filters
|
||||
for _, filter := range adhocFilters {
|
||||
matcher, err := filterToMatcher(filter)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// when ad hoc filters have the same key, the last one should be used
|
||||
filterMap[filter.Key] = matcher
|
||||
}
|
||||
|
||||
|
@ -106,6 +106,29 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) {
|
||||
expected: `{__name__="http_requests_total",namespace="istio"}`,
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: "merge scopes filters into using OR if they share filter key",
|
||||
query: `http_requests_total{}`,
|
||||
scopeFilters: []ScopeFilter{
|
||||
{Key: "namespace", Value: "default", Operator: FilterOperatorEquals},
|
||||
{Key: "namespace", Value: "kube-system", Operator: FilterOperatorEquals},
|
||||
},
|
||||
expected: `http_requests_total{namespace=~"default|kube-system"}`,
|
||||
expectErr: false,
|
||||
},
|
||||
{
|
||||
name: "adhoc filters win over scope filters if they share filter key",
|
||||
query: `http_requests_total{}`,
|
||||
scopeFilters: []ScopeFilter{
|
||||
{Key: "namespace", Value: "default", Operator: FilterOperatorEquals},
|
||||
{Key: "namespace", Value: "kube-system", Operator: FilterOperatorEquals},
|
||||
},
|
||||
adhocFilters: []ScopeFilter{
|
||||
{Key: "namespace", Value: "adhoc-wins", Operator: FilterOperatorEquals},
|
||||
},
|
||||
expected: `http_requests_total{namespace="adhoc-wins"}`,
|
||||
expectErr: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
@ -116,7 +139,7 @@ func TestApplyQueryFiltersAndGroupBy_Filters(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.expected, expr)
|
||||
require.Equal(t, tt.expected, expr, tt.name)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user