Skip to content

Commit

Permalink
Merge pull request #881 from kuisathaverat/fix/866
Browse files Browse the repository at this point in the history
fix: Fix No MonitoringAction found when open build log
  • Loading branch information
kuisathaverat authored Jul 2, 2024
2 parents 202ffaa + 399159c commit 35d71e4
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 38 deletions.
67 changes: 45 additions & 22 deletions src/main/java/io/jenkins/plugins/opentelemetry/OtelUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,42 @@

package io.jenkins.plugins.opentelemetry;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.codec.net.URLCodec;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.workflow.graph.FlowNode;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject;

import com.google.common.collect.Iterators;

import edu.umd.cs.findbugs.annotations.CheckForNull;
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import hudson.Plugin;
import hudson.model.FreeStyleBuild;
import hudson.model.Run;
import hudson.util.VersionNumber;
import io.jenkins.plugins.opentelemetry.job.MonitoringAction;
import io.jenkins.plugins.opentelemetry.semconv.JenkinsOtelSemanticAttributes;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.trace.Span;
Expand All @@ -30,28 +58,6 @@
import jenkins.scm.api.SCMHead;
import jenkins.scm.api.mixin.ChangeRequestSCMHead;
import jenkins.scm.api.mixin.TagSCMHead;
import org.apache.commons.codec.net.URLCodec;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.workflow.graph.FlowNode;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.stream.Collectors;

public class OtelUtils {

Expand All @@ -66,6 +72,8 @@ public class OtelUtils {
public static final String TAG = "tag";
public static final String JENKINS_CORE = "jenkins-core";
public static final String UNKNOWN_VALUE = "#unknown";
private static final Logger logger = Logger.getLogger(OtelUtils.class.getName());


@CheckForNull
public static String getSystemPropertyOrEnvironmentVariable(String environmentVariableName) {
Expand Down Expand Up @@ -321,4 +329,19 @@ public String get(@javax.annotation.Nullable HttpServletRequest request, @NonNul
.orElse(null);
}
}

/**
* Check if the run has Opentelemetry data
* To validate it search for the MonitoringAction in the build actions.
* @param run the Build
* @return true if the run has Opentelemetry data
*/
public static boolean hasOpentelemetryData(Run<?, ?> run){
MonitoringAction monitoringAction = run.getAction(MonitoringAction.class);
boolean ret = monitoringAction != null;

Check warning on line 341 in src/main/java/io/jenkins/plugins/opentelemetry/OtelUtils.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 341 is only partially covered, one branch is missing
if (!ret) {

Check warning on line 342 in src/main/java/io/jenkins/plugins/opentelemetry/OtelUtils.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 342 is only partially covered, one branch is missing
logger.log(Level.FINE, () -> "No MonitoringAction found in " + run);

Check warning on line 343 in src/main/java/io/jenkins/plugins/opentelemetry/OtelUtils.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 343 is not covered by tests
}
return ret;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import hudson.Extension;
import hudson.model.Run;
import io.jenkins.plugins.opentelemetry.JenkinsOpenTelemetryPluginConfiguration;
import io.jenkins.plugins.opentelemetry.OtelUtils;
import io.jenkins.plugins.opentelemetry.semconv.JenkinsOtelSemanticAttributes;
import io.jenkins.plugins.opentelemetry.semconv.OTelEnvironmentVariablesConventions;
import io.opentelemetry.api.baggage.Baggage;
Expand Down Expand Up @@ -50,10 +51,8 @@ public void addEnvironmentVariables(@NonNull Run run, @NonNull EnvVars envs, @No
TextMapSetter<EnvVars> setter = (carrier, key, value) -> carrier.put(key.toUpperCase(), value);
W3CBaggagePropagator.getInstance().inject(Context.current(), envs, setter);
}
MonitoringAction monitoringAction = run.getAction(MonitoringAction.class);
if (monitoringAction == null) {
LOGGER.log(Level.FINE, () -> "MonitoringAction NOT found on run " + run);
} else {
if (OtelUtils.hasOpentelemetryData(run)) {

Check warning on line 54 in src/main/java/io/jenkins/plugins/opentelemetry/job/OtelEnvironmentContributorService.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 54 is only partially covered, one branch is missing
MonitoringAction monitoringAction = run.getAction(MonitoringAction.class);
// Add visualization link as environment variables to provide visualization links in notifications (to GitHub, slack messages...)
for (MonitoringAction.ObservabilityBackendLink link : monitoringAction.getLinks()) {
// Default backend link got an empty environment variable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import hudson.model.Run;
import io.jenkins.plugins.opentelemetry.JenkinsControllerOpenTelemetry;
import io.jenkins.plugins.opentelemetry.OpenTelemetryLifecycleListener;
import io.jenkins.plugins.opentelemetry.OtelUtils;
import io.jenkins.plugins.opentelemetry.job.MonitoringAction;
import io.jenkins.plugins.opentelemetry.job.OtelTraceService;
import io.opentelemetry.api.incubator.events.EventLogger;
import io.opentelemetry.api.logs.LoggerProvider;
Expand Down Expand Up @@ -54,30 +56,46 @@ static OtelLogStorageFactory get() {
return ExtensionList.lookupSingleton(OtelLogStorageFactory.class);
}

/**
* Create a LogStorage for a given FlowExecutionOwner
* @param owner the FlowExecutionOwner
* @return the LogStorage, null if no Opentelemetry data is found, or a BrokenLogStorage if an error occurs.
*/
@Nullable
@Override
public LogStorage forBuild(@NonNull final FlowExecutionOwner owner) {
LogStorage ret = null;
if (!getJenkinsControllerOpenTelemetry().isLogsEnabled()) {
logger.log(Level.FINE, () -> "OTel Logs disabled");
return null;
return ret;
}

try {
Queue.Executable exec = owner.getExecutable();
if (exec instanceof Run) {
Run<?, ?> run = (Run<?, ?>) exec;

logger.log(Level.FINEST, () -> "forBuild(" + run + ")");

return new OtelLogStorage(run, getOtelTraceService(), tracer);
} else {
return null;
}
ret = forExec(exec);
} catch (IOException x) {
return new BrokenLogStorage(x);
ret = new BrokenLogStorage(x);

Check warning on line 76 in src/main/java/io/jenkins/plugins/opentelemetry/job/log/OtelLogStorageFactory.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered lines

Lines 75-76 are not covered by tests
}
return ret;
}

/**
* Create a LogStorage for a given Queve Executable
* @param exec the Queue Executable
* @return the LogStorage or null if no Opentelemetry data is found
*/
@Nullable
private LogStorage forExec(@NonNull Queue.Executable exec){
LogStorage ret = null;
if (exec instanceof Run) {
Run<?, ?> run = (Run<?, ?>) exec;
if(OtelUtils.hasOpentelemetryData(run)){

Check warning on line 91 in src/main/java/io/jenkins/plugins/opentelemetry/job/log/OtelLogStorageFactory.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 91 is only partially covered, one branch is missing
logger.log(Level.FINEST, () -> "forExec(" + run + ")");
ret = new OtelLogStorage(run, getOtelTraceService(), tracer);
}
}
return ret;
}

/**
* Workaround dependency injection problem. @Inject doesn't work here
*/
Expand Down

0 comments on commit 35d71e4

Please sign in to comment.