From cd4d5791c87990f7ee28749c8034343a70b4da5d Mon Sep 17 00:00:00 2001 From: brunobat Date: Wed, 16 Oct 2024 19:00:47 +0100 Subject: [PATCH] Fix Class Cast Exception --- .../metrics/ClassCastExceptionTest.java | 44 +++++++++++++++++++ .../OpenTelemetryVertxMetricsFactory.java | 27 ++++++++---- 2 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/metrics/ClassCastExceptionTest.java diff --git a/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/metrics/ClassCastExceptionTest.java b/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/metrics/ClassCastExceptionTest.java new file mode 100644 index 0000000000000..b23fa2f0daedc --- /dev/null +++ b/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/metrics/ClassCastExceptionTest.java @@ -0,0 +1,44 @@ +package io.quarkus.opentelemetry.deployment.metrics; + +import org.jboss.shrinkwrap.api.ShrinkWrap; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.jboss.shrinkwrap.api.spec.JavaArchive; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.opentelemetry.deployment.common.exporter.InMemoryMetricExporter; +import io.quarkus.opentelemetry.deployment.common.exporter.InMemoryMetricExporterProvider; +import io.quarkus.opentelemetry.deployment.common.exporter.TestSpanExporter; +import io.quarkus.opentelemetry.deployment.common.exporter.TestSpanExporterProvider; +import io.quarkus.test.QuarkusUnitTest; + +public class ClassCastExceptionTest { + + @RegisterExtension + static final QuarkusUnitTest TEST = new QuarkusUnitTest() + .setArchiveProducer( + () -> ShrinkWrap.create(JavaArchive.class) + .addClasses(TestSpanExporter.class, TestSpanExporterProvider.class) + .addClasses(InMemoryMetricExporter.class, InMemoryMetricExporterProvider.class) + .addAsResource(new StringAsset(InMemoryMetricExporterProvider.class.getCanonicalName()), + "META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider") + .add(new StringAsset( + "quarkus.otel.metrics.enabled=true\n" + + "quarkus.otel.metrics.exporter=in-memory\n" + + "quarkus.otel.metric.export.interval=300ms\n" + + "quarkus.http.limits.max-connections=50\n" + + "quarkus.otel.traces.exporter=none\n" + + "quarkus.otel.logs.exporter=none\n"), + "application.properties")); + + /** + * ClassCastException when using OpenTelemetry and max-connections property + * See https://github.com/quarkusio/quarkus/issues/43852 + */ + @Test + public void testReproducer() { + // This test is successful if it does not throw an exception + Assertions.assertTrue(true); + } +} diff --git a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/intrumentation/vertx/OpenTelemetryVertxMetricsFactory.java b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/intrumentation/vertx/OpenTelemetryVertxMetricsFactory.java index 58bef36792bb7..32e7d006de6ec 100644 --- a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/intrumentation/vertx/OpenTelemetryVertxMetricsFactory.java +++ b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/intrumentation/vertx/OpenTelemetryVertxMetricsFactory.java @@ -2,6 +2,7 @@ import java.util.Optional; +import io.quarkus.vertx.http.runtime.ExtendedQuarkusVertxHttpMetrics; import io.vertx.core.Context; import io.vertx.core.VertxOptions; import io.vertx.core.http.HttpServerOptions; @@ -16,7 +17,7 @@ * This is used to retrieve the route name from Vert.x. This is useful for OpenTelemetry to generate the Span name and * http.route attribute. Right now, there is no other way to retrieve the route name from Vert.x using the * Telemetry SPI, so we need to rely on the Metrics SPI. - * + *

* Right now, it is not possible to register multiple VertxMetrics, meaning that only a single one is * available per Quarkus instance. To avoid clashing with other extensions that provide Metrics data (like the * Micrometer extension), we only register the {@link OpenTelemetryVertxMetricsFactory} if the @@ -25,17 +26,19 @@ public class OpenTelemetryVertxMetricsFactory implements VertxMetricsFactory { @Override public VertxMetrics metrics(final VertxOptions options) { - return new VertxMetrics() { - @Override - public HttpServerMetrics createHttpServerMetrics(final HttpServerOptions options, - final SocketAddress localAddress) { - return new OpenTelemetryHttpServerMetrics(); - } - }; + return new OpenTelemetryHttpServerMetrics(); } public static class OpenTelemetryHttpServerMetrics - implements HttpServerMetrics { + implements HttpServerMetrics, + VertxMetrics, ExtendedQuarkusVertxHttpMetrics { + + @Override + public HttpServerMetrics createHttpServerMetrics(final HttpServerOptions options, + final SocketAddress localAddress) { + return this; + } + @Override public MetricRequest requestBegin(final Object socketMetric, final HttpRequest request) { return MetricRequest.request(request); @@ -48,6 +51,12 @@ public void requestRouted(final MetricRequest requestMetric, final String route) } } + @Override + public ConnectionTracker getHttpConnectionTracker() { + // To be implemented if we decide to instrument with OpenTelemetry. See VertxMeterBinderAdapter for an example. + return ExtendedQuarkusVertxHttpMetrics.NOOP_CONNECTION_TRACKER; + } + static final class MetricRequest { private final HttpRequest request;