Skip to content

Commit

Permalink
Make it possible to get stage statistics per build (#604)
Browse files Browse the repository at this point in the history
  • Loading branch information
Waschndolos authored Dec 22, 2023
1 parent 79a7d58 commit 82146d3
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 20 deletions.
13 changes: 6 additions & 7 deletions src/main/java/org/jenkinsci/plugins/prometheus/JobCollector.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import hudson.model.Run;
import io.prometheus.client.Collector;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.jenkinsci.plugins.prometheus.collectors.CollectorFactory;
import org.jenkinsci.plugins.prometheus.collectors.CollectorType;
import org.jenkinsci.plugins.prometheus.collectors.MetricCollector;
Expand Down Expand Up @@ -53,7 +54,7 @@ public BuildMetrics(String buildPrefix) {
this.buildPrefix = buildPrefix;
}

public void initCollectors(String[] labelNameArray, String[] labelStageNameArray) {
public void initCollectors(String[] labelNameArray) {
CollectorFactory factory = new CollectorFactory();
this.jobBuildResultOrdinal = factory.createRunCollector(CollectorType.BUILD_RESULT_ORDINAL_GAUGE, labelNameArray, buildPrefix);
this.jobBuildResult = factory.createRunCollector(CollectorType.BUILD_RESULT_GAUGE, labelNameArray, buildPrefix);
Expand All @@ -62,7 +63,7 @@ public void initCollectors(String[] labelNameArray, String[] labelStageNameArray
this.jobBuildTestsTotal = factory.createRunCollector(CollectorType.TOTAL_TESTS_GAUGE, labelNameArray, buildPrefix);
this.jobBuildTestsSkipped = factory.createRunCollector(CollectorType.SKIPPED_TESTS_GAUGE, labelNameArray, buildPrefix);
this.jobBuildTestsFailing = factory.createRunCollector(CollectorType.FAILED_TESTS_GAUGE, labelNameArray, buildPrefix);
this.stageSummary = factory.createRunCollector(CollectorType.STAGE_SUMMARY, labelStageNameArray, buildPrefix);
this.stageSummary = factory.createRunCollector(CollectorType.STAGE_SUMMARY, ArrayUtils.add(labelNameArray, "stage"), buildPrefix);
this.jobBuildLikelyStuck = factory.createRunCollector(CollectorType.BUILD_LIKELY_STUCK_GAUGE, labelNameArray, buildPrefix);
}
}
Expand Down Expand Up @@ -99,8 +100,6 @@ public List<MetricFamilySamples> collect() {
labelNameArray[labelNameArray.length - 1] = buildParam.trim();
}

String[] labelStageNameArray = Arrays.copyOf(labelBaseNameArray, labelBaseNameArray.length + 1);
labelStageNameArray[labelBaseNameArray.length] = "stage";

boolean processDisabledJobs = PrometheusConfiguration.get().isProcessingDisabledBuilds();
boolean ignoreBuildMetrics =
Expand Down Expand Up @@ -138,11 +137,11 @@ public List<MetricFamilySamples> collect() {
if (PrometheusConfiguration.get().isPerBuildMetrics()) {
labelNameArray = Arrays.copyOf(labelNameArray, labelNameArray.length + 1);
labelNameArray[labelNameArray.length - 1] = "number";
perBuildMetrics.initCollectors(labelNameArray, labelStageNameArray);
perBuildMetrics.initCollectors(labelNameArray);

Check warning on line 140 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 140 is not covered by tests
}

// The lastBuildMetrics are initialized with the "base" labels
lastBuildMetrics.initCollectors(labelBaseNameArray, labelStageNameArray);
lastBuildMetrics.initCollectors(labelBaseNameArray);


Jobs.forEachJob(job -> {
Expand Down Expand Up @@ -284,7 +283,7 @@ private void processRun(Job<?, ?> job, Run<?, ?> run, String[] buildLabelValueAr
buildMetrics.jobBuildStartMillis.calculateMetric(run, buildLabelValueArray);
buildMetrics.jobBuildDuration.calculateMetric(run, buildLabelValueArray);
// Label values are calculated within stageSummary so we pass null here.
buildMetrics.stageSummary.calculateMetric(run, new String[]{});
buildMetrics.stageSummary.calculateMetric(run, buildLabelValueArray);

Check warning on line 286 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 286 is not covered by tests
buildMetrics.jobBuildTestsTotal.calculateMetric(run, buildLabelValueArray);
buildMetrics.jobBuildTestsSkipped.calculateMetric(run, buildLabelValueArray);
buildMetrics.jobBuildTestsFailing.calculateMetric(run, buildLabelValueArray);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import hudson.model.Run;
import io.prometheus.client.SimpleCollector;
import io.prometheus.client.Summary;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.jenkinsci.plugins.prometheus.collectors.CollectorType;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
Expand Down Expand Up @@ -54,37 +54,33 @@ public void calculateMetric(Run<?, ?> jenkinsObject, String[] labelValues) {
var workflowRun = (WorkflowRun) jenkinsObject;
WorkflowJob job = workflowRun.getParent();
if (workflowRun.getExecution() != null) {
processPipelineRunStages(job, jenkinsObject, workflowRun);
processPipelineRunStages(job, workflowRun, labelValues);
}

}

private void processPipelineRunStages(Job job, Run latestfinishedRun, WorkflowRun workflowRun) {
private void processPipelineRunStages(Job job, WorkflowRun workflowRun, String[] labelValues) {
List<StageNodeExt> stages = getSortedStageNodes(workflowRun);
for (StageNodeExt stage : stages) {
if (stage != null) {
observeStage(job, latestfinishedRun, stage);
observeStage(job, workflowRun, stage, labelValues);
}
}
}


private void observeStage(Job job, Run run, StageNodeExt stage) {
private void observeStage(Job job, Run run, StageNodeExt stage, String[] labelValues) {

LOGGER.debug("Observing stage[{}] in run [{}] from job [{}]", stage.getName(), run.getNumber(), job.getName());
// Add this to the repo as well so I can group by Github Repository
String repoName = StringUtils.substringBetween(job.getFullName(), "/");
if (repoName == null) {
repoName = NOT_AVAILABLE;
}
String jobName = job.getFullName();
String stageName = stage.getName();
String[] labelValueArray = {jobName, repoName, String.valueOf(job.isBuildable()), stageName};

String[] values = ArrayUtils.add(labelValues, stageName);

if (stage.getStatus() == StatusExt.SUCCESS || stage.getStatus() == StatusExt.UNSTABLE) {
LOGGER.debug("getting duration for stage[{}] in run [{}] from job [{}]", stage.getName(), run.getNumber(), job.getName());
long duration = stage.getDurationMillis();
LOGGER.debug("duration was [{}] for stage[{}] in run [{}] from job [{}]", duration, stage.getName(), run.getNumber(), job.getName());
collector.labels(labelValueArray).observe(duration);
collector.labels(values).observe(duration);

Check warning on line 83 in src/main/java/org/jenkinsci/plugins/prometheus/collectors/builds/StageSummary.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 57-83 are not covered by tests
} else {
LOGGER.debug("Stage[{}] in run [{}] from job [{}] was not successful and will be ignored", stage.getName(), run.getNumber(), job.getName());
}
Expand Down

0 comments on commit 82146d3

Please sign in to comment.