-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ReconfigurableOpenTelemetry to the otel api plugin
- Loading branch information
1 parent
508a0f7
commit d6b8758
Showing
17 changed files
with
4,627 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
src/main/java/io/jenkins/plugins/opentelemetry/api/ExtendedOpenTelemetry.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package io.jenkins.plugins.opentelemetry.api; | ||
|
||
import edu.umd.cs.findbugs.annotations.NonNull; | ||
import hudson.ExtensionPoint; | ||
import io.opentelemetry.api.OpenTelemetry; | ||
import io.opentelemetry.api.incubator.events.EventLoggerBuilder; | ||
import io.opentelemetry.api.incubator.events.EventLoggerProvider; | ||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; | ||
import io.opentelemetry.sdk.resources.Resource; | ||
|
||
import java.util.Map; | ||
|
||
public interface ExtendedOpenTelemetry extends ExtensionPoint, OpenTelemetry { | ||
EventLoggerProvider getEventLoggerProvider(); | ||
EventLoggerBuilder eventLoggerBuilder(String instrumentationScopeName); | ||
ConfigProperties getConfig(); | ||
Resource getResource(); | ||
void configure(@NonNull Map<String, String> openTelemetryProperties, Resource openTelemetryResource); | ||
|
||
@Deprecated | ||
OpenTelemetry getImplementation(); | ||
} |
57 changes: 57 additions & 0 deletions
57
src/main/java/io/jenkins/plugins/opentelemetry/api/InstrumentationScope.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright The Original Author or Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.jenkins.plugins.opentelemetry.api; | ||
|
||
import javax.annotation.Nonnull; | ||
import javax.annotation.Nullable; | ||
import java.util.Objects; | ||
|
||
/** | ||
* <a href="https://opentelemetry.io/docs/concepts/instrumentation-scope/">OpenTelemetry instrumentation scope</a>, | ||
* data structured used by the {@link ReconfigurableOpenTelemetry} implementation | ||
*/ | ||
class InstrumentationScope { | ||
@Nonnull | ||
final String instrumentationScopeName; | ||
@Nullable | ||
final String schemaUrl; | ||
@Nullable | ||
final String instrumentationScopeVersion; | ||
|
||
public InstrumentationScope(String instrumentationScopeName, @Nullable String schemaUrl, @Nullable String instrumentationScopeVersion) { | ||
this.instrumentationScopeName = Objects.requireNonNull(instrumentationScopeName); | ||
this.schemaUrl = schemaUrl; | ||
this.instrumentationScopeVersion = instrumentationScopeVersion; | ||
} | ||
|
||
public InstrumentationScope(@Nonnull String instrumentationScopeName) { | ||
this.instrumentationScopeName = instrumentationScopeName; | ||
this.schemaUrl = null; | ||
this.instrumentationScopeVersion = null; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "InstrumentationScope{" + | ||
"instrumentationScopeName='" + instrumentationScopeName + '\'' + | ||
", schemaUrl='" + schemaUrl + '\'' + | ||
", instrumentationScopeVersion='" + instrumentationScopeVersion + '\'' + | ||
'}'; | ||
} | ||
|
||
@Override | ||
public boolean equals(Object o) { | ||
if (this == o) return true; | ||
if (o == null || getClass() != o.getClass()) return false; | ||
InstrumentationScope that = (InstrumentationScope) o; | ||
return Objects.equals(instrumentationScopeName, that.instrumentationScopeName) && Objects.equals(schemaUrl, that.schemaUrl) && Objects.equals(instrumentationScopeVersion, that.instrumentationScopeVersion); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(instrumentationScopeName, schemaUrl, instrumentationScopeVersion); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/main/java/io/jenkins/plugins/opentelemetry/api/OpenTelemetryLifecycleListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Copyright The Original Author or Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.jenkins.plugins.opentelemetry.api; | ||
|
||
import hudson.ExtensionPoint; | ||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; | ||
|
||
public interface OpenTelemetryLifecycleListener extends ExtensionPoint, Comparable<OpenTelemetryLifecycleListener> { | ||
|
||
default void afterConfiguration(ConfigProperties configProperties){} | ||
|
||
/** | ||
* @return the ordinal of this otel component to execute step handlers in predictable order. The smallest ordinal is handled first. | ||
*/ | ||
default int ordinal() { | ||
return 0; | ||
} | ||
|
||
@Override | ||
default int compareTo(OpenTelemetryLifecycleListener other) { | ||
if (this.ordinal() == other.ordinal()) { | ||
return this.getClass().getName().compareTo(other.getClass().getName()); | ||
} else { | ||
return Integer.compare(this.ordinal(), other.ordinal()); | ||
} | ||
} | ||
} |
100 changes: 100 additions & 0 deletions
100
src/main/java/io/jenkins/plugins/opentelemetry/api/ReconfigurableEventLoggerProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* Copyright The Original Author or Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.jenkins.plugins.opentelemetry.api; | ||
|
||
import com.google.common.annotations.VisibleForTesting; | ||
import io.opentelemetry.api.incubator.events.EventBuilder; | ||
import io.opentelemetry.api.incubator.events.EventLogger; | ||
import io.opentelemetry.api.incubator.events.EventLoggerBuilder; | ||
import io.opentelemetry.api.incubator.events.EventLoggerProvider; | ||
|
||
import java.util.Objects; | ||
import java.util.Optional; | ||
import java.util.concurrent.ConcurrentHashMap; | ||
import java.util.concurrent.ConcurrentMap; | ||
|
||
/** | ||
* <p> | ||
* A {@link EventLoggerProvider} that allows to reconfigure the {@link EventLogger}s. | ||
* </p> | ||
* <p> | ||
* We need reconfigurability because Jenkins supports changing the configuration of the OpenTelemetry params at runtime. | ||
* All instantiated eventLoggers are reconfigured when the configuration changes, when | ||
* {@link ReconfigurableEventLoggerProvider#setDelegate(EventLoggerProvider)} is invoked. | ||
* </p> | ||
*/ | ||
class ReconfigurableEventLoggerProvider implements EventLoggerProvider { | ||
|
||
private final ConcurrentMap<InstrumentationScope, ReconfigurableEventLogger> eventLoggers = new ConcurrentHashMap<>(); | ||
private EventLoggerProvider delegate = EventLoggerProvider.noop(); | ||
|
||
@Override | ||
public EventLoggerBuilder eventLoggerBuilder(String instrumentationScopeName) { | ||
return new ReconfigurableEventLoggerBuilder(delegate.eventLoggerBuilder(instrumentationScopeName), instrumentationScopeName); | ||
} | ||
|
||
@Override | ||
public EventLogger get(String instrumentationScopeName) { | ||
return eventLoggers.computeIfAbsent(new InstrumentationScope(instrumentationScopeName), key -> new ReconfigurableEventLogger(delegate.get(key.instrumentationScopeName))); | ||
} | ||
|
||
public void setDelegate(EventLoggerProvider delegateEventLoggerBuilder) { | ||
this.delegate = delegateEventLoggerBuilder; | ||
eventLoggers.forEach((key, reconfigurableEventLogger) -> { | ||
EventLoggerBuilder eventLoggerBuilder = delegateEventLoggerBuilder.eventLoggerBuilder(key.instrumentationScopeName); | ||
Optional.ofNullable(key.schemaUrl).ifPresent(eventLoggerBuilder::setSchemaUrl); | ||
Optional.ofNullable(key.instrumentationScopeVersion).ifPresent(eventLoggerBuilder::setInstrumentationVersion); | ||
reconfigurableEventLogger.delegateEventLogger = eventLoggerBuilder.build(); | ||
}); | ||
} | ||
|
||
@VisibleForTesting | ||
protected static class ReconfigurableEventLogger implements EventLogger { | ||
EventLogger delegateEventLogger; | ||
|
||
public ReconfigurableEventLogger(EventLogger delegateEventLogger) { | ||
this.delegateEventLogger = Objects.requireNonNull(delegateEventLogger); | ||
} | ||
|
||
@Override | ||
public EventBuilder builder(String eventName) { | ||
return delegateEventLogger.builder(eventName); | ||
} | ||
} | ||
|
||
@VisibleForTesting | ||
protected class ReconfigurableEventLoggerBuilder implements EventLoggerBuilder { | ||
EventLoggerBuilder delegate; | ||
String instrumentationScopeName; | ||
String schemaUrl; | ||
String instrumentationScopeVersion; | ||
|
||
public ReconfigurableEventLoggerBuilder(EventLoggerBuilder delegate, String instrumentationScopeName) { | ||
this.delegate = Objects.requireNonNull(delegate); | ||
this.instrumentationScopeName = Objects.requireNonNull(instrumentationScopeName); | ||
} | ||
|
||
@Override | ||
public EventLoggerBuilder setSchemaUrl(String schemaUrl) { | ||
delegate.setSchemaUrl(schemaUrl); | ||
this.schemaUrl = schemaUrl; | ||
return this; | ||
} | ||
|
||
@Override | ||
public EventLoggerBuilder setInstrumentationVersion(String instrumentationScopeVersion) { | ||
delegate.setInstrumentationVersion(instrumentationScopeVersion); | ||
this.instrumentationScopeVersion = instrumentationScopeVersion; | ||
return this; | ||
} | ||
|
||
@Override | ||
public EventLogger build() { | ||
InstrumentationScope key = new InstrumentationScope(instrumentationScopeName, schemaUrl, instrumentationScopeVersion); | ||
return eventLoggers.computeIfAbsent(key, k -> new ReconfigurableEventLogger(delegate.build())); | ||
} | ||
} | ||
} |
Oops, something went wrong.