Skip to content

Commit

Permalink
New metrics which shows the build log size in bytes (#668)
Browse files Browse the repository at this point in the history
* Removing System.out.println

* Creating new Gauge which shows the buildlog size in bytes

* Fixing codacy issues
  • Loading branch information
Waschndolos authored May 21, 2024
1 parent 304ce25 commit d7d9acf
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 3 deletions.
1 change: 1 addition & 0 deletions docs/metrics/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ will just return the last build. You can enable per build metrics in the configu
| default_jenkins_builds_available_builds_count | Gauge which indicates how many builds are available for the given job | gauge |
| default_jenkins_builds_discard_active | Gauge which indicates if the build discard feature is active for the job. | gauge |
| default_jenkins_builds_running_build_duration_milliseconds | Gauge which indicates the runtime of the current build. | gauge |
| default_jenkins_builds_<buildname>_last_logfile_size_bytes | Gauge which shows the log file size in bytes. | gauge |



Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ private static class BuildMetrics {
public MetricCollector<Run<?, ?>, ? extends Collector> jobBuildTestsTotal;
public MetricCollector<Run<?, ?>, ? extends Collector> jobBuildTestsSkipped;
public MetricCollector<Run<?, ?>, ? extends Collector> jobBuildTestsFailing;

public MetricCollector<Run<?,?>, ? extends Collector> jobBuildLikelyStuck;
private MetricCollector<Run<?, ?>, ? extends Collector> buildLogFileSizeGauge;

private final String buildPrefix;

Expand All @@ -65,6 +65,7 @@ public void initCollectors(String[] labelNameArray) {
this.jobBuildTestsFailing = factory.createRunCollector(CollectorType.FAILED_TESTS_GAUGE, labelNameArray, buildPrefix);
this.stageSummary = factory.createRunCollector(CollectorType.STAGE_SUMMARY, ArrayUtils.add(labelNameArray, "stage"), buildPrefix);
this.jobBuildLikelyStuck = factory.createRunCollector(CollectorType.BUILD_LIKELY_STUCK_GAUGE, labelNameArray, buildPrefix);
this.buildLogFileSizeGauge = factory.createRunCollector(CollectorType.BUILD_LOGFILE_SIZE_GAUGE, labelNameArray, buildPrefix);
}
}

Expand Down Expand Up @@ -97,6 +98,7 @@ public List<MetricFamilySamples> collect() {
// of "parameters" or "status"
summary = factory.createRunCollector(CollectorType.BUILD_DURATION_SUMMARY, labelNameArray, null);


// Counter manager acts as a DB to retrieve any counters that are already in memory instead of reinitializing
// them with each iteration of collect.
var manager = CounterManager.getManager();
Expand Down Expand Up @@ -207,6 +209,7 @@ private void addSamples(List<MetricFamilySamples> allSamples, BuildMetrics build
addSamples(allSamples, buildMetrics.jobBuildTestsFailing.collect(), "Adding [{}] samples from gauge ({})");
addSamples(allSamples, buildMetrics.jobBuildLikelyStuck.collect(), "Adding [{}] samples from gauge ({})");
addSamples(allSamples, buildMetrics.stageSummary.collect(), "Adding [{}] samples from summary ({})");
addSamples(allSamples, buildMetrics.buildLogFileSizeGauge.collect(), "Adding [{}] samples from summary ({})");
}

protected void appendJobMetrics(Job<?, ?> job) {
Expand Down Expand Up @@ -236,6 +239,7 @@ protected void appendJobMetrics(Job<?, ?> job) {
String[] labelValueArray = JobLabel.getJobLabelValues(job, run);

summary.calculateMetric(run, labelValueArray);

if (isPerBuildMetrics) {
labelValueArray = Arrays.copyOf(labelValueArray, labelValueArray.length + 1);
labelValueArray[labelValueArray.length - 1] = String.valueOf(run.getNumber());
Expand All @@ -259,6 +263,7 @@ private void processRun(Job<?, ?> job, Run<?, ?> run, String[] buildLabelValueAr
buildMetrics.jobBuildTestsSkipped.calculateMetric(run, buildLabelValueArray);
buildMetrics.jobBuildTestsFailing.calculateMetric(run, buildLabelValueArray);
buildMetrics.jobBuildLikelyStuck.calculateMetric(run,buildLabelValueArray);
buildMetrics.buildLogFileSizeGauge.calculateMetric(run, buildLabelValueArray);

Check warning on line 266 in src/main/java/org/jenkinsci/plugins/prometheus/JobCollector.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 266 is not covered by tests
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ public enum CollectorType {
JENKINS_VERSION_INFO_GAUGE("version"),
NODES_ONLINE_GAUGE("nodes_online"),
BUILD_DURATION_GAUGE("build_duration_milliseconds"),
BUILD_LOGFILE_SIZE_GAUGE("build_logfile_size_bytes"),
BUILD_DURATION_SUMMARY("duration_milliseconds_summary"),
BUILD_RESULT_GAUGE("build_result"),
BUILD_RESULT_ORDINAL_GAUGE("build_result_ordinal"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,12 @@ public class BuildCollectorFactory extends BaseCollectorFactory {
return saveBuildCollector(new BuildLikelyStuckGauge(labelNames, namespace, subsystem, prefix));
case BUILD_ABORTED_COUNTER:
return saveBuildCollector(new BuildAbortedCounter(labelNames, namespace, subsystem, prefix));
case BUILD_UNSTABLE_COUNTER:
case BUILD_UNSTABLE_COUNTER:
return saveBuildCollector(new BuildUnstableCounter(labelNames, namespace, subsystem, prefix));
case BUILD_TOTAL_COUNTER:
return saveBuildCollector(new BuildTotalCounter(labelNames, namespace, subsystem, prefix));
case BUILD_LOGFILE_SIZE_GAUGE:
return saveBuildCollector(new BuildLogFileSizeGauge(labelNames, namespace, subsystem, prefix));
default:
return new NoOpMetricCollector<>();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.jenkinsci.plugins.prometheus.collectors.builds;

import hudson.console.AnnotatedLargeText;
import hudson.model.Run;
import io.prometheus.client.Gauge;
import io.prometheus.client.SimpleCollector;
import org.jenkinsci.plugins.prometheus.collectors.CollectorType;

public class BuildLogFileSizeGauge extends BuildsMetricCollector<Run<?, ?>, Gauge> {

protected BuildLogFileSizeGauge(String[] labelNames, String namespace, String subsystem, String namePrefix) {
super(labelNames, namespace, subsystem, namePrefix);
}

@Override
protected CollectorType getCollectorType() {
return CollectorType.BUILD_LOGFILE_SIZE_GAUGE;
}

@Override
protected String getHelpText() {
return "Build logfile size in bytes";
}

@Override
protected SimpleCollector.Builder<?, Gauge> getCollectorBuilder() {
return Gauge.build();
}

@Override
public void calculateMetric(Run<?, ?> jenkinsObject, String[] labelValues) {
if (!jenkinsObject.isBuilding()) {
AnnotatedLargeText logText = jenkinsObject.getLogText();
long logFileSize = logText.length();

collector.labels(labelValues).set(logFileSize);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ public void testCollectResult() {

Assertions.assertEquals(1, collect.size());

System.out.println(collect.get(0).samples);
Assertions.assertEquals(3, collect.get(0).samples.size(), "Would expect one result");

for (Collector.MetricFamilySamples.Sample sample : collect.get(0).samples) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package org.jenkinsci.plugins.prometheus.collectors.builds;

import hudson.console.AnnotatedLargeText;
import io.prometheus.client.Collector;
import org.jenkinsci.plugins.prometheus.collectors.testutils.MockedRunCollectorTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class BuildLogFileSizeGaugeTest extends MockedRunCollectorTest {

@Test
public void testNothingCalculatedWhenRunIsBuilding() {

when(mock.isBuilding()).thenReturn(true);

BuildLogFileSizeGauge sut = new BuildLogFileSizeGauge(getLabelNames(), getNamespace(), getSubSystem(), "default");

sut.calculateMetric(mock, getLabelValues());

List<Collector.MetricFamilySamples> collect = sut.collect();

assertEquals(1, collect.size());
assertEquals(0, collect.get(0).samples.size(), "Would expect no sample created when run is running");
}

@Test
public void testCollectResult() {

when(mock.isBuilding()).thenReturn(false);
AnnotatedLargeText annotatedLargeText = Mockito.mock(AnnotatedLargeText.class);
when(annotatedLargeText.length()).thenReturn(3000L);

when(mock.getLogText()).thenReturn(annotatedLargeText);

BuildLogFileSizeGauge sut = new BuildLogFileSizeGauge(getLabelNames(), getNamespace(), getSubSystem(), "default");

sut.calculateMetric(mock, getLabelValues());

List<Collector.MetricFamilySamples> collect = sut.collect();

assertEquals(1, collect.size());
assertEquals(3000.0, collect.get(0).samples.get(0).value);

}
}

0 comments on commit d7d9acf

Please sign in to comment.