diff --git a/src/main/java/io/jenkins/plugins/opentelemetry/api/ExtendedOpenTelemetry.java b/src/main/java/io/jenkins/plugins/opentelemetry/api/ExtendedOpenTelemetry.java index 9b0f1c8..295ae9e 100644 --- a/src/main/java/io/jenkins/plugins/opentelemetry/api/ExtendedOpenTelemetry.java +++ b/src/main/java/io/jenkins/plugins/opentelemetry/api/ExtendedOpenTelemetry.java @@ -15,7 +15,14 @@ public interface ExtendedOpenTelemetry extends ExtensionPoint, OpenTelemetry { EventLoggerBuilder eventLoggerBuilder(String instrumentationScopeName); ConfigProperties getConfig(); Resource getResource(); + + /** + * + * @deprecated use {@link #configure(Map, Resource, boolean)} + */ + @Deprecated void configure(@NonNull Map openTelemetryProperties, Resource openTelemetryResource); + default void configure(@NonNull Map openTelemetryProperties, Resource openTelemetryResource, boolean disableShutdownHook){} @Deprecated OpenTelemetry getImplementation(); diff --git a/src/main/java/io/jenkins/plugins/opentelemetry/api/ReconfigurableOpenTelemetry.java b/src/main/java/io/jenkins/plugins/opentelemetry/api/ReconfigurableOpenTelemetry.java index 8c1ac10..443f9e9 100644 --- a/src/main/java/io/jenkins/plugins/opentelemetry/api/ReconfigurableOpenTelemetry.java +++ b/src/main/java/io/jenkins/plugins/opentelemetry/api/ReconfigurableOpenTelemetry.java @@ -28,6 +28,7 @@ import io.opentelemetry.context.propagation.ContextPropagators; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; @@ -61,6 +62,7 @@ public class ReconfigurableOpenTelemetry implements ExtendedOpenTelemetry, OpenT Resource resource = Resource.empty(); ConfigProperties config = ConfigPropertiesUtils.emptyConfig(); OpenTelemetry openTelemetryImpl = OpenTelemetry.noop(); + Thread shutdownHook; final ReconfigurableMeterProvider meterProviderImpl = new ReconfigurableMeterProvider(); final ReconfigurableTracerProvider traceProviderImpl = new ReconfigurableTracerProvider(); final ReconfigurableLoggerProvider loggerProviderImpl = new ReconfigurableLoggerProvider(); @@ -81,17 +83,27 @@ public ReconfigurableOpenTelemetry() { logger.log(Level.WARNING, "GlobalEventLoggerProvider already set", e); } - logger.log(Level.FINE, () -> "Initialize " + + logger.log(Level.FINE, () -> "Configure " + "GlobalOpenTelemetry with instance " + Optional.of(GlobalOpenTelemetry.get()).map(ot -> ot + "@" + System.identityHashCode(ot)) + "and " + "GlobalEventLoggerProvide with instance " + Optional.of(GlobalEventLoggerProvider.get()).map(elp -> elp + "@" + System.identityHashCode(elp))); } @Initializer(after = InitMilestone.EXTENSIONS_AUGMENTED, before = InitMilestone.SYSTEM_CONFIG_LOADED) public void init() { - logger.log(Level.INFO, "OpenTelemetry initialized as NoOp"); + logger.log(Level.INFO, "OpenTelemetry configured as NoOp"); } + /** + * Configure the OpenTelemetry SDK with the given properties and resource disabling the OTel SDK shutdown hook + */ + @Deprecated + @Override public void configure(@NonNull Map openTelemetryProperties, Resource openTelemetryResource) { + configure(openTelemetryProperties, openTelemetryResource, true); + } + + @Override + public void configure(@NonNull Map openTelemetryProperties, Resource openTelemetryResource, boolean disableShutdownHook) { if (openTelemetryProperties.containsKey("otel.exporter.otlp.endpoint") || openTelemetryProperties.containsKey("otel.traces.exporter") || @@ -119,13 +131,26 @@ public void configure(@NonNull Map openTelemetryProperties, Reso return this.resource; } ) - // disable shutdown hook, SDK closed by #close() .disableShutdownHook() .build() .getOpenTelemetrySdk(); - setOpenTelemetryImpl(openTelemetrySdk); + if (disableShutdownHook) { + if (shutdownHook == null) { + // nothing to do, no shutdownhook registered + } else { + Runtime.getRuntime().removeShutdownHook(shutdownHook); + } + } else { + if (shutdownHook == null) { + shutdownHook = new Thread(this::close); + Runtime.getRuntime().addShutdownHook(shutdownHook); + } else { + // nothing to do, shutdown hook already registered + } + } + logger.log(Level.INFO, () -> "OpenTelemetry initialized: " + ConfigPropertiesUtils.prettyPrintOtelSdkConfig(this.config, this.resource)); } else { // NO-OP @@ -251,4 +276,18 @@ protected void postOpenTelemetrySdkConfiguration() { openTelemetryLifecycleListener.afterConfiguration(this.config); }); } + + static class ShutdownHook extends Thread { + final OpenTelemetrySdk openTelemetrySdk; + + public ShutdownHook(OpenTelemetrySdk openTelemetrySdk) { + super("OpenTelemetry SDK Shutdown Hook"); + this.openTelemetrySdk = openTelemetrySdk; + } + + @Override + public void run() { + openTelemetrySdk.close(); + } + } }