Skip to content

Commit

Permalink
Add reconfigurability of the TraceProvider, LoggerProvider, and Event…
Browse files Browse the repository at this point in the history
…LoggerProvider

Signed-off-by: Cyrille Le Clerc <cyrille.leclerc@grafana.com>
  • Loading branch information
cyrille-leclerc committed Jun 20, 2024
1 parent a702d36 commit d0c9ca4
Show file tree
Hide file tree
Showing 15 changed files with 1,234 additions and 367 deletions.
24 changes: 21 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<gitHubRepo>jenkinsci/${project.artifactId}-plugin</gitHubRepo>
<opentelemetry.version>1.39.0</opentelemetry.version>
<opentelemetry-instrumentation.version>2.5.0</opentelemetry-instrumentation.version>
<opentelemetry-semconv.version>1.25.0-alpha</opentelemetry-semconv.version>
<opentelemetry-contrib.version>1.36.0-alpha</opentelemetry-contrib.version>
<useBeta>true</useBeta>
<elasticstack.version>8.14.1</elasticstack.version>
Expand Down Expand Up @@ -93,15 +94,32 @@
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
<version>1.39.0-8.vfb_39d89a_2812</version>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api-incubator</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-context</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry.semconv</groupId>
<artifactId>opentelemetry-semconv</artifactId>
<version>${opentelemetry-semconv.version}</version>
</dependency>
<dependency>
<groupId>io.opentelemetry.semconv</groupId>
<artifactId>opentelemetry-semconv-incubating</artifactId>
<version>${opentelemetry-semconv.version}</version>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-instrumentation-api</artifactId>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.Extension;
import hudson.ExtensionList;
import io.jenkins.plugins.opentelemetry.opentelemetry.AbstractReconfigurableOpenTelemetryWrapper;
import io.jenkins.plugins.opentelemetry.opentelemetry.ReconfigurableOpenTelemetry;
import io.jenkins.plugins.opentelemetry.semconv.JenkinsOtelSemanticAttributes;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.incubator.events.EventLogger;
Expand All @@ -30,7 +30,7 @@
* {@link OpenTelemetry} instance intended to live on the Jenkins Controller.
*/
@Extension
public class JenkinsControllerOpenTelemetry extends AbstractReconfigurableOpenTelemetryWrapper implements OpenTelemetry {
public class JenkinsControllerOpenTelemetry extends ReconfigurableOpenTelemetry implements OpenTelemetry {

private static final Logger LOGGER = Logger.getLogger(JenkinsControllerOpenTelemetry.class.getName());

Expand All @@ -42,20 +42,33 @@ public class JenkinsControllerOpenTelemetry extends AbstractReconfigurableOpenTe
public final static AtomicInteger INSTANCE_COUNTER = new AtomicInteger(0);

@NonNull
private final transient ReconfigurableTracer defaultTracer = new ReconfigurableTracer();
private final transient Tracer defaultTracer;
protected transient Meter defaultMeter;
protected transient EventLogger defaultEventLogger;
protected final transient EventLogger defaultEventLogger;

public JenkinsControllerOpenTelemetry() {
super();
if (INSTANCE_COUNTER.get() > 0) {

Check warning on line 51 in src/main/java/io/jenkins/plugins/opentelemetry/JenkinsControllerOpenTelemetry.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Partially covered line

Line 51 is only partially covered, one branch is missing
LOGGER.log(Level.WARNING, "More than one instance of JenkinsControllerOpenTelemetry created: " + INSTANCE_COUNTER.get());

Check warning on line 52 in src/main/java/io/jenkins/plugins/opentelemetry/JenkinsControllerOpenTelemetry.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 52 is not covered by tests
}

String opentelemetryPluginVersion = OtelUtils.getOpentelemetryPluginVersion();

this.defaultTracer =
getTracerProvider()
.tracerBuilder(JenkinsOtelSemanticAttributes.INSTRUMENTATION_NAME)
.setInstrumentationVersion(opentelemetryPluginVersion)
.build();

this.defaultEventLogger = getEventLoggerProvider()
.eventLoggerBuilder(JenkinsOtelSemanticAttributes.INSTRUMENTATION_NAME)
.setInstrumentationVersion(opentelemetryPluginVersion)
.build();
}

@NonNull
public Tracer getDefaultTracer() {
return Preconditions.checkNotNull(defaultTracer.getDelegate());
return defaultTracer;
}

public boolean isLogsEnabled() {
Expand Down Expand Up @@ -85,7 +98,7 @@ public void shutdown() {
}

public void initialize(@NonNull OpenTelemetryConfiguration configuration) {
initialize(
configure(
configuration.toOpenTelemetryProperties(),
configuration.toOpenTelemetryResource());
}
Expand All @@ -94,19 +107,10 @@ public void initialize(@NonNull OpenTelemetryConfiguration configuration) {
protected void postOpenTelemetrySdkConfiguration() {
String opentelemetryPluginVersion = OtelUtils.getOpentelemetryPluginVersion();

this.defaultTracer.setDelegate(
getTracerProvider()
.tracerBuilder(JenkinsOtelSemanticAttributes.INSTRUMENTATION_NAME)
.setInstrumentationVersion(opentelemetryPluginVersion)
.build());
this.defaultMeter = getMeterProvider()
.meterBuilder(JenkinsOtelSemanticAttributes.INSTRUMENTATION_NAME)
.setInstrumentationVersion(opentelemetryPluginVersion)
.build();
this.defaultEventLogger = GlobalEventLoggerProvider.get()
.eventLoggerBuilder(JenkinsOtelSemanticAttributes.INSTRUMENTATION_NAME)
.setInstrumentationVersion(opentelemetryPluginVersion)
.build();

LOGGER.log(Level.FINER, () -> "Configure OpenTelemetryLifecycleListeners: " + ExtensionList.lookup(OpenTelemetryLifecycleListener.class).stream().sorted().map(e -> e.getClass().getName()).collect(Collectors.joining(", ")));
ExtensionList.lookup(OpenTelemetryLifecycleListener.class).stream()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,16 @@
import java.io.StringReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
Expand Down Expand Up @@ -178,7 +187,6 @@ protected Object readResolve() {
return this;
}


@NonNull
public OpenTelemetryConfiguration toOpenTelemetryConfiguration() {
Properties properties = new Properties();
Expand All @@ -188,7 +196,7 @@ public OpenTelemetryConfiguration toOpenTelemetryConfiguration() {
LOGGER.log(Level.WARNING, "Exception parsing configuration properties", e);
}

Map<String, String> configurationProperties = new HashMap();
Map<String, String> configurationProperties = new HashMap<>();
getObservabilityBackends().forEach(backend -> configurationProperties.putAll(backend.getOtelConfigurationProperties()));
configurationProperties.put(JenkinsOtelSemanticAttributes.JENKINS_VERSION.getKey(), OtelUtils.getJenkinsVersion());
configurationProperties.put(JenkinsOtelSemanticAttributes.JENKINS_URL.getKey(), this.jenkinsLocationConfiguration.getUrl());
Expand All @@ -200,7 +208,7 @@ public OpenTelemetryConfiguration toOpenTelemetryConfiguration() {
return new OpenTelemetryConfiguration(
Optional.ofNullable(this.getEndpoint()),
Optional.ofNullable(this.getTrustedCertificatesPem()),
Optional.ofNullable(this.getAuthentication()),
Optional.of(this.getAuthentication()),
Optional.ofNullable(this.getExporterTimeoutMillis()),
Optional.ofNullable(this.getExporterIntervalMillis()),
Optional.ofNullable(this.getServiceName()),
Expand All @@ -209,14 +217,28 @@ public OpenTelemetryConfiguration toOpenTelemetryConfiguration() {
configurationProperties);
}

/**
* Register reconfigurable {@link io.opentelemetry.api.OpenTelemetry}
* on {@link io.opentelemetry.api.GlobalOpenTelemetry}
* and {@link io.jenkins.plugins.opentelemetry.opentelemetry.ReconfigurableEventLoggerProvider}
* on {@link io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider}
* as early as possible in Jenkins lifecycle so any plugin invoking those Global setters will have the
* reconfigurable instance .
*/
@Initializer(after = InitMilestone.EXTENSIONS_AUGMENTED, before = InitMilestone.SYSTEM_CONFIG_LOADED)
public void initializeOpenTelemetryAfterExtensionsAugmented() {
LOGGER.log(Level.INFO, "Initialize Jenkins OpenTelemetry Plugin with a NoOp implementation...");
jenkinsControllerOpenTelemetry.configure(Collections.emptyMap(), Resource.empty());
}

/**
* Initialize the Otel SDK, must happen after the plugin has been configured by the standard config and by JCasC
* JCasC configuration happens during `SYSTEM_CONFIG_ADAPTED` (see `io.jenkins.plugins.casc.ConfigurationAsCode#init()`)
*/
@Initializer(after = InitMilestone.SYSTEM_CONFIG_ADAPTED, before = InitMilestone.JOB_LOADED)
@SuppressWarnings("MustBeClosedChecker")
public void initializeOpenTelemetry() {
LOGGER.log(Level.FINE, "Initialize Jenkins OpenTelemetry Plugin...");
LOGGER.log(Level.INFO, "Initialize Jenkins OpenTelemetry Plugin...");
OpenTelemetryConfiguration newOpenTelemetryConfiguration = toOpenTelemetryConfiguration();
if (Objects.equals(this.currentOpenTelemetryConfiguration, newOpenTelemetryConfiguration)) {
LOGGER.log(Level.FINE, "Configuration didn't change, skip reconfiguration");
Expand Down Expand Up @@ -559,7 +581,8 @@ public LogStorageRetriever getLogStorageRetriever() {

@NonNull
@MustBeClosed
@SuppressWarnings("MustBeClosedChecker") // false positive invoking backend.getLogStorageRetriever(templateBindingsProvider)
@SuppressWarnings("MustBeClosedChecker")
// false positive invoking backend.getLogStorageRetriever(templateBindingsProvider)
private LogStorageRetriever resolveLogStorageRetriever() {
LogStorageRetriever logStorageRetriever = null;

Expand Down

This file was deleted.

Loading

0 comments on commit d0c9ca4

Please sign in to comment.