STORK_METRICS = new ConcurrentHashMap<>();
+
+ @Override
+ public StorkObservation create(String serviceName, String serviceDiscoveryType,
+ String serviceSelectionType) {
+ return STORK_METRICS.computeIfAbsent(serviceName + METRICS_SUFIX,
+ key -> new StorkObservation(serviceName, serviceDiscoveryType, serviceSelectionType,
+ this));
+ }
+
+ @Override
+ public void complete(StorkObservation observation) {
+ Tags tags = Tags.of(Tag.of("service-name", observation.getServiceName()));
+
+ Counter instanceCounter = Counter.builder("stork.service-discovery.instances.count")
+ .description("The number of service instances discovered")
+ .tags(tags)
+ .register(registry);
+
+ Timer serviceDiscoveryTimer = Timer
+ .builder("stork.service-discovery.duration")
+ .description("The duration of the discovery operation")
+ .tags(tags)
+ .register(registry);
+
+ Timer serviceSelectionTimer = Timer
+ .builder("stork.service-selection.duration")
+ .description("The duration of the selection operation ")
+ .tags(tags)
+ .register(registry);
+
+ Counter serviceDiscoveryFailures = Counter
+ .builder("stork.service-discovery.failures")
+ .description("The number of failures during service discovery").tags(tags)
+ .register(registry);
+
+ Counter serviceSelectionFailures = Counter
+ .builder("stork.service-selection.failures")
+ .description("The number of failures during service selection.").tags(tags)
+ .register(registry);
+
+ instanceCounter.increment(observation.getDiscoveredInstancesCount());
+ serviceDiscoveryTimer.record(observation.getServiceDiscoveryDuration().getNano(), TimeUnit.NANOSECONDS);
+ serviceSelectionTimer.record(observation.getServiceSelectionDuration().getNano(), TimeUnit.NANOSECONDS);
+
+ if (observation.failure() != null) {
+ if (observation.isServiceDiscoverySuccessful()) {
+ serviceSelectionFailures.increment();
+ } else {// SD failure
+ serviceDiscoveryFailures.increment();
+ }
+ }
+
+ }
+}
diff --git a/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/config/MicrometerConfig.java b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/config/MicrometerConfig.java
index 75042e33cf11d..7286227a22b23 100644
--- a/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/config/MicrometerConfig.java
+++ b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/config/MicrometerConfig.java
@@ -99,6 +99,7 @@ public static class BinderConfig {
public KafkaConfigGroup kafka;
public RedisConfigGroup redis;
+ public StorkConfigGroup stork;
public GrpcServerConfigGroup grpcServer;
diff --git a/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/config/StorkConfigGroup.java b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/config/StorkConfigGroup.java
new file mode 100644
index 0000000000000..cca42c194fbb2
--- /dev/null
+++ b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/config/StorkConfigGroup.java
@@ -0,0 +1,33 @@
+package io.quarkus.micrometer.runtime.config;
+
+import java.util.Optional;
+
+import io.quarkus.runtime.annotations.ConfigGroup;
+import io.quarkus.runtime.annotations.ConfigItem;
+
+@ConfigGroup
+public class StorkConfigGroup implements MicrometerConfig.CapabilityEnabled {
+ /**
+ * Stork metrics support.
+ *
+ * Support for Stork metrics will be enabled if Micrometer support is enabled,
+ * the Quarkus Stork extension is on the classpath
+ * and either this value is true, or this value is unset and
+ * {@code quarkus.micrometer.binder-enabled-default} is true.
+ */
+ @ConfigItem
+ public Optional enabled;
+
+ @Override
+ public Optional getEnabled() {
+ return enabled;
+ }
+
+ @Override
+ public String toString() {
+ return this.getClass().getSimpleName()
+ + "{enabled=" + enabled
+ + '}';
+ }
+
+}
diff --git a/extensions/smallrye-stork/runtime/src/main/java/io/quarkus/stork/QuarkusStorkObservableInfrastructure.java b/extensions/smallrye-stork/runtime/src/main/java/io/quarkus/stork/QuarkusStorkObservableInfrastructure.java
new file mode 100644
index 0000000000000..1030fab1b6696
--- /dev/null
+++ b/extensions/smallrye-stork/runtime/src/main/java/io/quarkus/stork/QuarkusStorkObservableInfrastructure.java
@@ -0,0 +1,22 @@
+package io.quarkus.stork;
+
+import jakarta.inject.Singleton;
+
+import io.smallrye.stork.api.observability.ObservationCollector;
+import io.vertx.core.Vertx;
+
+@Singleton
+public class QuarkusStorkObservableInfrastructure extends QuarkusStorkInfrastructure {
+
+ private final ObservationCollector observationCollector;
+
+ public QuarkusStorkObservableInfrastructure(Vertx vertx, ObservationCollector observationCollector) {
+ super(vertx);
+ this.observationCollector = observationCollector;
+ }
+
+ @Override
+ public ObservationCollector getObservationCollector() {
+ return observationCollector;
+ }
+}
diff --git a/extensions/smallrye-stork/runtime/src/main/java/io/quarkus/stork/SmallRyeStorkRecorder.java b/extensions/smallrye-stork/runtime/src/main/java/io/quarkus/stork/SmallRyeStorkRecorder.java
index dd82473fdac6c..4935a63c2cf29 100644
--- a/extensions/smallrye-stork/runtime/src/main/java/io/quarkus/stork/SmallRyeStorkRecorder.java
+++ b/extensions/smallrye-stork/runtime/src/main/java/io/quarkus/stork/SmallRyeStorkRecorder.java
@@ -2,11 +2,15 @@
import java.util.List;
+import jakarta.enterprise.inject.Instance;
+import jakarta.enterprise.inject.spi.CDI;
+
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.ShutdownContext;
import io.quarkus.runtime.annotations.Recorder;
import io.smallrye.stork.Stork;
import io.smallrye.stork.api.config.ServiceConfig;
+import io.smallrye.stork.api.observability.ObservationCollector;
import io.vertx.core.Vertx;
@Recorder
@@ -15,7 +19,14 @@ public class SmallRyeStorkRecorder {
public void initialize(ShutdownContext shutdown, RuntimeValue vertx, StorkConfiguration configuration) {
List serviceConfigs = StorkConfigUtil.toStorkServiceConfig(configuration);
StorkConfigProvider.init(serviceConfigs);
- Stork.initialize(new QuarkusStorkInfrastructure(vertx.getValue()));
+ Instance instance = CDI.current().select(ObservationCollector.class);
+ if (instance.isResolvable()) {
+ Stork.initialize(new QuarkusStorkObservableInfrastructure(vertx.getValue(), instance.get()));
+ } else {
+ QuarkusStorkInfrastructure infrastructure = new QuarkusStorkInfrastructure(vertx.getValue());
+ Stork.initialize(infrastructure);
+ }
+
shutdown.addShutdownTask(new Runnable() {
@Override
public void run() {
diff --git a/independent-projects/resteasy-reactive/pom.xml b/independent-projects/resteasy-reactive/pom.xml
index 4920d8e9a3607..527adec1ac51e 100644
--- a/independent-projects/resteasy-reactive/pom.xml
+++ b/independent-projects/resteasy-reactive/pom.xml
@@ -67,7 +67,7 @@
5.3.2
1.0.0.Final
2.15.2
- 2.3.1
+ 2.4.0
3.0.2
3.0.3
3.0.0