add label_matcher param to filter alerts (#5353)
Signed-off-by: junot <junotxiang@kubesphere.io> Signed-off-by: junot <junotxiang@kubesphere.io>
This commit is contained in:
@@ -35,6 +35,7 @@ const (
|
||||
// for alert
|
||||
FieldAlertLabelFilters = "label_filters"
|
||||
FieldAlertActiveAt = "activeAt"
|
||||
FieldAlertLabelMatcher = "label_matcher"
|
||||
)
|
||||
|
||||
var SortableFields = []string{
|
||||
|
||||
@@ -66,6 +66,7 @@ func AddToContainer(container *restful.Container, informers informers.InformerFa
|
||||
Param(ws.QueryParameter(query.ParameterOrderBy, "sort parameters, one of `activeAt`. e.g. orderBy=activeAt")).
|
||||
Param(ws.QueryParameter(kapialertingv2beta1.FieldState, "state, one of `firing`, `pending`")).
|
||||
Param(ws.QueryParameter(kapialertingv2beta1.FieldAlertLabelFilters, "label filters, concatenating multiple filters with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a").DataFormat("key=%s,key~%s")).
|
||||
Param(ws.QueryParameter(kapialertingv2beta1.FieldAlertLabelMatcher, "label matcher to match alert labels, follow prometheus matcher format. e.g. `{label_name1=\"valueA\",label_name2=~\"valueB|valueC\"}`")).
|
||||
Returns(http.StatusOK, kapi.StatusOK, kapi.ListResult{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AlertingTag}))
|
||||
|
||||
@@ -96,6 +97,7 @@ func AddToContainer(container *restful.Container, informers informers.InformerFa
|
||||
Param(ws.QueryParameter(query.ParameterOrderBy, "sort parameters, one of `activeAt`. e.g. orderBy=activeAt")).
|
||||
Param(ws.QueryParameter(kapialertingv2beta1.FieldState, "state, one of `firing`, `pending`")).
|
||||
Param(ws.QueryParameter(kapialertingv2beta1.FieldAlertLabelFilters, "label filters, concatenating multiple filters with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a").DataFormat("key=%s,key~%s")).
|
||||
Param(ws.QueryParameter(kapialertingv2beta1.FieldAlertLabelMatcher, "label matcher to match alert labels, follow prometheus matcher format. e.g. `{label_name1=\"valueA\",label_name2=~\"valueB|valueC\"}`")).
|
||||
Returns(http.StatusOK, kapi.StatusOK, kapi.ListResult{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AlertingTag}))
|
||||
|
||||
@@ -120,13 +122,14 @@ func AddToContainer(container *restful.Container, informers informers.InformerFa
|
||||
|
||||
ws.Route(ws.GET("/globalalerts").
|
||||
To(handler.handleListGlobalAlerts).
|
||||
Doc("list the alerts of globalrulegroups in the cluster").
|
||||
Doc("list the alerts of globalrulegroups").
|
||||
Param(ws.QueryParameter(query.ParameterPage, "page").Required(false).DataFormat("page=%d").DefaultValue("page=1")).
|
||||
Param(ws.QueryParameter(query.ParameterLimit, "limit").Required(false)).
|
||||
Param(ws.QueryParameter(query.ParameterAscending, "sort parameters, e.g. reverse=true").Required(false).DefaultValue("ascending=false")).
|
||||
Param(ws.QueryParameter(query.ParameterOrderBy, "sort parameters, one of `activeAt`. e.g. orderBy=activeAt")).
|
||||
Param(ws.QueryParameter(kapialertingv2beta1.FieldState, "state, one of `firing`, `pending`")).
|
||||
Param(ws.QueryParameter(kapialertingv2beta1.FieldAlertLabelFilters, "label filters, concatenating multiple filters with commas, equal symbol for exact query, wave symbol for fuzzy query e.g. name~a").DataFormat("key=%s,key~%s")).
|
||||
Param(ws.QueryParameter(kapialertingv2beta1.FieldAlertLabelMatcher, "label matcher to match alert labels, follow prometheus matcher format. e.g. `{label_name1=\"valueA\",label_name2=~\"valueB|valueC\"}`")).
|
||||
Param(ws.QueryParameter(kapialertingv2beta1.FieldBuiltin, "filter alerts, `true` for alerts from built-in rule groups and `false` for alerts from custom rule groups")).
|
||||
Returns(http.StatusOK, kapi.StatusOK, kapi.ListResult{}).
|
||||
Metadata(restfulspec.KeyOpenAPITags, []string{constants.AlertingTag}))
|
||||
|
||||
@@ -16,9 +16,11 @@ package alerting
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
promlabels "github.com/prometheus/prometheus/pkg/labels"
|
||||
"github.com/prometheus/prometheus/promql/parser"
|
||||
promrules "github.com/prometheus/prometheus/rules"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
@@ -243,7 +245,10 @@ func (o *ruleGroupOperator) ListAlerts(ctx context.Context, namespace string,
|
||||
}
|
||||
}
|
||||
|
||||
filterAlert := o.createFilterAlertFunc(queryParam)
|
||||
filterAlert, err := o.createFilterAlertFunc(queryParam)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
listResult := resources.DefaultList(alerts, queryParam, func(left, right runtime.Object, field query.Field) bool {
|
||||
return o.compareAlert(&left.(*wrapAlert).Alert, &right.(*wrapAlert).Alert, field)
|
||||
}, func(obj runtime.Object, filter query.Filter) bool {
|
||||
@@ -269,12 +274,20 @@ func (d *ruleGroupOperator) compareAlert(left, right *kapialertingv2beta1.Alert,
|
||||
return false
|
||||
}
|
||||
|
||||
func (d *ruleGroupOperator) createFilterAlertFunc(queryParam *query.Query) func(alert *kapialertingv2beta1.Alert, filter query.Filter) bool {
|
||||
func (d *ruleGroupOperator) createFilterAlertFunc(queryParam *query.Query) (func(alert *kapialertingv2beta1.Alert, filter query.Filter) bool, error) {
|
||||
var labelFilters kapialertingv2beta1.LabelFilters
|
||||
var labelMatchers []*promlabels.Matcher
|
||||
var err error
|
||||
if len(queryParam.Filters) > 0 {
|
||||
if filters, ok := queryParam.Filters[kapialertingv2beta1.FieldAlertLabelFilters]; ok {
|
||||
labelFilters = kapialertingv2beta1.ParseLabelFilters(string(filters))
|
||||
}
|
||||
if matcherStr, ok := queryParam.Filters[kapialertingv2beta1.FieldAlertLabelMatcher]; ok {
|
||||
labelMatchers, err = parser.ParseMetricSelector(string(matcherStr))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid %s param: %v", kapialertingv2beta1.FieldAlertLabelMatcher, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return func(alert *kapialertingv2beta1.Alert, filter query.Filter) bool {
|
||||
switch filter.Field {
|
||||
@@ -283,11 +296,22 @@ func (d *ruleGroupOperator) createFilterAlertFunc(queryParam *query.Query) func(
|
||||
return true
|
||||
}
|
||||
return labelFilters.Matches(alert.Labels)
|
||||
case kapialertingv2beta1.FieldAlertLabelMatcher:
|
||||
for _, m := range labelMatchers {
|
||||
var v string
|
||||
if len(alert.Labels) > 0 {
|
||||
v = alert.Labels[m.Name]
|
||||
}
|
||||
if !m.Matches(v) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case kapialertingv2beta1.FieldState:
|
||||
return alert.State == string(filter.Value)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (o *ruleGroupOperator) GetRuleGroup(ctx context.Context, namespace, name string) (*kapialertingv2beta1.RuleGroup, error) {
|
||||
@@ -474,7 +498,10 @@ func (o *ruleGroupOperator) ListClusterAlerts(ctx context.Context,
|
||||
}
|
||||
}
|
||||
|
||||
filterAlert := o.createFilterAlertFunc(queryParam)
|
||||
filterAlert, err := o.createFilterAlertFunc(queryParam)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
listResult := resources.DefaultList(alerts, queryParam, func(left, right runtime.Object, field query.Field) bool {
|
||||
return o.compareAlert(&left.(*wrapAlert).Alert, &right.(*wrapAlert).Alert, field)
|
||||
}, func(obj runtime.Object, filter query.Filter) bool {
|
||||
@@ -717,7 +744,10 @@ func (o *ruleGroupOperator) ListGlobalAlerts(ctx context.Context,
|
||||
}
|
||||
}
|
||||
|
||||
filterAlert := o.createFilterAlertFunc(queryParam)
|
||||
filterAlert, err := o.createFilterAlertFunc(queryParam)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
listResult := resources.DefaultList(alerts, queryParam, func(left, right runtime.Object, field query.Field) bool {
|
||||
return o.compareAlert(&left.(*wrapAlert).Alert, &right.(*wrapAlert).Alert, field)
|
||||
}, func(obj runtime.Object, filter query.Filter) bool {
|
||||
|
||||
Reference in New Issue
Block a user