From 3affe77f2de7333a8ab318f189778fdbd155d580 Mon Sep 17 00:00:00 2001 From: Waschndolos Date: Thu, 14 Sep 2023 18:39:19 +0200 Subject: [PATCH] Fixes #554. Apply Metric Filter on all external metrics --- .../disabledmetrics/MetricStatusChecker.java | 12 ++++++++- .../service/DefaultPrometheusMetrics.java | 17 +++++++++++- .../MetricStatusCheckerTest.java | 27 +++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/config/disabledmetrics/MetricStatusChecker.java b/src/main/java/org/jenkinsci/plugins/prometheus/config/disabledmetrics/MetricStatusChecker.java index cca188f0c..3f7e4cc47 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/config/disabledmetrics/MetricStatusChecker.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/config/disabledmetrics/MetricStatusChecker.java @@ -1,12 +1,15 @@ package org.jenkinsci.plugins.prometheus.config.disabledmetrics; +import io.prometheus.client.Collector; +import io.prometheus.client.CollectorRegistry; import org.jenkinsci.plugins.prometheus.config.PrometheusConfiguration; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; public class MetricStatusChecker { @@ -51,4 +54,11 @@ public static boolean isEnabled(String metricName) { } return true; } + + public static Set filter(List allMetricNames) { + if (allMetricNames == null) { + return new HashSet<>(); + } + return allMetricNames.stream().filter(MetricStatusChecker::isEnabled).collect(Collectors.toSet()); + } } diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java b/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java index 99259f1f8..2b7935a9b 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/service/DefaultPrometheusMetrics.java @@ -8,12 +8,14 @@ import io.prometheus.client.hotspot.DefaultExports; import jenkins.metrics.api.Metrics; import org.jenkinsci.plugins.prometheus.*; +import org.jenkinsci.plugins.prometheus.config.disabledmetrics.MetricStatusChecker; import org.jenkinsci.plugins.prometheus.util.JenkinsNodeBuildsSampleBuilder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.StringWriter; +import java.util.*; import java.util.concurrent.atomic.AtomicReference; public class DefaultPrometheusMetrics implements PrometheusMetrics { @@ -49,10 +51,23 @@ public String getMetrics() { @Override public void collectMetrics() { try (StringWriter buffer = new StringWriter()) { - TextFormat.write004(buffer, collectorRegistry.metricFamilySamples()); + Set filteredMetrics = MetricStatusChecker.filter(getMetricNames()); + TextFormat.write004(buffer, collectorRegistry.filteredMetricFamilySamples(filteredMetrics)); cachedMetrics.set(buffer.toString()); } catch (IOException e) { logger.debug("Unable to collect metrics"); } } + + private List getMetricNames() { + Enumeration metricFamilySamplesEnumeration = collectorRegistry.metricFamilySamples(); + List allMetricNames = new ArrayList<>(); + while (metricFamilySamplesEnumeration.hasMoreElements()) { + Collector.MetricFamilySamples familySamples = metricFamilySamplesEnumeration.nextElement(); + if (familySamples != null && familySamples.name != null) { + allMetricNames.add(familySamples.name); + } + } + return allMetricNames; + } } diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/config/disabledmetrics/MetricStatusCheckerTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/config/disabledmetrics/MetricStatusCheckerTest.java index 46ab18f2a..bc10896bb 100644 --- a/src/test/java/org/jenkinsci/plugins/prometheus/config/disabledmetrics/MetricStatusCheckerTest.java +++ b/src/test/java/org/jenkinsci/plugins/prometheus/config/disabledmetrics/MetricStatusCheckerTest.java @@ -9,6 +9,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; import static org.mockito.Mockito.*; @@ -181,6 +182,32 @@ void testNamedDisabledMetricAndRegexAvailableMatches() { } } + + @Test + void testFilterExternalMetricNames() { + Jenkins jenkins = mock(Jenkins.class); + + PrometheusConfiguration mockedConfig = mock(PrometheusConfiguration.class); + List entries = new ArrayList<>(); + entries.add(new NamedDisabledMetric("other_metric")); + entries.add(new RegexDisabledMetric("j?vm.*")); + DisabledMetricConfig disabledMetricConfig = new DisabledMetricConfig(entries); + + when(mockedConfig.getDisabledMetricConfig()).thenReturn(disabledMetricConfig); + + + try (MockedStatic jenkinsStatic = mockStatic(Jenkins.class); + MockedStatic configStatic = mockStatic(PrometheusConfiguration.class)) { + jenkinsStatic.when(Jenkins::get).thenReturn(jenkins); + configStatic.when(PrometheusConfiguration::get).thenReturn(mockedConfig); + + List allMetrics = List.of("some_metric", "jvm_xxx", "vm_xxx"); + Set filteredMetrics = MetricStatusChecker.filter(allMetrics); + Assertions.assertEquals(1, filteredMetrics.size()); + Assertions.assertEquals("some_metric", filteredMetrics.stream().findFirst().get()); + } + } + @Test // shouldn't take more than 3 seconds @Timeout(value = 3L)