From 756ebfa0f3d42b0966af3e45ce325f8ac73dd2e7 Mon Sep 17 00:00:00 2001 From: Julien Pinsonneau Date: Thu, 22 Feb 2024 10:14:18 +0100 Subject: [PATCH] add 'different' filter to prom metrics --- pkg/api/api.go | 1 + pkg/api/encode_prom.go | 11 +++--- pkg/pipeline/encode/encode_prom_metric.go | 42 +++++++++++++++-------- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/pkg/api/api.go b/pkg/api/api.go index 0bbc0d725..2ff4fbe93 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -51,6 +51,7 @@ const ( AddKubernetesInfraRuleType = "add_kubernetes_infra" ReinterpretDirectionRuleType = "reinterpret_direction" PromFilterExact = "exact" + PromFilterDifferent = "different" PromFilterPresence = "presence" PromFilterAbsence = "absence" PromFilterRegex = "regex" diff --git a/pkg/api/encode_prom.go b/pkg/api/encode_prom.go index 07213d613..98faff43c 100644 --- a/pkg/api/encode_prom.go +++ b/pkg/api/encode_prom.go @@ -70,14 +70,15 @@ type MetricsItems []MetricsItem type MetricsFilter struct { Key string `yaml:"key" json:"key" doc:"the key to match and filter by"` Value string `yaml:"value" json:"value" doc:"the value to match and filter by"` - Type string `yaml:"type" json:"type" enum:"MetricEncodeFilterTypeEnum" doc:"the type of filter match: exact (default), presence, absence or regex"` + Type string `yaml:"type" json:"type" enum:"MetricEncodeFilterTypeEnum" doc:"the type of filter match: exact (default), different, presence, absence or regex"` } type MetricEncodeFilterTypeEnum struct { - Exact string `yaml:"exact" json:"exact" doc:"match exactly the provided fitler value"` - Presence string `yaml:"presence" json:"presence" doc:"filter key must be present (filter value is ignored)"` - Absence string `yaml:"absence" json:"absence" doc:"filter key must be absent (filter value is ignored)"` - Regex string `yaml:"regex" json:"regex" doc:"match filter value as a regular expression"` + Exact string `yaml:"exact" json:"exact" doc:"match exactly the provided fitler value"` + Different string `yaml:"different" json:"different" doc:"not match the provided fitler value"` + Presence string `yaml:"presence" json:"presence" doc:"filter key must be present (filter value is ignored)"` + Absence string `yaml:"absence" json:"absence" doc:"filter key must be absent (filter value is ignored)"` + Regex string `yaml:"regex" json:"regex" doc:"match filter value as a regular expression"` } func MetricEncodeFilterTypeName(t string) string { diff --git a/pkg/pipeline/encode/encode_prom_metric.go b/pkg/pipeline/encode/encode_prom_metric.go index 15fe7854e..38586f81e 100644 --- a/pkg/pipeline/encode/encode_prom_metric.go +++ b/pkg/pipeline/encode/encode_prom_metric.go @@ -15,30 +15,29 @@ type MetricInfo struct { FilterPredicates []Predicate } -func Presence(filter api.MetricsFilter) Predicate { +func presence(filter api.MetricsFilter) Predicate { return func(flow config.GenericMap) bool { _, found := flow[filter.Key] return found } } -func Absence(filter api.MetricsFilter) Predicate { +func absence(filter api.MetricsFilter) Predicate { return func(flow config.GenericMap) bool { _, found := flow[filter.Key] return !found } } -func Exact(filter api.MetricsFilter) Predicate { +func exact(filter api.MetricsFilter) Predicate { return func(flow config.GenericMap) bool { - if val, found := flow[filter.Key]; found { - sVal, ok := val.(string) - if !ok { - sVal = fmt.Sprint(val) - } - return sVal == filter.Value - } - return false + return matchExactly(flow, filter) + } +} + +func different(filter api.MetricsFilter) Predicate { + return func(flow config.GenericMap) bool { + return !matchExactly(flow, filter) } } @@ -59,16 +58,18 @@ func regex(filter api.MetricsFilter) Predicate { func filterToPredicate(filter api.MetricsFilter) Predicate { switch filter.Type { case api.PromFilterExact: - return Exact(filter) + return exact(filter) + case api.PromFilterDifferent: + return different(filter) case api.PromFilterPresence: - return Presence(filter) + return presence(filter) case api.PromFilterAbsence: - return Absence(filter) + return absence(filter) case api.PromFilterRegex: return regex(filter) } // Default = Exact - return Exact(filter) + return exact(filter) } func CreateMetricInfo(def api.MetricsItem) *MetricInfo { @@ -80,3 +81,14 @@ func CreateMetricInfo(def api.MetricsItem) *MetricInfo { } return &mi } + +func matchExactly(flow config.GenericMap, filter api.MetricsFilter) bool { + if val, found := flow[filter.Key]; found { + sVal, ok := val.(string) + if !ok { + sVal = fmt.Sprint(val) + } + return sVal == filter.Value + } + return false +}