From 2e350ec693dd9c64207789ff8752abf51ddd7e70 Mon Sep 17 00:00:00 2001 From: waschndolos Date: Wed, 25 Oct 2023 17:40:27 +0200 Subject: [PATCH] Adding metric which shows if job log is updated --- .../plugins/prometheus/JobCollector.java | 6 ++ .../prometheus/collectors/CollectorType.java | 4 +- .../collectors/jobs/JobCollectorFactory.java | 2 + .../collectors/jobs/LogUpdatedGauge.java | 38 +++++++++++++ .../jobs/BuildDiscardGaugeTest.java | 2 +- .../jobs/CurrentRunDurationGaugeTest.java | 1 - .../collectors/jobs/HealthScoreGaugeTest.java | 1 - .../collectors/jobs/JobCollectorTest.java | 3 - .../collectors/jobs/LogUpdatedGaugeTest.java | 55 +++++++++++++++++++ 9 files changed, 103 insertions(+), 9 deletions(-) create mode 100644 src/main/java/org/jenkinsci/plugins/prometheus/collectors/jobs/LogUpdatedGauge.java create mode 100644 src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/LogUpdatedGaugeTest.java diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/JobCollector.java b/src/main/java/org/jenkinsci/plugins/prometheus/JobCollector.java index a3e055816..19f11df26 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/JobCollector.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/JobCollector.java @@ -32,6 +32,7 @@ public class JobCollector extends Collector { private MetricCollector, ? extends Collector> nbBuildsGauge; private MetricCollector, ? extends Collector> buildDiscardGauge; private MetricCollector, ? extends Collector> currentRunDurationGauge; + private MetricCollector, ? extends Collector> logUpdatedGauge; private static class BuildMetrics { @@ -129,6 +130,8 @@ public List collect() { currentRunDurationGauge = factory.createJobCollector(CollectorType.CURRENT_RUN_DURATION_GAUGE, labelBaseNameArray); + logUpdatedGauge = factory.createJobCollector(CollectorType.JOB_LOG_UPDATED_GAUGE, labelBaseNameArray); + if (PrometheusConfiguration.get().isPerBuildMetrics()) { labelNameArray = Arrays.copyOf(labelNameArray, labelNameArray.length + 1); labelNameArray[labelNameArray.length - 1] = "number"; @@ -164,6 +167,7 @@ public List collect() { addSamples(samples, nbBuildsGauge.collect(), "Adding [{}] samples from gauge ({})"); addSamples(samples, buildDiscardGauge.collect(), "Adding [{}] samples from gauge ({})"); addSamples(samples, currentRunDurationGauge.collect(), "Adding [{}] samples from gauge ({})"); + addSamples(samples, logUpdatedGauge.collect(), "Adding [{}] samples from gauge ({})"); addSamples(samples, lastBuildMetrics); if (PrometheusConfiguration.get().isPerBuildMetrics()) { addSamples(samples, perBuildMetrics); @@ -217,6 +221,8 @@ protected void appendJobMetrics(Job job) { jobHealthScoreGauge.calculateMetric(job, baseLabelValueArray); buildDiscardGauge.calculateMetric(job, baseLabelValueArray); currentRunDurationGauge.calculateMetric(job, baseLabelValueArray); + logUpdatedGauge.calculateMetric(job, baseLabelValueArray); + processRun(job, lastBuild, baseLabelValueArray, lastBuildMetrics); Run run = lastBuild; diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/CollectorType.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/CollectorType.java index fd19083e3..6593c21a3 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/CollectorType.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/CollectorType.java @@ -52,9 +52,7 @@ public enum CollectorType { COVERAGE_FILE_MISSED("coverage_file_missed"), COVERAGE_FILE_TOTAL("coverage_file_total"), - - - ; + JOB_LOG_UPDATED_GAUGE("job_log_updated"); private final String name; diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/jobs/JobCollectorFactory.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/jobs/JobCollectorFactory.java index 059742785..276e354a8 100644 --- a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/jobs/JobCollectorFactory.java +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/jobs/JobCollectorFactory.java @@ -23,6 +23,8 @@ public JobCollectorFactory() { return saveBuildCollector(new BuildDiscardGauge(labelNames, namespace, subsystem)); case CURRENT_RUN_DURATION_GAUGE: return saveBuildCollector(new CurrentRunDurationGauge(labelNames, namespace, subsystem)); + case JOB_LOG_UPDATED_GAUGE: + return saveBuildCollector(new LogUpdatedGauge(labelNames, namespace, subsystem)); default: return new NoOpMetricCollector<>(); } diff --git a/src/main/java/org/jenkinsci/plugins/prometheus/collectors/jobs/LogUpdatedGauge.java b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/jobs/LogUpdatedGauge.java new file mode 100644 index 000000000..bdf0bf0ee --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/prometheus/collectors/jobs/LogUpdatedGauge.java @@ -0,0 +1,38 @@ +package org.jenkinsci.plugins.prometheus.collectors.jobs; + +import hudson.model.Job; +import io.prometheus.client.Gauge; +import io.prometheus.client.SimpleCollector; +import org.jenkinsci.plugins.prometheus.collectors.CollectorType; +import org.jenkinsci.plugins.prometheus.collectors.builds.BuildsMetricCollector; + +public class LogUpdatedGauge extends BuildsMetricCollector, Gauge> { + + protected LogUpdatedGauge(String[] labelNames, String namespace, String subsystem) { + super(labelNames, namespace, subsystem); + } + + @Override + protected CollectorType getCollectorType() { + return CollectorType.JOB_LOG_UPDATED_GAUGE; + } + + @Override + protected String getHelpText() { + return "Provides a hint if a job is still logging. Maybe not 100% accurate - but a good hint."; + } + + @Override + protected SimpleCollector.Builder getCollectorBuilder() { + return Gauge.build(); + } + + @Override + public void calculateMetric(Job jenkinsObject, String[] labelValues) { + + if (jenkinsObject != null) { + boolean logUpdated = jenkinsObject.isLogUpdated(); + this.collector.labels(labelValues).set(logUpdated ? 1.0 : 0.0); + } + } +} diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/BuildDiscardGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/BuildDiscardGaugeTest.java index 464d62abf..8f663e964 100644 --- a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/BuildDiscardGaugeTest.java +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/BuildDiscardGaugeTest.java @@ -10,7 +10,7 @@ public class BuildDiscardGaugeTest extends JobCollectorTest { - @Override + @Test void testCollectResult() { when(job.getBuildDiscarder()).thenReturn(null); diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/CurrentRunDurationGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/CurrentRunDurationGaugeTest.java index e9f066f5f..b710530c5 100644 --- a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/CurrentRunDurationGaugeTest.java +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/CurrentRunDurationGaugeTest.java @@ -19,7 +19,6 @@ public class CurrentRunDurationGaugeTest extends JobCollectorTest { @Mock Run currentRun; - @Override @Test public void testCollectResult() { when(currentRun.isBuilding()).thenReturn(true); diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/HealthScoreGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/HealthScoreGaugeTest.java index 2793a27df..8f344d065 100644 --- a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/HealthScoreGaugeTest.java +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/HealthScoreGaugeTest.java @@ -10,7 +10,6 @@ public class HealthScoreGaugeTest extends JobCollectorTest { - @Override @Test public void testCollectResult() { diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/JobCollectorTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/JobCollectorTest.java index e9f729adc..6632adf35 100644 --- a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/JobCollectorTest.java +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/JobCollectorTest.java @@ -14,7 +14,4 @@ public abstract class JobCollectorTest extends CollectorTest { protected Job job; - abstract void testCollectResult(); - - } diff --git a/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/LogUpdatedGaugeTest.java b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/LogUpdatedGaugeTest.java new file mode 100644 index 000000000..d9a2e512d --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/prometheus/collectors/jobs/LogUpdatedGaugeTest.java @@ -0,0 +1,55 @@ +package org.jenkinsci.plugins.prometheus.collectors.jobs; + +import io.prometheus.client.Collector; +import org.junit.Test; + +import java.util.List; + +import static org.mockito.Mockito.when; + +public class LogUpdatedGaugeTest extends JobCollectorTest { + + + @Test + public void testBasicAttributes() { + when(job.isLogUpdated()).thenReturn(true); + + LogUpdatedGauge sut = new LogUpdatedGauge(new String[]{"jenkins_job", "repo"}, "default", "jenkins"); + + sut.calculateMetric(job, new String[]{"job1", "NA"}); + List collect = sut.collect(); + + validateMetricFamilySampleListSize(collect, 1); + + Collector.MetricFamilySamples samples = collect.get(0); + validateNames(samples, new String[]{"default_jenkins_builds_job_log_updated"}); + validateMetricFamilySampleSize(samples, 1); + + } + + @Test + public void testLogIsUpdatedReturnsOne() { + + when(job.isLogUpdated()).thenReturn(true); + + LogUpdatedGauge sut = new LogUpdatedGauge(new String[]{"jenkins_job", "repo"}, "default", "jenkins"); + + sut.calculateMetric(job, new String[]{"job1", "NA"}); + List collect = sut.collect(); + Collector.MetricFamilySamples samples = collect.get(0); + validateValue(samples.samples.get(0), 1.0); + } + + @Test + public void testLogIsNotUpdatedReturnsZero() { + + when(job.isLogUpdated()).thenReturn(false); + + LogUpdatedGauge sut = new LogUpdatedGauge(new String[]{"jenkins_job", "repo"}, "default", "jenkins"); + + sut.calculateMetric(job, new String[]{"job1", "NA"}); + List collect = sut.collect(); + Collector.MetricFamilySamples samples = collect.get(0); + validateValue(samples.samples.get(0), 0.0); + } +} \ No newline at end of file