Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Metrics which shows the Stage ordinal #704

Merged
merged 2 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/metrics/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
| default_jenkins_builds_last_build_tests_total | Number of total tests during the last build | gauge |
| default_jenkins_builds_last_last_build_tests_skipped | Number of skipped tests during the last build | gauge |
| default_jenkins_builds_last_build_tests_failing | Number of failing tests during the last build | gauge |
| default_jenkins_builds_last_stage_result_ordinal | Status ordinal of a stage in a pipeline (0=NOT_EXECUTED,1=ABORTED,2=SUCCESS,3=IN_PROGRESS,4=PAUSED_PENDING_INPUT,5=FAILED,6=UNSTABLE) | gauge |

Check warning

Code scanning / Markdownlint (reported by Codacy)

Expected: 80; Actual: 261 Warning documentation

Expected: 80; Actual: 261
| default_jenkins_builds_last_stage_duration_milliseconds_summary | Summary of Jenkins build times by Job and Stage in the last build | summary |
| default_jenkins_builds_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 @@ -43,6 +43,7 @@
public MetricCollector<Run<?, ?>, ? extends Collector> jobBuildStartMillis;
public MetricCollector<Run<?, ?>, ? extends Collector> jobBuildDuration;
public MetricCollector<Run<?, ?>, ? extends Collector> stageSummary;
public MetricCollector<Run<?, ?>, ? extends Collector> stageBuildResultOrdinal;
public MetricCollector<Run<?, ?>, ? extends Collector> jobBuildTestsTotal;
public MetricCollector<Run<?, ?>, ? extends Collector> jobBuildTestsSkipped;
public MetricCollector<Run<?, ?>, ? extends Collector> jobBuildTestsFailing;
Expand All @@ -65,6 +66,7 @@
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, ArrayUtils.add(labelNameArray, "stage"), buildPrefix);
this.stageBuildResultOrdinal = factory.createRunCollector(CollectorType.STAGE_BUILDRESULT_ORDINAL, 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 @@ -214,6 +216,7 @@
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.stageBuildResultOrdinal.collect(), "Adding [{}] samples from summary ({})");
addSamples(allSamples, buildMetrics.buildLogFileSizeGauge.collect(), "Adding [{}] samples from summary ({})");
}

Expand Down Expand Up @@ -264,6 +267,7 @@
buildMetrics.jobBuildDuration.calculateMetric(run, buildLabelValueArray);
// Label values are calculated within stageSummary so we pass null here.
buildMetrics.stageSummary.calculateMetric(run, buildLabelValueArray);
buildMetrics.stageBuildResultOrdinal.calculateMetric(run, buildLabelValueArray);

Check warning on line 270 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 270 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 @@ -23,6 +23,7 @@ public enum CollectorType {
FAILED_TESTS_GAUGE("build_tests_failing"),
SKIPPED_TESTS_GAUGE("last_build_tests_skipped"),
STAGE_SUMMARY("stage_duration_milliseconds_summary"),
STAGE_BUILDRESULT_ORDINAL("stage_result_ordinal"),
TOTAL_TESTS_GAUGE("build_tests_total"),
HEALTH_SCORE_GAUGE("health_score"),
NB_BUILDS_GAUGE("available_builds_count"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public class BuildCollectorFactory extends BaseCollectorFactory {
return saveBuildCollector(new SkippedTestsGauge(labelNames, namespace, subsystem, prefix));
case STAGE_SUMMARY:
return saveBuildCollector(new StageSummary(labelNames, namespace, subsystem, prefix));
case STAGE_BUILDRESULT_ORDINAL:
return saveBuildCollector(new StageBuildResultOrdinalGauge(labelNames, namespace, subsystem, prefix));
case TOTAL_TESTS_GAUGE:
return saveBuildCollector(new TotalTestsGauge(labelNames, namespace, subsystem, prefix));
case BUILD_LIKELY_STUCK_GAUGE:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package org.jenkinsci.plugins.prometheus.collectors.builds;

import com.cloudbees.workflow.rest.external.StageNodeExt;
import hudson.model.Job;
import hudson.model.Run;
import io.prometheus.client.Gauge;
import io.prometheus.client.SimpleCollector;
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;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

import static org.jenkinsci.plugins.prometheus.util.FlowNodes.getSortedStageNodes;

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

private static final Logger LOGGER = LoggerFactory.getLogger(StageBuildResultOrdinalGauge.class);

protected StageBuildResultOrdinalGauge(String[] labelNames, String namespace, String subsystem, String prefix) {
super(labelNames, namespace, subsystem, prefix);
}

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

@Override
protected String getHelpText() {
return "Build status of a Stage. 0=NOT_EXECUTED,1=ABORTED,2=SUCCESS,3=IN_PROGRESS,4=PAUSED_PENDING_INPUT,5=FAILED,6=UNSTABLE";
}

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

@Override
public void calculateMetric(Run<?, ?> run, String[] labelValues) {
if (run.isBuilding()) {
return;
}

if (!(run instanceof WorkflowRun)) {
return;
}

var workflowRun = (WorkflowRun) run;
WorkflowJob job = workflowRun.getParent();
if (workflowRun.getExecution() != null) {
processPipelineRunStages(job, workflowRun, labelValues);
}
}

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

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());
String stageName = stage.getName();

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

collector.labels(values).set(stage.getStatus().ordinal());
}

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

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 44-76 are not covered by tests
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;

import static org.jenkinsci.plugins.prometheus.util.FlowNodes.getSortedStageNodes;

public class StageSummary extends BuildsMetricCollector<Run<?, ?>, Summary> {

private static final String NOT_AVAILABLE = "NA";
private static final Logger LOGGER = LoggerFactory.getLogger(StageSummary.class);

protected StageSummary(String[] labelNames, String namespace, String subsystem, String namePrefix) {
Expand Down
Loading