diff --git a/extensions/opentelemetry/deployment/src/main/java/io/quarkus/opentelemetry/deployment/tracing/instrumentation/InstrumentationProcessor.java b/extensions/opentelemetry/deployment/src/main/java/io/quarkus/opentelemetry/deployment/tracing/instrumentation/InstrumentationProcessor.java
index 1bac28f2b0fe32..853a6682a92617 100644
--- a/extensions/opentelemetry/deployment/src/main/java/io/quarkus/opentelemetry/deployment/tracing/instrumentation/InstrumentationProcessor.java
+++ b/extensions/opentelemetry/deployment/src/main/java/io/quarkus/opentelemetry/deployment/tracing/instrumentation/InstrumentationProcessor.java
@@ -109,7 +109,7 @@ VertxOptionsConsumerBuildItem vertxTracingOptions(
return new VertxOptionsConsumerBuildItem(vertxTracingOptions, LIBRARY_AFTER);
}
- // RESTEasy and Vert.x web
+ // REaSTEasy and Vert.x web
@BuildStep
void registerResteasyClassicAndOrResteasyReactiveProvider(
Capabilities capabilities,
@@ -142,5 +142,4 @@ void resteasyReactiveIntegration(
preExceptionMapperHandlerBuildItemBuildProducer
.produce(new PreExceptionMapperHandlerBuildItem(new AttachExceptionHandler()));
}
-
}
diff --git a/extensions/opentelemetry/runtime/pom.xml b/extensions/opentelemetry/runtime/pom.xml
index 7befd1be1b261e..700b06eb1d29fc 100644
--- a/extensions/opentelemetry/runtime/pom.xml
+++ b/extensions/opentelemetry/runtime/pom.xml
@@ -61,7 +61,16 @@
quarkus-smallrye-reactive-messaging
true
-
+
+ io.quarkus
+ quarkus-quartz
+ true
+
+
+
+
+
+
io.opentelemetry
diff --git a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/build/TracesBuildConfig.java b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/build/TracesBuildConfig.java
index 2bbe78e10fbf13..54c6908fc9b64a 100644
--- a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/build/TracesBuildConfig.java
+++ b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/build/TracesBuildConfig.java
@@ -12,6 +12,7 @@
* Tracing build time configuration
*/
@ConfigGroup
+//@ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED)
public interface TracesBuildConfig {
/**
diff --git a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/runtime/OTelRuntimeConfig.java b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/runtime/OTelRuntimeConfig.java
index b7eb750b2e36fc..2a40c85ac11d18 100644
--- a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/runtime/OTelRuntimeConfig.java
+++ b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/runtime/OTelRuntimeConfig.java
@@ -63,4 +63,12 @@ public interface OTelRuntimeConfig {
*/
@WithName("experimental.resource.disabled-keys")
Optional> experimentalResourceDisabledKeys();
+
+ /**
+ * Indicates whether experimental attributes are disabled.
+ * If enabled, experimental data will be excluded from spans.
+ */
+ @WithName("experimental.attributes.disabled")
+ @WithDefault("false")
+ boolean attributesExperimentalDisabled();
}
diff --git a/extensions/quartz/runtime/pom.xml b/extensions/quartz/runtime/pom.xml
index 0540be355fbaeb..1b7818b00dfa17 100644
--- a/extensions/quartz/runtime/pom.xml
+++ b/extensions/quartz/runtime/pom.xml
@@ -55,6 +55,17 @@
-->
+
+
+ io.opentelemetry.instrumentation
+ opentelemetry-instrumentation-api
+ true
+
+
+ io.opentelemetry.instrumentation
+ opentelemetry-instrumentation-api-semconv
+ true
+
diff --git a/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/QuartzScheduler.java b/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/QuartzScheduler.java
index 395a6de8369a4a..1c36f338ac2e7c 100644
--- a/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/QuartzScheduler.java
+++ b/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/QuartzScheduler.java
@@ -12,5 +12,4 @@ public interface QuartzScheduler extends Scheduler {
* @return the underlying {@link org.quartz.Scheduler} instance, or {@code null} if the scheduler was not started
*/
org.quartz.Scheduler getScheduler();
-
}
diff --git a/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java b/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java
index ce07d6ee5914c4..1bd7ca86347a2d 100644
--- a/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java
+++ b/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzSchedulerImpl.java
@@ -31,11 +31,13 @@
import jakarta.enterprise.inject.Instance;
import jakarta.enterprise.inject.Produces;
import jakarta.enterprise.inject.Typed;
+import jakarta.enterprise.inject.spi.CDI;
import jakarta.inject.Singleton;
import jakarta.interceptor.Interceptor;
import jakarta.transaction.SystemException;
import jakarta.transaction.UserTransaction;
+import org.eclipse.microprofile.config.ConfigProvider;
import org.jboss.logging.Logger;
import org.quartz.CronScheduleBuilder;
import org.quartz.Job;
@@ -65,6 +67,7 @@
import io.quarkus.arc.Subclass;
import io.quarkus.quartz.QuartzScheduler;
+import io.quarkus.quartz.runtime.tracing.WithSpanJob;
import io.quarkus.runtime.StartupEvent;
import io.quarkus.scheduler.FailedExecution;
import io.quarkus.scheduler.Scheduled;
@@ -84,7 +87,9 @@
import io.quarkus.scheduler.common.runtime.ScheduledMethod;
import io.quarkus.scheduler.common.runtime.SchedulerContext;
import io.quarkus.scheduler.common.runtime.SyntheticScheduled;
+import io.quarkus.scheduler.common.runtime.WithSpanInvoker;
import io.quarkus.scheduler.common.runtime.util.SchedulerUtils;
+import io.quarkus.scheduler.runtime.SchedulerConfig;
import io.quarkus.scheduler.runtime.SchedulerRuntimeConfig;
import io.quarkus.scheduler.runtime.SchedulerRuntimeConfig.StartMode;
import io.quarkus.scheduler.runtime.SimpleScheduler;
@@ -123,6 +128,7 @@ public class QuartzSchedulerImpl implements QuartzScheduler {
private final Event scheduledJobPausedEvent;
private final Event scheduledJobResumedEvent;
private final QuartzRuntimeConfig runtimeConfig;
+ private final SchedulerConfig schedulerConfig;
public QuartzSchedulerImpl(SchedulerContext context, QuartzSupport quartzSupport,
SchedulerRuntimeConfig schedulerRuntimeConfig,
@@ -131,7 +137,8 @@ public QuartzSchedulerImpl(SchedulerContext context, QuartzSupport quartzSupport
Event schedulerResumedEvent, Event scheduledJobPausedEvent,
Event scheduledJobResumedEvent,
Instance jobs, Instance userTransaction,
- Vertx vertx) {
+ Vertx vertx,
+ SchedulerConfig schedulerConfig) {
this.shutdownWaitTime = quartzSupport.getRuntimeConfig().shutdownWaitTime;
this.skippedExecutionEvent = skippedExecutionEvent;
this.successExecutionEvent = successExecutionEvent;
@@ -143,6 +150,7 @@ public QuartzSchedulerImpl(SchedulerContext context, QuartzSupport quartzSupport
this.runtimeConfig = quartzSupport.getRuntimeConfig();
this.enabled = schedulerRuntimeConfig.enabled;
this.defaultOverdueGracePeriod = schedulerRuntimeConfig.overdueGracePeriod;
+ this.schedulerConfig = schedulerConfig;
StartMode startMode = initStartMode(schedulerRuntimeConfig, runtimeConfig);
@@ -196,7 +204,8 @@ public QuartzSchedulerImpl(SchedulerContext context, QuartzSupport quartzSupport
scheduler = schedulerFactory.getScheduler();
// Set custom job factory
- scheduler.setJobFactory(new InvokerJobFactory(scheduledTasks, jobs, vertx));
+ scheduler.setJobFactory(
+ new InvokerJobFactory(scheduledTasks, jobs, vertx, schedulerConfig));
if (transaction != null) {
transaction.begin();
@@ -757,6 +766,14 @@ private Optional> createTrigger(String identity, Scheduled sch
return Optional.of(triggerBuilder);
}
+ private static boolean isOTelTracingEnabled() {
+ return ConfigProvider.getConfig().getValue("quarkus.otel.enabled", Boolean.class);
+ }
+
+ private static boolean isOTelExtensionAvailable() {
+ return CDI.current().select(io.opentelemetry.api.OpenTelemetry.class).isResolvable();
+ }
+
class QuartzJobDefinition extends AbstractJobDefinition {
QuartzJobDefinition(String id) {
@@ -791,6 +808,7 @@ public boolean isRunningOnVirtualThread() {
};
} else {
invoker = new DefaultInvoker() {
+
@Override
public CompletionStage invokeBean(ScheduledExecution execution) {
try {
@@ -807,6 +825,7 @@ public boolean isBlocking() {
};
}
+
Scheduled scheduled = new SyntheticScheduled(identity, cron, every, 0, TimeUnit.MINUTES, delayed,
overdueGracePeriod, concurrentExecution, skipPredicate, timeZone);
@@ -816,6 +835,9 @@ public boolean isBlocking() {
if (triggerBuilder.isPresent()) {
invoker = SimpleScheduler.initInvoker(invoker, skippedExecutionEvent, successExecutionEvent,
failedExecutionEvent, concurrentExecution, skipPredicate);
+ if (schedulerConfig.tracingEnabled && isOTelExtensionAvailable() && isOTelTracingEnabled()) {
+ invoker = new WithSpanInvoker(invoker);
+ }
org.quartz.Trigger trigger = triggerBuilder.get().build();
QuartzTrigger existing = scheduledTasks.putIfAbsent(identity, new QuartzTrigger(trigger.getKey(),
new Function<>() {
@@ -895,6 +917,7 @@ public void run() {
});
} else {
context.executeBlocking(new Callable