@@ -22,13 +22,16 @@ var (
2222 defaultRetryAttempts = 60
2323)
2424
25- func CheckMetric (promAddress , metricName string , validMetric map [string ]string ) error {
25+ func CheckMetric (promAddress , metricName string , validMetric map [string ]string , partial ... bool ) error {
2626 defaultRetrier := retry.Retrier {Attempts : defaultRetryAttempts , Delay : defaultRetryDelay }
2727
2828 ctx := context .Background ()
2929 pctx , cancel := context .WithCancel (ctx )
3030 defer cancel ()
3131
32+ // Default partial to false if not provided
33+ usePartial := len (partial ) > 0 && partial [0 ]
34+
3235 metrics := map [string ]* promclient.MetricFamily {}
3336 scrapeMetricsFn := func () error {
3437 log .Printf ("checking for metrics on %s" , promAddress )
@@ -42,7 +45,11 @@ func CheckMetric(promAddress, metricName string, validMetric map[string]string)
4245
4346 // loop through each metric to check for a match,
4447 // if none is found then log and return an error which will trigger a retry
45- err = verifyValidMetricPresent (metricName , metrics , validMetric )
48+ if usePartial {
49+ err = verifyValidMetricPresentPartial (metricName , metrics , validMetric )
50+ } else {
51+ err = verifyValidMetricPresent (metricName , metrics , validMetric )
52+ }
4653 if err != nil {
4754 log .Printf ("failed to find metric matching %s: %+v\n " , metricName , validMetric )
4855 return ErrNoMetricFound
@@ -99,6 +106,43 @@ func verifyValidMetricPresent(metricName string, data map[string]*promclient.Met
99106 return fmt .Errorf ("failed to find metric matching: %+v: %w" , validMetric , ErrNoMetricFound )
100107}
101108
109+ // verifyValidMetricPresentPartial checks if a metric exists with labels that contain
110+ // all the key-value pairs in validMetric (partial matching - the metric can have additional labels)
111+ func verifyValidMetricPresentPartial (metricName string , data map [string ]* promclient.MetricFamily , validMetric map [string ]string ) error {
112+ for _ , metric := range data {
113+ if metric .GetName () == metricName {
114+ for _ , metric := range metric .GetMetric () {
115+
116+ // get all labels and values on the metric
117+ metricLabels := map [string ]string {}
118+ for _ , label := range metric .GetLabel () {
119+ metricLabels [label .GetName ()] = label .GetValue ()
120+ }
121+
122+ // if valid metric is empty, then we just need to make sure the metric and value is present
123+ if len (validMetric ) == 0 && len (metricLabels ) > 0 {
124+ return nil
125+ }
126+
127+ // Check if all key-value pairs in validMetric exist in metricLabels
128+ allMatch := true
129+ for key , value := range validMetric {
130+ if metricLabels [key ] != value {
131+ allMatch = false
132+ break
133+ }
134+ }
135+
136+ if allMatch {
137+ return nil
138+ }
139+ }
140+ }
141+ }
142+
143+ return fmt .Errorf ("failed to find metric matching: %+v: %w" , validMetric , ErrNoMetricFound )
144+ }
145+
102146func getAllPrometheusMetricsFromURL (url string ) (map [string ]* promclient.MetricFamily , error ) {
103147 client := http.Client {}
104148 resp , err := client .Get (url ) //nolint
0 commit comments