Skip to content

Commit

Permalink
Add NPE checks for jobs started with scripting (#471)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikita-tkachenko-datadog authored Nov 20, 2024
1 parent 4687cf3 commit b49a77e
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -922,13 +922,21 @@ public static boolean isStageNode(FlowNode flowNode) {
* Returns enclosing stage node for the given node.
* Never returns the node itself.
*/
@SuppressFBWarnings("DCN_NULLPOINTER_EXCEPTION")
public static BlockStartNode getEnclosingStageNode(FlowNode node) {
for (BlockStartNode block : node.iterateEnclosingBlocks()) {
if (DatadogUtilities.isStageNode(block)) {
return block;
try {
for (BlockStartNode block : node.iterateEnclosingBlocks()) {
if (DatadogUtilities.isStageNode(block)) {
return block;
}
}
return null;

} catch (NullPointerException e) {
// FlowNode#iterateEnclosingBlocks may throw an NPE
severe(logger, e, "Error while looking for enclosing stage node");
return null;
}
return null;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ of this software and associated documentation files (the "Software"), to deal
import org.datadog.jenkins.plugins.datadog.traces.message.TraceSpan;
import org.datadog.jenkins.plugins.datadog.traces.write.TraceWriter;
import org.datadog.jenkins.plugins.datadog.traces.write.TraceWriterFactory;
import org.datadog.jenkins.plugins.datadog.util.SuppressFBWarnings;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;

import javax.annotation.Nonnull;
Expand Down Expand Up @@ -87,11 +88,10 @@ public void onInitialize(Run run) {
}
logger.fine("Start DatadogBuildListener#onInitialize");

// Get Datadog Client Instance
DatadogClient client = getDatadogClient();
if (client == null) {
return;
}
run.addAction(new GitCommitAction());
run.addAction(new GitRepositoryAction());
run.addAction(new TraceInfoAction());
run.addAction(new PipelineQueueInfoAction());

// Collect Build Data
BuildData buildData;
Expand Down Expand Up @@ -123,11 +123,6 @@ public void onInitialize(Run run) {
final BuildSpanAction buildSpanAction = new BuildSpanAction(buildSpanContext, upstreamBuildSpanContext);
run.addAction(buildSpanAction);

run.addAction(new GitCommitAction());
run.addAction(new GitRepositoryAction());
run.addAction(new TraceInfoAction());
run.addAction(new PipelineQueueInfoAction());

logger.fine("End DatadogBuildListener#onInitialize");
} catch (Exception e) {
DatadogUtilities.severe(logger, e, "Failed to process build initialization");
Expand Down Expand Up @@ -317,16 +312,18 @@ public void onCompleted(Run run, @Nonnull TaskListener listener) {

if (run instanceof WorkflowRun) {
RunExt extRun = getRunExtForRun((WorkflowRun) run);
long pauseDurationMillis = 0;
for (StageNodeExt stage : extRun.getStages()) {
pauseDurationMillis += stage.getPauseDurationMillis();
if (extRun != null){
long pauseDurationMillis = 0;
for (StageNodeExt stage : extRun.getStages()) {
pauseDurationMillis += stage.getPauseDurationMillis();
}
metrics.gauge("jenkins.job.pause_duration", TimeUnit.MILLISECONDS.toSeconds(pauseDurationMillis), hostname, tags);
logger.fine(String.format("[%s]: Pause Duration: %s", buildData.getJobName(), toTimeString(pauseDurationMillis)));
long buildDurationMillis = run.getDuration() - pauseDurationMillis;
metrics.gauge("jenkins.job.build_duration", TimeUnit.MILLISECONDS.toSeconds(buildDurationMillis), hostname, tags);
logger.fine(
String.format("[%s]: Build Duration (without pause): %s", buildData.getJobName(), toTimeString(buildDurationMillis)));
}
metrics.gauge("jenkins.job.pause_duration", TimeUnit.MILLISECONDS.toSeconds(pauseDurationMillis), hostname, tags);
logger.fine(String.format("[%s]: Pause Duration: %s", buildData.getJobName(), toTimeString(pauseDurationMillis)));
long buildDurationMillis = run.getDuration() - pauseDurationMillis;
metrics.gauge("jenkins.job.build_duration", TimeUnit.MILLISECONDS.toSeconds(buildDurationMillis), hostname, tags);
logger.fine(
String.format("[%s]: Build Duration (without pause): %s", buildData.getJobName(), toTimeString(buildDurationMillis)));
}

Metrics.getInstance().incrementCounter("jenkins.job.completed", hostname, tags);
Expand Down Expand Up @@ -537,12 +534,19 @@ private boolean isFailedBuild(Run<?, ?> run) {
return run != null && run.getResult() != Result.SUCCESS;
}

@SuppressFBWarnings("DCN_NULLPOINTER_EXCEPTION")
public RunExt getRunExtForRun(WorkflowRun run) {
DatadogGlobalConfiguration cfg = DatadogUtilities.getDatadogGlobalDescriptor();
if (cfg.isCacheBuildRuns()) {
return RunExt.create(run);
} else {
return RunExt.createNew(run);
try {
if (cfg.isCacheBuildRuns()) {
return RunExt.create(run);
} else {
return RunExt.createNew(run);
}
} catch (NullPointerException e) {
// RunExt#create and RunExt#createNew may throw an NPE
DatadogUtilities.severe(logger, e, "Error while getting RunExt");
return null;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,11 @@ private List<StageData> traverseStages(List<FlowNode> heads, int limit) {
Queue<FlowNode> nodes = new ArrayDeque<>(heads);
while (!nodes.isEmpty()) {
FlowNode node = nodes.poll();
nodes.addAll(node.getParents());
for (FlowNode parent : node.getParents()) {
if (parent != null){
nodes.add(parent);
}
}

if (!(node instanceof BlockEndNode)) {
continue;
Expand Down

0 comments on commit b49a77e

Please sign in to comment.