Skip to content

Disabling opentelemetry at runtime with quarkus.otel.sdk.disabled crashes when opentelemetry metrics are also enabled #50041

@Captn-Red-Beard

Description

@Captn-Red-Beard

Describe the bug

I'm using OpenTelemetry on a project and I have "quarkus.otel.metrics.enabled" set to true in the application properties to use the OpenTelemetry metrics. I'm looking for a way to disable OpenTelemetry across the board at runtime, but when I use "quarkus.otel.sdk.disabled=true" quarkus fails to start and the app crashes.

When I remove/disable the metrics setting from the application properties, it runs fine with the sdk disabled.

Here are some of the logs I'm seeing that may be relevant:

io.opentelemetry.api.GlobalOpenTelemetry maybeAutoConfigureAndSetGlobal
INFO: AutoConfiguredOpenTelemetrySdk found on classpath but automatic configuration is disabled. To enable, run your JVM with -Dotel.java.global-autoconfigure.enabled=true

io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder build
INFO: Error encountered during autoconfiguration. Closing partially configured components.

And here is the (cleaned) stack trace:

Caused by: jakarta.enterprise.inject.CreationException: Error creating synthetic bean [Le6zQbzkojAYO_OiKIQWJf4lGa4]: io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException: Unexpected configuration error
        at io.opentelemetry.api.OpenTelemetry_Le6zQbzkojAYO_OiKIQWJf4lGa4_Synthetic_Bean.doCreate(Unknown Source)
        at io.opentelemetry.api.OpenTelemetry_Le6zQbzkojAYO_OiKIQWJf4lGa4_Synthetic_Bean.create(Unknown Source)
        at io.opentelemetry.api.OpenTelemetry_Le6zQbzkojAYO_OiKIQWJf4lGa4_Synthetic_Bean.create(Unknown Source)
        at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:119)
        at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:38)
        at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:35)
        at io.quarkus.arc.impl.LazyValue.get(LazyValue.java:32)
        at io.quarkus.arc.impl.ComputingCache.computeIfAbsent(ComputingCache.java:69)
        at io.quarkus.arc.impl.ComputingCacheContextInstances.computeIfAbsent(ComputingCacheContextInstances.java:19)
        at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:35)
        at io.opentelemetry.api.OpenTelemetry_Le6zQbzkojAYO_OiKIQWJf4lGa4_Synthetic_Bean.get(Unknown Source)
        at io.opentelemetry.api.OpenTelemetry_Le6zQbzkojAYO_OiKIQWJf4lGa4_Synthetic_Bean.get(Unknown Source)
        at io.quarkus.opentelemetry.runtime.metrics.instrumentation.JvmMetricsService_Bean.doCreate(Unknown Source)
        at io.quarkus.opentelemetry.runtime.metrics.instrumentation.JvmMetricsService_Bean.create(Unknown Source)
        at io.quarkus.opentelemetry.runtime.metrics.instrumentation.JvmMetricsService_Bean.create(Unknown Source)
        at io.quarkus.arc.impl.AbstractSharedContext.createInstanceHandle(AbstractSharedContext.java:119)
        at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:38)
        at io.quarkus.arc.impl.AbstractSharedContext$1.get(AbstractSharedContext.java:35)
        at io.quarkus.arc.generator.Default_jakarta_enterprise_context_ApplicationScoped_ContextInstances.c10(Unknown Source)
        at io.quarkus.arc.generator.Default_jakarta_enterprise_context_ApplicationScoped_ContextInstances.computeIfAbsent(Unknown Source)
        at io.quarkus.arc.impl.AbstractSharedContext.get(AbstractSharedContext.java:35)
        at io.quarkus.arc.impl.ClientProxies.getApplicationScopedDelegate(ClientProxies.java:23)
        at io.quarkus.opentelemetry.runtime.metrics.instrumentation.JvmMetricsService_ClientProxy.arc$delegate(Unknown Source)
        at io.quarkus.opentelemetry.runtime.metrics.instrumentation.JvmMetricsService_ClientProxy.arc_contextualInstance(Unknown Source)
        at io.quarkus.opentelemetry.runtime.metrics.instrumentation.JvmMetricsService_Observer_Synthetic_vd_bkAR2o0UcQjUjxrxCSro3tS0.notify(Unknown Source)
        at io.quarkus.arc.impl.EventImpl$Notifier.notifyObservers(EventImpl.java:365)
        at io.quarkus.arc.impl.EventImpl$Notifier.notify(EventImpl.java:347)
        at io.quarkus.arc.impl.EventImpl.fire(EventImpl.java:81)
        at io.quarkus.arc.runtime.ArcRecorder.fireLifecycleEvent(ArcRecorder.java:163)
        at io.quarkus.arc.runtime.ArcRecorder.handleLifecycleEvents(ArcRecorder.java:114)
        at io.quarkus.runner.recorded.LifecycleEventsBuildStep$startupEvent1144526294.deploy_0(Unknown Source)
        at io.quarkus.runner.recorded.LifecycleEventsBuildStep$startupEvent1144526294.deploy(Unknown Source)
        ... 6 more
Caused by: io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException: Unexpected configuration error
        at io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder.build(AutoConfiguredOpenTelemetrySdkBuilder.java:527)
        at io.quarkus.opentelemetry.runtime.OpenTelemetryRecorder$1.apply(OpenTelemetryRecorder.java:74)
        at io.quarkus.opentelemetry.runtime.OpenTelemetryRecorder$1.apply(OpenTelemetryRecorder.java:60)
        at io.opentelemetry.api.OpenTelemetry_Le6zQbzkojAYO_OiKIQWJf4lGa4_Synthetic_Bean.createSynthetic(Unknown Source)
        ... 38 more
Caused by: java.lang.IllegalStateException: GlobalOpenTelemetry.set has already been called. GlobalOpenTelemetry.set must be called only once before any calls to GlobalOpenTelemetry.get. If you are using the OpenTelemetrySdk, use OpenTelemetrySdkBuilder.buildAndRegisterGlobal instead. Previous invocation set to cause of this exception.
        at io.opentelemetry.api.GlobalOpenTelemetry.set(GlobalOpenTelemetry.java:107)
        at io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder.maybeSetAsGlobal(AutoConfiguredOpenTelemetrySdkBuilder.java:594)
        at io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder.build(AutoConfiguredOpenTelemetrySdkBuilder.java:508)
        ... 41 more
Caused by: java.lang.Throwable
        at io.opentelemetry.api.GlobalOpenTelemetry.set(GlobalOpenTelemetry.java:115)
        at io.opentelemetry.api.GlobalOpenTelemetry.get(GlobalOpenTelemetry.java:85)
	...
        at io.quarkus.scheduler.common.runtime.DefaultInvoker.invoke(DefaultInvoker.java:25)
        at io.quarkus.scheduler.common.runtime.DelegateInvoker.invokeDelegate(DelegateInvoker.java:29)
        at io.quarkus.scheduler.common.runtime.StatusEmitterInvoker.invoke(StatusEmitterInvoker.java:35)
        at io.quarkus.scheduler.common.runtime.DelegateInvoker.invokeDelegate(DelegateInvoker.java:29)
        at io.quarkus.scheduler.common.runtime.DelegateInvoker.invokeComplete(DelegateInvoker.java:36)
        at io.quarkus.scheduler.common.runtime.OffloadingInvoker$2.call(OffloadingInvoker.java:54)
        at io.quarkus.scheduler.common.runtime.OffloadingInvoker$2.call(OffloadingInvoker.java:51)
        at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$4(ContextImpl.java:192)
        at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:270)
        at io.vertx.core.impl.ContextImpl$1.execute(ContextImpl.java:221)
        at io.vertx.core.impl.WorkerTask.run(WorkerTask.java:56)
        at io.quarkus.vertx.core.runtime.VertxCoreRecorder$15.runWith(VertxCoreRecorder.java:643)
        at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2675)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2654)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1591)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:1583)

Expected behavior

Disabling OpenTelemetry at runtime with "quarkus.otel.sdk.disabled=true", even with the metrics enabled, would ideally be successful in completely disabling all OpenTelemetry instrumentation, automatic and manual.

Actual behavior

When OpenTelemetry is disabled at runtime with OpenTelemetry metrics simultaneously enabled, Quarkus fails to start.

How to Reproduce?

Steps to reproduce:

  1. In a maven project using the Quarkus OpenTelemetry extension, enable metrics in the application properties with "quarkus.otel.metrics.enabled"
  2. Disable OpenTelemetry with "quarkus.otel.sdk.disabled=true" either from the application properties or the command line.

Output of uname -a or ver

Linux BSPC-HY7JZH3 5.15.167.4-microsoft-standard-WSL2 #1 SMP Tue Nov 5 00:21:55 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

Output of java -version

openjdk version "21.0.5" 2024-10-15 LTS OpenJDK Runtime Environment Corretto-21.0.5.11.1 (build 21.0.5+11-LTS) OpenJDK 64-Bit Server VM Corretto-21.0.5.11.1 (build 21.0.5+11-LTS, mixed mode, sharing)

Quarkus version or git rev

3.20.1

Build tool (ie. output of mvnw --version or gradlew --version)

Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937) Maven home: /opt/apache-maven-3.9.9 Java version: 21.0.5, vendor: Amazon.com Inc., runtime: /usr/lib/jvm/java-21-amazon-corretto Default locale: en, platform encoding: UTF-8 OS name: "linux", version: "5.15.167.4-microsoft-standard-wsl2", arch: "amd64", family: "unix"

Additional information

No response

Metadata

Metadata

Assignees

Type

Projects

Status

Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions