From bfaee7bf9cdc3993885f11d632fce36299a6dbfe Mon Sep 17 00:00:00 2001 From: brunobat Date: Tue, 20 Aug 2024 14:01:27 +0100 Subject: [PATCH] Upgrade micrometer to 1.13. Use prometheus simple client --- bom/application/pom.xml | 4 +- .../telemetry-micrometer-tutorial.adoc | 2 + .../deployment/pom.xml | 2 +- .../runtime/pom.xml | 2 +- extensions/micrometer/deployment/pom.xml | 2 +- .../deployment/MicrometerProcessor.java | 15 ++++++- .../deployment/binder/NettyMetricsTest.java | 20 +++++++-- .../binder/RedisClientMetricsTest.java | 20 +++++++-- .../StorkMetricsLoadBalancerFailTest.java | 38 ++++++++++++---- .../StorkMetricsServiceDiscoveryFailTest.java | 39 +++++++++++++---- .../deployment/binder/StorkMetricsTest.java | 43 ++++++++++++++----- .../binder/VertxConnectionMetricsTest.java | 28 +++++++++--- .../binder/VertxEventBusMetricsTest.java | 17 +++++++- .../binder/VertxHttpClientMetricsTest.java | 31 +++++++++---- .../VertxTcpMetricsNoClientMetricsTest.java | 17 +++++++- .../binder/VertxUdpMetricsTest.java | 25 ++++++++--- extensions/micrometer/runtime/pom.xml | 2 +- .../runtime/MicrometerRecorder.java | 7 ++- .../stork/StorkObservationCollectorBean.java | 23 ++++++---- .../vertx/HttpInstrumenterVertxTracer.java | 8 +++- .../ExtendedQuarkusVertxHttpMetrics.java | 1 + 21 files changed, 270 insertions(+), 76 deletions(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index b11e683324738..ad48331945bc3 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -36,8 +36,8 @@ 2.5.0-alpha 1.25.0-alpha 5.3.1 - 1.12.5 - 2.1.12 + 1.13.3 + 2.2.2 0.22.0 22.1 3.1 diff --git a/docs/src/main/asciidoc/telemetry-micrometer-tutorial.adoc b/docs/src/main/asciidoc/telemetry-micrometer-tutorial.adoc index 4d83350cef63f..287ade0da1418 100644 --- a/docs/src/main/asciidoc/telemetry-micrometer-tutorial.adoc +++ b/docs/src/main/asciidoc/telemetry-micrometer-tutorial.adoc @@ -40,6 +40,8 @@ include::{includes}/devtools/create-app.adoc[] This command generates a Maven project, that imports the `micrometer-registry-prometheus` extension as a dependency. This extension will load the core `micrometer` extension as well as additional library dependencies required to support prometheus. +NOTE: To maintain backwards compatibility, the extension uses the Prometheus client v0.x from Micrometer 1.13+, instead of their default v1.x client. + == Create a REST endpoint Let's first add a simple endpoint that calculates prime numbers. diff --git a/extensions/micrometer-registry-prometheus/deployment/pom.xml b/extensions/micrometer-registry-prometheus/deployment/pom.xml index e1b665a45f8c0..7838ddfabb0de 100644 --- a/extensions/micrometer-registry-prometheus/deployment/pom.xml +++ b/extensions/micrometer-registry-prometheus/deployment/pom.xml @@ -27,7 +27,7 @@ io.micrometer - micrometer-registry-prometheus + micrometer-registry-prometheus-simpleclient diff --git a/extensions/micrometer-registry-prometheus/runtime/pom.xml b/extensions/micrometer-registry-prometheus/runtime/pom.xml index 1027bba2f1548..53329e453e628 100644 --- a/extensions/micrometer-registry-prometheus/runtime/pom.xml +++ b/extensions/micrometer-registry-prometheus/runtime/pom.xml @@ -32,7 +32,7 @@ io.micrometer - micrometer-registry-prometheus + micrometer-registry-prometheus-simpleclient diff --git a/extensions/micrometer/deployment/pom.xml b/extensions/micrometer/deployment/pom.xml index cf068ad6c8e55..c447125f6737d 100644 --- a/extensions/micrometer/deployment/pom.xml +++ b/extensions/micrometer/deployment/pom.xml @@ -63,7 +63,7 @@ io.micrometer - micrometer-registry-prometheus + micrometer-registry-prometheus-simpleclient test diff --git a/extensions/micrometer/deployment/src/main/java/io/quarkus/micrometer/deployment/MicrometerProcessor.java b/extensions/micrometer/deployment/src/main/java/io/quarkus/micrometer/deployment/MicrometerProcessor.java index b7f2b605d1dd0..3707ef261190b 100644 --- a/extensions/micrometer/deployment/src/main/java/io/quarkus/micrometer/deployment/MicrometerProcessor.java +++ b/extensions/micrometer/deployment/src/main/java/io/quarkus/micrometer/deployment/MicrometerProcessor.java @@ -37,6 +37,7 @@ import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.CombinedIndexBuildItem; import io.quarkus.deployment.builditem.ShutdownContextBuildItem; +import io.quarkus.deployment.builditem.SystemPropertyBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.deployment.metrics.MetricsCapabilityBuildItem; import io.quarkus.deployment.metrics.MetricsFactoryConsumerBuildItem; @@ -207,8 +208,18 @@ void configureRegistry(MicrometerRecorder recorder, MicrometerConfig config, List providerClassItems, List metricsFactoryConsumerBuildItems, - List providerClasses, - ShutdownContextBuildItem shutdownContextBuildItem) { + ShutdownContextBuildItem shutdownContextBuildItem, + BuildProducer systemProperty) { + + // Avoid users from receiving: + // [io.mic.cor.ins.com.CompositeMeterRegistry] (main) A MeterFilter is being configured after a Meter has been + // registered to this registry... + // It's unavoidable because of how Quarkus startup works and users cannot do anything about it. + // see: https://github.com/micrometer-metrics/micrometer/issues/4920#issuecomment-2298348202 + systemProperty.produce( + new SystemPropertyBuildItem( + "quarkus.log.category.\"io.micrometer.core.instrument.composite.CompositeMeterRegistry\".level", + "ERROR")); Set> typeClasses = new HashSet<>(); for (MicrometerRegistryProviderBuildItem item : providerClassItems) { diff --git a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/NettyMetricsTest.java b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/NettyMetricsTest.java index 8384a8900e7d9..49b15fa6b36a2 100644 --- a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/NettyMetricsTest.java +++ b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/NettyMetricsTest.java @@ -14,7 +14,9 @@ import jakarta.inject.Inject; import org.hamcrest.Matchers; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.extension.RegisterExtension; @@ -22,12 +24,13 @@ import io.micrometer.common.docs.KeyName; import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.Meter; -import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Tags; import io.micrometer.core.instrument.binder.MeterBinder; import io.micrometer.core.instrument.binder.netty4.NettyAllocatorMetrics; import io.micrometer.core.instrument.binder.netty4.NettyEventExecutorMetrics; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.netty.buffer.PooledByteBufAllocator; import io.netty.buffer.UnpooledByteBufAllocator; import io.netty.channel.EventLoopGroup; @@ -53,8 +56,17 @@ public class NettyMetricsTest { @Any Instance binders; - @Inject - MeterRegistry registry; + final static SimpleMeterRegistry registry = new SimpleMeterRegistry(); + + @BeforeAll + static void setRegistry() { + Metrics.addRegistry(registry); + } + + @AfterAll() + static void removeRegistry() { + Metrics.removeRegistry(registry); + } @Inject Vertx vertx; @@ -228,4 +240,4 @@ private void checkMetrics(List meters, EventExecutor executor, int expect Assertions.assertEquals(expected, mvInt); } } -} \ No newline at end of file +} diff --git a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/RedisClientMetricsTest.java b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/RedisClientMetricsTest.java index 15b79e3bd1873..8291689c4e0f4 100644 --- a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/RedisClientMetricsTest.java +++ b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/RedisClientMetricsTest.java @@ -6,15 +6,18 @@ import jakarta.inject.Inject; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.extension.RegisterExtension; import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.search.MeterNotFoundException; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.quarkus.redis.datasource.RedisDataSource; import io.quarkus.test.QuarkusUnitTest; import io.vertx.redis.client.Command; @@ -27,15 +30,24 @@ public class RedisClientMetricsTest { @RegisterExtension static final QuarkusUnitTest config = new QuarkusUnitTest(); + final static SimpleMeterRegistry registry = new SimpleMeterRegistry(); + + @BeforeAll + static void setRegistry() { + Metrics.addRegistry(registry); + } + + @AfterAll() + static void removeRegistry() { + Metrics.removeRegistry(registry); + } + @Inject RedisDataSource ds; @Inject Redis redis; - @Inject - MeterRegistry registry; - @Test void testCommands() { double count = 0.0; diff --git a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/StorkMetricsLoadBalancerFailTest.java b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/StorkMetricsLoadBalancerFailTest.java index db194f741a533..586569da48acb 100644 --- a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/StorkMetricsLoadBalancerFailTest.java +++ b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/StorkMetricsLoadBalancerFailTest.java @@ -8,6 +8,8 @@ import jakarta.inject.Inject; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; @@ -15,9 +17,10 @@ import org.mockito.Mockito; import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Timer; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.quarkus.micrometer.runtime.binder.stork.StorkObservationCollectorBean; import io.quarkus.micrometer.test.GreetingResource; import io.quarkus.micrometer.test.MockServiceSelectorConfiguration; @@ -50,8 +53,17 @@ public class StorkMetricsLoadBalancerFailTest { MockServiceSelectorProviderLoader.class, GreetingResource.class, GreetingResource.GreetingRestClient.class, Util.class)); - @Inject - MeterRegistry registry; + final static SimpleMeterRegistry registry = new SimpleMeterRegistry(); + + @BeforeAll + static void setRegistry() { + Metrics.addRegistry(registry); + } + + @AfterAll() + static void removeRegistry() { + Metrics.removeRegistry(registry); + } @Inject MockServiceSelectorProvider provider; @@ -91,15 +103,25 @@ private static void assertStorkMetrics(String serviceName) { } private void assertStorkMetricsInMicrometerRegistry(String serviceName) { - Counter instanceCounter = registry.counter("stork.service-discovery.instances.count", "service-name", serviceName); - Timer serviceDiscoveryDuration = registry.timer("stork.service-discovery.duration", "service-name", serviceName); - Timer serviceSelectionDuration = registry.timer("stork.service-selection.duration", "service-name", serviceName); - Counter serviceDiscoveryFailures = registry.counter("stork.service-discovery.failures", "service-name", serviceName); - Counter loadBalancerFailures = registry.counter("stork.service-selection.failures", "service-name", serviceName); + Counter instanceCounter = registry.find("stork.service-discovery.instances.count").tag("service-name", serviceName) + .counter(); + Timer serviceDiscoveryDuration = registry.find("stork.service-discovery.duration").tag("service-name", serviceName) + .timer(); + Timer serviceSelectionDuration = registry.find("stork.service-selection.duration").tag("service-name", serviceName) + .timer(); + Counter serviceDiscoveryFailures = registry.find("stork.service-discovery.failures").tag("service-name", serviceName) + .counter(); + Counter loadBalancerFailures = registry.find("stork.service-selection.failures").tag("service-name", serviceName) + .counter(); Util.assertTags(Tag.of("service-name", serviceName), instanceCounter, serviceDiscoveryDuration, serviceSelectionDuration); + Assertions.assertThat(instanceCounter).isNotNull(); + Assertions.assertThat(serviceDiscoveryDuration).isNotNull(); + Assertions.assertThat(serviceSelectionDuration).isNotNull(); + Assertions.assertThat(serviceDiscoveryFailures).isNotNull(); + Assertions.assertThat(loadBalancerFailures).isNotNull(); Assertions.assertThat(instanceCounter.count()).isEqualTo(1); Assertions.assertThat(loadBalancerFailures.count()).isEqualTo(1); Assertions.assertThat(serviceDiscoveryFailures.count()).isEqualTo(0); diff --git a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/StorkMetricsServiceDiscoveryFailTest.java b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/StorkMetricsServiceDiscoveryFailTest.java index bb7bf88b562f2..92beb6f34c099 100644 --- a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/StorkMetricsServiceDiscoveryFailTest.java +++ b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/StorkMetricsServiceDiscoveryFailTest.java @@ -2,13 +2,14 @@ package io.quarkus.micrometer.deployment.binder; import static io.restassured.RestAssured.when; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import java.util.concurrent.TimeUnit; import jakarta.inject.Inject; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; @@ -16,9 +17,10 @@ import org.mockito.Mockito; import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Timer; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.quarkus.micrometer.runtime.binder.stork.StorkObservationCollectorBean; import io.quarkus.micrometer.test.GreetingResource; import io.quarkus.micrometer.test.MockServiceDiscoveryConfiguration; @@ -48,8 +50,17 @@ public class StorkMetricsServiceDiscoveryFailTest { MockServiceDiscoveryProviderLoader.class, GreetingResource.class, GreetingResource.GreetingRestClient.class, Util.class)); - @Inject - MeterRegistry registry; + final static SimpleMeterRegistry registry = new SimpleMeterRegistry(); + + @BeforeAll + static void setRegistry() { + Metrics.addRegistry(registry); + } + + @AfterAll() + static void removeRegistry() { + Metrics.removeRegistry(registry); + } @Inject MockServiceDiscoveryProvider provider; @@ -73,15 +84,25 @@ public void shouldGetStorkMetricsWhenServiceDiscoveryFails() { } private void assertStorkMetricsInMicrometerRegistry(String serviceName) { - Counter instanceCounter = registry.counter("stork.service-discovery.instances.count", "service-name", serviceName); - Timer serviceDiscoveryDuration = registry.timer("stork.service-discovery.duration", "service-name", serviceName); - Timer serviceSelectionDuration = registry.timer("stork.service-selection.duration", "service-name", serviceName); - Counter serviceDiscoveryFailures = registry.counter("stork.service-discovery.failures", "service-name", serviceName); - Counter loadBalancerFailures = registry.counter("stork.service-selection.failures", "service-name", serviceName); + Counter instanceCounter = registry.find("stork.service-discovery.instances.count").tags("service-name", serviceName) + .counter(); + Timer serviceDiscoveryDuration = registry.find("stork.service-discovery.duration").tags("service-name", serviceName) + .timer(); + Timer serviceSelectionDuration = registry.find("stork.service-selection.duration").tags("service-name", serviceName) + .timer(); + Counter serviceDiscoveryFailures = registry.find("stork.service-discovery.failures").tags("service-name", serviceName) + .counter(); + Counter loadBalancerFailures = registry.find("stork.service-selection.failures").tags("service-name", serviceName) + .counter(); Util.assertTags(Tag.of("service-name", serviceName), instanceCounter, serviceDiscoveryDuration, serviceSelectionDuration); + Assertions.assertThat(instanceCounter).isNotNull(); + Assertions.assertThat(serviceDiscoveryDuration).isNotNull(); + Assertions.assertThat(serviceSelectionDuration).isNotNull(); + Assertions.assertThat(serviceDiscoveryFailures).isNotNull(); + Assertions.assertThat(loadBalancerFailures).isNotNull(); Assertions.assertThat(instanceCounter.count()).isEqualTo(0); Assertions.assertThat(loadBalancerFailures.count()).isEqualTo(0); Assertions.assertThat(serviceDiscoveryFailures.count()).isEqualTo(1); diff --git a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/StorkMetricsTest.java b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/StorkMetricsTest.java index 42ff35297e6e6..b7b548f914ec7 100644 --- a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/StorkMetricsTest.java +++ b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/StorkMetricsTest.java @@ -5,18 +5,19 @@ import java.util.concurrent.TimeUnit; -import jakarta.inject.Inject; - import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.DisabledOnOs; import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.extension.RegisterExtension; import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Timer; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.quarkus.micrometer.runtime.binder.stork.StorkObservationCollectorBean; import io.quarkus.micrometer.test.GreetingResource; import io.quarkus.micrometer.test.PingPongResource; @@ -37,15 +38,25 @@ public class StorkMetricsTest { .overrideConfigKey("quarkus.stork.greeting-service.service-discovery.type", "static") .overrideConfigKey("quarkus.stork.greeting-service.service-discovery.address-list", "${test.url}") .overrideConfigKey("quarkus.redis.devservices.enabled", "false") + .overrideConfigKey("quarkus.log.category.\"io.micrometer.core.instrument\".level", "DEBUG") .withApplicationRoot((jar) -> jar .addClasses(PingPongResource.class, PingPongResource.PingPongRestClient.class, GreetingResource.class, GreetingResource.GreetingRestClient.class, Util.class)); - @Inject - MeterRegistry registry; + final static SimpleMeterRegistry registry = new SimpleMeterRegistry(); + + @BeforeAll + static void setRegistry() { + Metrics.addRegistry(registry); + } + + @AfterAll() + static void removeRegistry() { + Metrics.removeRegistry(registry); + } @Test - public void shouldGetStorkMetricsForTwoServicesWhenEverythingSucceded() { + public void shouldGetStorkMetricsForTwoServicesWhenEverythingSucceeded() { when().get("/ping/one").then().statusCode(200); when().get("greeting/hola").then().statusCode(200); @@ -61,15 +72,25 @@ public void shouldGetStorkMetricsForTwoServicesWhenEverythingSucceded() { private void assertStorkMetricsInMicrometerRegistry(String serviceName) { - Counter instanceCounter = registry.counter("stork.service-discovery.instances.count", "service-name", serviceName); - Timer serviceDiscoveryDuration = registry.timer("stork.service-discovery.duration", "service-name", serviceName); - Timer serviceSelectionDuration = registry.timer("stork.service-selection.duration", "service-name", serviceName); - Counter serviceDiscoveryFailures = registry.counter("stork.service-discovery.failures", "service-name", serviceName); - Counter loadBalancerFailures = registry.counter("stork.service-selection.failures", "service-name", serviceName); + Counter instanceCounter = registry.find("stork.service-discovery.instances.count").tags("service-name", serviceName) + .counter(); + Timer serviceDiscoveryDuration = registry.find("stork.service-discovery.duration").tags("service-name", serviceName) + .timer(); + Timer serviceSelectionDuration = registry.find("stork.service-selection.duration").tags("service-name", serviceName) + .timer(); + Counter serviceDiscoveryFailures = registry.find("stork.service-discovery.failures").tags("service-name", serviceName) + .counter(); + Counter loadBalancerFailures = registry.find("stork.service-selection.failures").tags("service-name", serviceName) + .counter(); Util.assertTags(Tag.of("service-name", serviceName), instanceCounter, serviceDiscoveryDuration, serviceSelectionDuration); + Assertions.assertThat(instanceCounter).isNotNull(); + Assertions.assertThat(serviceDiscoveryDuration).isNotNull(); + Assertions.assertThat(serviceSelectionDuration).isNotNull(); + Assertions.assertThat(serviceDiscoveryFailures).isNotNull(); + Assertions.assertThat(loadBalancerFailures).isNotNull(); Assertions.assertThat(instanceCounter.count()).isEqualTo(1); Assertions.assertThat(serviceDiscoveryDuration.totalTime(TimeUnit.NANOSECONDS)).isGreaterThan(0); Assertions.assertThat(serviceSelectionDuration.totalTime(TimeUnit.NANOSECONDS)).isGreaterThan(0); diff --git a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxConnectionMetricsTest.java b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxConnectionMetricsTest.java index 560e7514463c5..b63b5374e2753 100644 --- a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxConnectionMetricsTest.java +++ b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxConnectionMetricsTest.java @@ -7,13 +7,16 @@ import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.logging.Logger; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Observes; import jakarta.inject.Inject; import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -21,6 +24,7 @@ import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.Gauge; import io.micrometer.core.instrument.Metrics; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.quarkus.runtime.StartupEvent; import io.quarkus.test.QuarkusUnitTest; import io.restassured.RestAssured; @@ -31,6 +35,8 @@ */ public class VertxConnectionMetricsTest { + private static final Logger log = Logger.getLogger(VertxConnectionMetricsTest.class.getName()); + @RegisterExtension static final QuarkusUnitTest config = new QuarkusUnitTest() .withConfigurationResource("test-logging.properties") @@ -41,6 +47,18 @@ public class VertxConnectionMetricsTest { .overrideConfigKey("quarkus.http.idle-timeout", "1s") .withApplicationRoot(jar -> jar.addClasses(App.class)); + final static SimpleMeterRegistry registry = new SimpleMeterRegistry(); + + @BeforeAll + static void setRegistry() { + Metrics.addRegistry(registry); + } + + @AfterAll() + static void removeRegistry() { + Metrics.removeRegistry(registry); + } + @Inject App app; @@ -65,7 +83,7 @@ void testConnectionMetrics() throws InterruptedException { for (int i = 0; i < concurrency; i++) { executor.submit(() -> { try { - RestAssured.get("/ok").statusCode(); + log.info("status code received: " + RestAssured.get("/ok").statusCode()); } catch (Exception e) { // RestAssured considers the rejection as an error. rejected.incrementAndGet(); @@ -76,18 +94,18 @@ void testConnectionMetrics() throws InterruptedException { } Assertions.assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue(); - Gauge max = Metrics.globalRegistry.find("vertx.http.connections.max").gauge(); - Gauge current = Metrics.globalRegistry.find("vertx.http.connections.current").gauge(); + Gauge max = registry.find("vertx.http.connections.max").gauge(); + Gauge current = registry.find("vertx.http.connections.current").gauge(); Assertions.assertThat(max).isNotNull(); Assertions.assertThat(current).isNotNull(); - Assertions.assertThat(max.value()).isEqualTo(2); + Assertions.assertThat(max.value()).isEqualTo(2);// this is time windowed test... Set time window to large value // All requests are done, and connection closed (idle timeout) await().untilAsserted(() -> Assertions.assertThat(current.value()).isEqualTo(0)); if (rejected.get() > 0) { - Counter counter = Metrics.globalRegistry.find("vertx.http.connections.rejected").counter(); + Counter counter = registry.find("vertx.http.connections.rejected").counter(); Assertions.assertThat(counter).isNotNull(); Assertions.assertThat(counter.count()).isGreaterThan(0); } diff --git a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxEventBusMetricsTest.java b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxEventBusMetricsTest.java index 6c50d11e9f41a..fbc410238e901 100644 --- a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxEventBusMetricsTest.java +++ b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxEventBusMetricsTest.java @@ -2,12 +2,15 @@ import jakarta.inject.Inject; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.search.Search; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.quarkus.test.QuarkusUnitTest; import io.vertx.mutiny.core.Vertx; @@ -19,11 +22,23 @@ public class VertxEventBusMetricsTest { .overrideConfigKey("quarkus.redis.devservices.enabled", "false") .withEmptyApplication(); + final static SimpleMeterRegistry registry = new SimpleMeterRegistry(); + + @BeforeAll + static void setRegistry() { + Metrics.addRegistry(registry); + } + + @AfterAll() + static void removeRegistry() { + Metrics.removeRegistry(registry); + } + @Inject Vertx vertx; private Search getMeter(String name, String address) { - return Metrics.globalRegistry.find(name).tags("address", address); + return registry.find(name).tags("address", address); } @Test diff --git a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxHttpClientMetricsTest.java b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxHttpClientMetricsTest.java index 1267e99dad045..05222595a003d 100644 --- a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxHttpClientMetricsTest.java +++ b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxHttpClientMetricsTest.java @@ -10,12 +10,15 @@ import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.search.Search; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.quarkus.micrometer.test.Util; import io.quarkus.test.QuarkusUnitTest; import io.vertx.core.http.HttpClientOptions; @@ -38,6 +41,18 @@ public class VertxHttpClientMetricsTest { .withApplicationRoot((jar) -> jar .addClasses(App.class, HttpClient.class, WsClient.class, Util.class)); + final static SimpleMeterRegistry registry = new SimpleMeterRegistry(); + + @BeforeAll + static void setRegistry() { + Metrics.addRegistry(registry); + } + + @AfterAll() + static void removeRegistry() { + Metrics.removeRegistry(registry); + } + @Inject HttpClient client; @@ -48,7 +63,7 @@ public class VertxHttpClientMetricsTest { WsClient ws; private Search getMeter(String name) { - return Metrics.globalRegistry.find(name); + return registry.find(name); } @Test @@ -59,7 +74,7 @@ void testWebClientMetrics() { // If the WS test runs before, some data was already written double sizeBefore = 0; if (getMeter("http.client.bytes.written").summary() != null) { - sizeBefore = Metrics.globalRegistry.find("http.client.bytes.written") + sizeBefore = registry.find("http.client.bytes.written") .tag("clientName", "my-client") .summary().totalAmount(); } @@ -74,10 +89,10 @@ void testWebClientMetrics() { double expectedBytesWritten = sizeBefore + 5; await().untilAsserted( () -> Assertions.assertEquals(expectedBytesWritten, - Metrics.globalRegistry.find("http.client.bytes.written") + registry.find("http.client.bytes.written") .tag("clientName", "my-client").summary().totalAmount())); await().untilAsserted(() -> Assertions.assertEquals(7, - Metrics.globalRegistry.find("http.client.bytes.read") + registry.find("http.client.bytes.read") .tag("clientName", "my-client").summary().totalAmount())); await().until(() -> getMeter("http.client.requests").timer().totalTime(TimeUnit.NANOSECONDS) > 0); @@ -86,15 +101,15 @@ void testWebClientMetrics() { return getMeter("http.client.requests").timer().count() == 1; }); - Assertions.assertEquals(1, Metrics.globalRegistry.find("http.client.requests") + Assertions.assertEquals(1, registry.find("http.client.requests") .tag("uri", "root") .tag("outcome", "SUCCESS").timers().size(), - Util.foundClientRequests(Metrics.globalRegistry, "/ with tag outcome=SUCCESS.")); + Util.foundClientRequests(registry, "/ with tag outcome=SUCCESS.")); // Queue - Assertions.assertEquals(2, Metrics.globalRegistry.find("http.client.queue.delay") + Assertions.assertEquals(2, registry.find("http.client.queue.delay") .tag("clientName", "my-client").timer().count()); - Assertions.assertTrue(Metrics.globalRegistry.find("http.client.queue.delay") + Assertions.assertTrue(registry.find("http.client.queue.delay") .tag("clientName", "my-client").timer().totalTime(TimeUnit.NANOSECONDS) > 0); await().until(() -> getMeter("http.client.queue.size").gauge().value() == 0.0); diff --git a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxTcpMetricsNoClientMetricsTest.java b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxTcpMetricsNoClientMetricsTest.java index 1c0f8bfc500e9..c9324e1de9166 100644 --- a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxTcpMetricsNoClientMetricsTest.java +++ b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxTcpMetricsNoClientMetricsTest.java @@ -9,12 +9,15 @@ import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.search.Search; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.quarkus.test.QuarkusUnitTest; import io.vertx.mutiny.core.Vertx; import io.vertx.mutiny.core.net.NetSocket; @@ -34,8 +37,20 @@ public class VertxTcpMetricsNoClientMetricsTest { @Inject NetServer server; + final static SimpleMeterRegistry registry = new SimpleMeterRegistry(); + + @BeforeAll + static void setRegistry() { + Metrics.addRegistry(registry); + } + + @AfterAll() + static void removeRegistry() { + Metrics.removeRegistry(registry); + } + private Search getMeter(String name) { - return Metrics.globalRegistry.find(name); + return registry.find(name); } @Test diff --git a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxUdpMetricsTest.java b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxUdpMetricsTest.java index a341a23bb3ec4..57c09a9872243 100644 --- a/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxUdpMetricsTest.java +++ b/extensions/micrometer/deployment/src/test/java/io/quarkus/micrometer/deployment/binder/VertxUdpMetricsTest.java @@ -5,12 +5,15 @@ import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.search.Search; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import io.quarkus.test.QuarkusUnitTest; import io.vertx.mutiny.core.Vertx; import io.vertx.mutiny.core.datagram.DatagramSocket; @@ -24,6 +27,18 @@ public class VertxUdpMetricsTest { .withApplicationRoot((jar) -> jar .addClasses(ParticipantA.class, ParticipantB.class)); + final static SimpleMeterRegistry registry = new SimpleMeterRegistry(); + + @BeforeAll + static void setRegistry() { + Metrics.addRegistry(registry); + } + + @AfterAll() + static void removeRegistry() { + Metrics.removeRegistry(registry); + } + @Inject ParticipantA clientA; @@ -31,7 +46,7 @@ public class VertxUdpMetricsTest { ParticipantB clientB; private Search getMeter(String name) { - return Metrics.globalRegistry.find(name); + return registry.find(name); } @Test @@ -40,14 +55,14 @@ void testUdpMetrics() { clientB.start(); try { await().until(clientB::isDone); - Assertions.assertTrue(Metrics.globalRegistry.find("udp.bytes.read").tags("address", "127.0.0.1:8888").summary() + Assertions.assertTrue(registry.find("udp.bytes.read").tags("address", "127.0.0.1:8888").summary() .totalAmount() > 0); - Assertions.assertTrue(Metrics.globalRegistry.find("udp.bytes.read").tags("address", "127.0.0.1:8889").summary() + Assertions.assertTrue(registry.find("udp.bytes.read").tags("address", "127.0.0.1:8889").summary() .totalAmount() > 0); Assertions.assertNotNull( - Metrics.globalRegistry.find("udp.bytes.written").tags("address", "127.0.0.1:8889").summary()); + registry.find("udp.bytes.written").tags("address", "127.0.0.1:8889").summary()); Assertions.assertNotNull( - Metrics.globalRegistry.find("udp.bytes.written").tags("address", "127.0.0.1:8888").summary()); + registry.find("udp.bytes.written").tags("address", "127.0.0.1:8888").summary()); } finally { clientA.stop(); clientB.stop(); diff --git a/extensions/micrometer/runtime/pom.xml b/extensions/micrometer/runtime/pom.xml index 5573112a7d4b0..e1013832188d3 100644 --- a/extensions/micrometer/runtime/pom.xml +++ b/extensions/micrometer/runtime/pom.xml @@ -49,7 +49,7 @@ io.micrometer - micrometer-registry-prometheus + micrometer-registry-prometheus-simpleclient true diff --git a/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/MicrometerRecorder.java b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/MicrometerRecorder.java index d80a9054a1335..3ee697ae5835d 100644 --- a/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/MicrometerRecorder.java +++ b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/MicrometerRecorder.java @@ -29,6 +29,7 @@ import io.micrometer.core.instrument.binder.system.FileDescriptorMetrics; import io.micrometer.core.instrument.binder.system.ProcessorMetrics; import io.micrometer.core.instrument.binder.system.UptimeMetrics; +import io.micrometer.core.instrument.composite.CompositeMeterRegistry; import io.micrometer.core.instrument.config.MeterFilter; import io.quarkus.arc.Arc; import io.quarkus.micrometer.runtime.binder.HttpBinderConfiguration; @@ -56,10 +57,12 @@ public class MicrometerRecorder { @StaticInit public RuntimeValue createRootRegistry(MicrometerConfig config, String qUri, String httpUri) { - factory = new MicrometerMetricsFactory(config, Metrics.globalRegistry); + + CompositeMeterRegistry globalRegistry = Metrics.globalRegistry; + factory = new MicrometerMetricsFactory(config, globalRegistry); nonApplicationUri = qUri; httpRootUri = httpUri; - return new RuntimeValue<>(Metrics.globalRegistry); + return new RuntimeValue<>(globalRegistry); } @RuntimeInit diff --git a/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/binder/stork/StorkObservationCollectorBean.java b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/binder/stork/StorkObservationCollectorBean.java index c4b1552c280dc..a49b5ed341a12 100644 --- a/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/binder/stork/StorkObservationCollectorBean.java +++ b/extensions/micrometer/runtime/src/main/java/io/quarkus/micrometer/runtime/binder/stork/StorkObservationCollectorBean.java @@ -10,7 +10,6 @@ import io.micrometer.core.instrument.Counter; import io.micrometer.core.instrument.Meter; import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Tags; import io.micrometer.core.instrument.Timer; @@ -23,7 +22,6 @@ public class StorkObservationCollectorBean implements ObservationCollector, StorkEventHandler { public static final String METRICS_SUFFIX = "-metrics"; - final MeterRegistry registry = Metrics.globalRegistry; public final static Map STORK_METRICS = new ConcurrentHashMap<>(); private final Meter.MeterProvider instanceCounter; private final Meter.MeterProvider serviceDiscoveryTimer; @@ -31,7 +29,7 @@ public class StorkObservationCollectorBean implements ObservationCollector, Stor private final Meter.MeterProvider serviceDiscoveryFailures; private final Meter.MeterProvider serviceSelectionFailures; - public StorkObservationCollectorBean() { + public StorkObservationCollectorBean(final MeterRegistry registry) { this.instanceCounter = Counter .builder("stork.service-discovery.instances.count") @@ -45,7 +43,7 @@ public StorkObservationCollectorBean() { this.serviceSelectionTimer = Timer .builder("stork.service-selection.duration") - .description("The duration of the selection operation ") + .description("The duration of the selection operation") .withRegistry(registry); this.serviceDiscoveryFailures = Counter @@ -55,7 +53,7 @@ public StorkObservationCollectorBean() { this.serviceSelectionFailures = Counter .builder("stork.service-selection.failures") - .description("The number of failures during service selection.") + .description("The number of failures during service selection") .withRegistry(registry); } @@ -71,18 +69,27 @@ public StorkObservation create(String serviceName, String serviceDiscoveryType, public void complete(StorkObservation observation) { Tags tags = Tags.of(Tag.of("service-name", observation.getServiceName())); - this.instanceCounter.withTags(tags).increment(observation.getDiscoveredInstancesCount()); + int count = observation.getDiscoveredInstancesCount(); + this.instanceCounter.withTags(tags).increment(Math.max(count, 0)); this.serviceDiscoveryTimer.withTags(tags).record(observation.getServiceDiscoveryDuration().getNano(), TimeUnit.NANOSECONDS); this.serviceSelectionTimer.withTags(tags).record(observation.getServiceSelectionDuration().getNano(), TimeUnit.NANOSECONDS); + Counter ssf = this.serviceSelectionFailures.withTags(tags); + Counter sdf = this.serviceDiscoveryFailures.withTags(tags); if (observation.failure() != null) { if (observation.isServiceDiscoverySuccessful()) { - this.serviceSelectionFailures.withTags(tags).increment(); + ssf.increment(); } else {// SD failure - this.serviceDiscoveryFailures.withTags(tags).increment(); + sdf.increment(); + // This forces the creation of the counter if it does not exist. + ssf.increment(0); } + } else { + // This forces the creation of the counters if they do not exist. + ssf.increment(0); + sdf.increment(0); } } diff --git a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/intrumentation/vertx/HttpInstrumenterVertxTracer.java b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/intrumentation/vertx/HttpInstrumenterVertxTracer.java index 40b3030204c24..d8974c1c69215 100644 --- a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/intrumentation/vertx/HttpInstrumenterVertxTracer.java +++ b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/intrumentation/vertx/HttpInstrumenterVertxTracer.java @@ -297,8 +297,12 @@ public void onEnd( final HttpRequest httpRequest, final HttpResponse httpResponse, final Throwable error) { - attributes.put(HTTP_REQUEST_BODY_SIZE, getContentLength(httpRequest.headers())); - attributes.put(HTTP_RESPONSE_BODY_SIZE, getContentLength(httpResponse.headers())); + if (httpRequest != null) { + attributes.put(HTTP_REQUEST_BODY_SIZE, getContentLength(httpRequest.headers())); + } + if (httpResponse != null) { + attributes.put(HTTP_RESPONSE_BODY_SIZE, getContentLength(httpResponse.headers())); + } } private static Long getContentLength(final MultiMap headers) { diff --git a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ExtendedQuarkusVertxHttpMetrics.java b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ExtendedQuarkusVertxHttpMetrics.java index 2f94d233396cb..96def15ccee6b 100644 --- a/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ExtendedQuarkusVertxHttpMetrics.java +++ b/extensions/vertx-http/runtime/src/main/java/io/quarkus/vertx/http/runtime/ExtendedQuarkusVertxHttpMetrics.java @@ -22,6 +22,7 @@ public void onConnectionRejected() { @Override public void initialize(int maxConnections, AtomicInteger current) { + // no-op } };