diff --git a/devtools/bom-descriptor-json/pom.xml b/devtools/bom-descriptor-json/pom.xml index afe2b7aff156b..f54a1277606bb 100644 --- a/devtools/bom-descriptor-json/pom.xml +++ b/devtools/bom-descriptor-json/pom.xml @@ -2008,6 +2008,19 @@ + + io.quarkus + quarkus-resteasy-observability + ${project.version} + pom + test + + + * + * + + + io.quarkus quarkus-resteasy-qute diff --git a/docs/pom.xml b/docs/pom.xml index 9e67166360b6f..b42c6c23ab6da 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -1969,6 +1969,19 @@ + + io.quarkus + quarkus-resteasy-observability-deployment + ${project.version} + pom + test + + + * + * + + + io.quarkus quarkus-resteasy-qute-deployment diff --git a/extensions/micrometer/deployment/pom.xml b/extensions/micrometer/deployment/pom.xml index 876b4c21d78ba..42e689ce8bca4 100644 --- a/extensions/micrometer/deployment/pom.xml +++ b/extensions/micrometer/deployment/pom.xml @@ -119,7 +119,7 @@ maven-surefire-plugin - DEBUG + INFO diff --git a/extensions/micrometer/deployment/src/test/resources/test-logging.properties b/extensions/micrometer/deployment/src/test/resources/test-logging.properties index 7a2ecfd97109f..6eed6ab2596da 100644 --- a/extensions/micrometer/deployment/src/test/resources/test-logging.properties +++ b/extensions/micrometer/deployment/src/test/resources/test-logging.properties @@ -1,5 +1,4 @@ -quarkus.log.category."io.quarkus.micrometer".level=DEBUG -quarkus.log.category."io.quarkus.resteasy.observability".level=DEBUG +#quarkus.log.category."io.quarkus.micrometer".level=DEBUG quarkus.log.category."io.quarkus.bootstrap".level=INFO -quarkus.log.category."io.quarkus.arc".level=DEBUG +#quarkus.log.category."io.quarkus.arc".level=DEBUG quarkus.log.category."io.netty".level=INFO diff --git a/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/vertx/VertxTracingAdapter.java b/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/vertx/VertxTracingAdapter.java index e1b41259a08da..4398119bbde6c 100644 --- a/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/vertx/VertxTracingAdapter.java +++ b/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/vertx/VertxTracingAdapter.java @@ -5,6 +5,7 @@ import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_FLAVOR; import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_HOST; import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_METHOD; +import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_ROUTE; import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_SCHEME; import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_STATUS_CODE; import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_TARGET; @@ -142,6 +143,13 @@ public void sendResponse( return; } + // Update Span name if parameterized path present + String pathTemplate = context.getLocal("UrlPathTemplate"); + if (pathTemplate != null && !pathTemplate.isEmpty()) { + span.updateName(pathTemplate.substring(1)); + span.setAttribute(HTTP_ROUTE, pathTemplate); + } + ((ContextInternal) context).dispatch(() -> { if (failure != null) { span.setStatus(StatusCode.ERROR); diff --git a/extensions/resteasy-classic/resteasy-common/deployment/pom.xml b/extensions/resteasy-classic/resteasy-common/deployment/pom.xml index adaa64e8f0b3a..b576be2661e1e 100644 --- a/extensions/resteasy-classic/resteasy-common/deployment/pom.xml +++ b/extensions/resteasy-classic/resteasy-common/deployment/pom.xml @@ -29,6 +29,10 @@ io.quarkus quarkus-arc-deployment + + io.quarkus + quarkus-resteasy-observability-deployment + diff --git a/extensions/resteasy-classic/resteasy-common/runtime/pom.xml b/extensions/resteasy-classic/resteasy-common/runtime/pom.xml index 01dcc526a8260..8f8c76dfecc74 100644 --- a/extensions/resteasy-classic/resteasy-common/runtime/pom.xml +++ b/extensions/resteasy-classic/resteasy-common/runtime/pom.xml @@ -30,6 +30,10 @@ io.quarkus quarkus-arc + + io.quarkus + quarkus-resteasy-observability + com.sun.activation jakarta.activation diff --git a/extensions/resteasy-classic/resteasy-server-common/deployment/pom.xml b/extensions/resteasy-classic/resteasy-server-common/deployment/pom.xml index 88a865a8fa738..b1940b0c73202 100644 --- a/extensions/resteasy-classic/resteasy-server-common/deployment/pom.xml +++ b/extensions/resteasy-classic/resteasy-server-common/deployment/pom.xml @@ -37,10 +37,6 @@ io.quarkus quarkus-undertow-spi - - io.quarkus - quarkus-resteasy-observability-spi - diff --git a/extensions/resteasy-classic/resteasy-server-common/deployment/src/main/java/io/quarkus/resteasy/server/common/deployment/ResteasyServerCommonProcessor.java b/extensions/resteasy-classic/resteasy-server-common/deployment/src/main/java/io/quarkus/resteasy/server/common/deployment/ResteasyServerCommonProcessor.java index f30f125f94c9b..0ef2ebd8530d4 100755 --- a/extensions/resteasy-classic/resteasy-server-common/deployment/src/main/java/io/quarkus/resteasy/server/common/deployment/ResteasyServerCommonProcessor.java +++ b/extensions/resteasy-classic/resteasy-server-common/deployment/src/main/java/io/quarkus/resteasy/server/common/deployment/ResteasyServerCommonProcessor.java @@ -70,7 +70,7 @@ import io.quarkus.resteasy.common.deployment.ResteasyCommonProcessor.ResteasyCommonConfig; import io.quarkus.resteasy.common.runtime.QuarkusInjectorFactory; import io.quarkus.resteasy.common.spi.ResteasyDotNames; -import io.quarkus.resteasy.observability.spi.RestApplicationPathBuildItem; +import io.quarkus.resteasy.observability.deployment.RestApplicationPathBuildItem; import io.quarkus.resteasy.server.common.runtime.QuarkusResteasyDeployment; import io.quarkus.resteasy.server.common.spi.AdditionalJaxRsResourceDefiningAnnotationBuildItem; import io.quarkus.resteasy.server.common.spi.AdditionalJaxRsResourceMethodAnnotationsBuildItem; diff --git a/extensions/resteasy-observability/deployment/pom.xml b/extensions/resteasy-observability/deployment/pom.xml index 24917d8283563..e5c0349b4297d 100644 --- a/extensions/resteasy-observability/deployment/pom.xml +++ b/extensions/resteasy-observability/deployment/pom.xml @@ -25,11 +25,11 @@ io.quarkus - quarkus-resteasy-observability + quarkus-vertx-http-deployment io.quarkus - quarkus-resteasy-observability-spi + quarkus-resteasy-observability diff --git a/extensions/resteasy-observability/spi/src/main/java/io/quarkus/resteasy/observability/spi/RestApplicationPathBuildItem.java b/extensions/resteasy-observability/deployment/src/main/java/io/quarkus/resteasy/observability/deployment/RestApplicationPathBuildItem.java similarity index 91% rename from extensions/resteasy-observability/spi/src/main/java/io/quarkus/resteasy/observability/spi/RestApplicationPathBuildItem.java rename to extensions/resteasy-observability/deployment/src/main/java/io/quarkus/resteasy/observability/deployment/RestApplicationPathBuildItem.java index 43a2c19b5ac2b..c99ee1d1b6e65 100644 --- a/extensions/resteasy-observability/spi/src/main/java/io/quarkus/resteasy/observability/spi/RestApplicationPathBuildItem.java +++ b/extensions/resteasy-observability/deployment/src/main/java/io/quarkus/resteasy/observability/deployment/RestApplicationPathBuildItem.java @@ -1,4 +1,4 @@ -package io.quarkus.resteasy.observability.spi; +package io.quarkus.resteasy.observability.deployment; import io.quarkus.builder.item.SimpleBuildItem; diff --git a/extensions/resteasy-observability/deployment/src/main/java/io/quarkus/resteasy/observability/runtime/deployment/RestPathAnnotationProcessor.java b/extensions/resteasy-observability/deployment/src/main/java/io/quarkus/resteasy/observability/deployment/RestPathAnnotationProcessor.java similarity index 74% rename from extensions/resteasy-observability/deployment/src/main/java/io/quarkus/resteasy/observability/runtime/deployment/RestPathAnnotationProcessor.java rename to extensions/resteasy-observability/deployment/src/main/java/io/quarkus/resteasy/observability/deployment/RestPathAnnotationProcessor.java index b1f2e05f3989a..a6c3763137ed0 100644 --- a/extensions/resteasy-observability/deployment/src/main/java/io/quarkus/resteasy/observability/runtime/deployment/RestPathAnnotationProcessor.java +++ b/extensions/resteasy-observability/deployment/src/main/java/io/quarkus/resteasy/observability/deployment/RestPathAnnotationProcessor.java @@ -1,4 +1,4 @@ -package io.quarkus.resteasy.observability.runtime.deployment; +package io.quarkus.resteasy.observability.deployment; import java.util.Optional; import java.util.regex.Pattern; @@ -13,10 +13,14 @@ import io.quarkus.arc.deployment.AdditionalBeanBuildItem; import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem; import io.quarkus.arc.processor.AnnotationsTransformer; +import io.quarkus.deployment.Capabilities; +import io.quarkus.deployment.Capability; +import io.quarkus.deployment.annotations.BuildProducer; import io.quarkus.deployment.annotations.BuildStep; +import io.quarkus.deployment.metrics.MetricsCapabilityBuildItem; import io.quarkus.resteasy.observability.runtime.QuarkusRestPathTemplate; import io.quarkus.resteasy.observability.runtime.QuarkusRestPathTemplateInterceptor; -import io.quarkus.resteasy.observability.spi.RestApplicationPathBuildItem; +import io.quarkus.runtime.metrics.MetricsFactory; public class RestPathAnnotationProcessor { @@ -29,19 +33,30 @@ public class RestPathAnnotationProcessor { public static final Pattern MULTIPLE_SLASH_PATTERN = Pattern.compile("//+"); @BuildStep() - AdditionalBeanBuildItem registerBeanClasses() { + AdditionalBeanBuildItem registerBeanClasses(Capabilities capabilities, + Optional metricsCapability) { + if (notRequired(capabilities, metricsCapability)) { + return null; + } + return AdditionalBeanBuildItem.builder() - .setUnremovable() .addBeanClass(TEMPLATE_PATH.toString()) .addBeanClass(TEMPLATE_PATH_INTERCEPTOR.toString()) .build(); } @BuildStep - AnnotationsTransformerBuildItem findRestPaths( + void findRestPaths( + Capabilities capabilities, Optional metricsCapability, + BuildProducer transformers, Optional restApplicationPath) { - return new AnnotationsTransformerBuildItem(new AnnotationsTransformer() { + if (notRequired(capabilities, metricsCapability)) { + // Don't create transformer if Micrometer or OpenTelemetry are not present + return; + } + + transformers.produce(new AnnotationsTransformerBuildItem(new AnnotationsTransformer() { @Override public boolean appliesTo(AnnotationTarget.Kind kind) { return kind == AnnotationTarget.Kind.METHOD; @@ -78,7 +93,7 @@ public void transform(TransformationContext ctx) { .add(TEMPLATE_PATH, AnnotationValue.createStringValue("value", templatePath)) .done(); } - }); + })); } String slashify(String path) { @@ -97,4 +112,10 @@ String slashify(String path) { } return '/' + path; } + + private boolean notRequired(Capabilities capabilities, + Optional metricsCapability) { + return !(metricsCapability.isPresent() && metricsCapability.get().metricsSupported(MetricsFactory.MICROMETER)) + && capabilities.isMissing(Capability.OPENTELEMETRY_TRACER); + } } diff --git a/extensions/resteasy-observability/pom.xml b/extensions/resteasy-observability/pom.xml index 504fc914a0ba8..de423271d7b61 100644 --- a/extensions/resteasy-observability/pom.xml +++ b/extensions/resteasy-observability/pom.xml @@ -17,7 +17,6 @@ pom - spi runtime deployment diff --git a/extensions/resteasy-observability/runtime/pom.xml b/extensions/resteasy-observability/runtime/pom.xml index 72dfda4a6db08..0a6f5c40e0878 100644 --- a/extensions/resteasy-observability/runtime/pom.xml +++ b/extensions/resteasy-observability/runtime/pom.xml @@ -25,6 +25,10 @@ io.quarkus quarkus-arc + + io.quarkus + quarkus-vertx-http + diff --git a/extensions/resteasy-observability/runtime/src/main/java/io/quarkus/resteasy/observability/runtime/QuarkusRestPathTemplate.java b/extensions/resteasy-observability/runtime/src/main/java/io/quarkus/resteasy/observability/runtime/QuarkusRestPathTemplate.java index f234a7e394852..193907ea044df 100644 --- a/extensions/resteasy-observability/runtime/src/main/java/io/quarkus/resteasy/observability/runtime/QuarkusRestPathTemplate.java +++ b/extensions/resteasy-observability/runtime/src/main/java/io/quarkus/resteasy/observability/runtime/QuarkusRestPathTemplate.java @@ -6,6 +6,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import javax.enterprise.util.Nonbinding; import javax.interceptor.InterceptorBinding; @Inherited @@ -13,5 +14,6 @@ @Target({ ElementType.ANNOTATION_TYPE, ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface QuarkusRestPathTemplate { + @Nonbinding String value() default ""; } diff --git a/extensions/resteasy-observability/runtime/src/main/java/io/quarkus/resteasy/observability/runtime/QuarkusRestPathTemplateInterceptor.java b/extensions/resteasy-observability/runtime/src/main/java/io/quarkus/resteasy/observability/runtime/QuarkusRestPathTemplateInterceptor.java index ad689daa22a3c..0304b5c329d12 100644 --- a/extensions/resteasy-observability/runtime/src/main/java/io/quarkus/resteasy/observability/runtime/QuarkusRestPathTemplateInterceptor.java +++ b/extensions/resteasy-observability/runtime/src/main/java/io/quarkus/resteasy/observability/runtime/QuarkusRestPathTemplateInterceptor.java @@ -11,6 +11,7 @@ import org.jboss.logging.Logger; import io.quarkus.arc.ArcInvocationContext; +import io.vertx.core.Vertx; @SuppressWarnings("unused") @QuarkusRestPathTemplate @@ -22,21 +23,22 @@ public class QuarkusRestPathTemplateInterceptor { @AroundInvoke Object restMethodInvoke(InvocationContext context) throws Exception { QuarkusRestPathTemplate annotation = getAnnotation(context); - log.infof("QuarkusRestPathTemplate annotated method invoked with %s", annotation); + log.debugf("QuarkusRestPathTemplate annotated method invoked with %s", annotation); if (annotation != null) { - + Vertx.currentContext().putLocal("UrlPathTemplate", annotation.value()); } return context.proceed(); } + @SuppressWarnings("unchecked") static QuarkusRestPathTemplate getAnnotation(InvocationContext context) { Set annotations = (Set) context.getContextData() .get(ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS); for (Annotation a : annotations) { - if (QuarkusRestPathTemplate.class.isInstance(a)) { - return QuarkusRestPathTemplate.class.cast(a); + if (a instanceof QuarkusRestPathTemplate) { + return (QuarkusRestPathTemplate) a; } } return null; diff --git a/extensions/resteasy-observability/spi/pom.xml b/extensions/resteasy-observability/spi/pom.xml deleted file mode 100644 index 9b3c8169aec85..0000000000000 --- a/extensions/resteasy-observability/spi/pom.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - 4.0.0 - - - quarkus-resteasy-observability-parent - io.quarkus - 999-SNAPSHOT - ../pom.xml - - - quarkus-resteasy-observability-spi - Telemetry SPI for RESTEasy workloads - - - - io.quarkus - quarkus-core-deployment - - - - \ No newline at end of file diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/deployment/pom.xml b/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/deployment/pom.xml index dd4841d3ac674..75c54eebeac40 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/deployment/pom.xml +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/deployment/pom.xml @@ -45,6 +45,10 @@ io.quarkus quarkus-jsonp-deployment + + io.quarkus + quarkus-resteasy-observability-deployment + diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/runtime/pom.xml b/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/runtime/pom.xml index abe382006375c..dc0a2b576a1ad 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/runtime/pom.xml +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive-common/runtime/pom.xml @@ -34,6 +34,10 @@ io.quarkus quarkus-jsonp + + io.quarkus + quarkus-resteasy-observability + org.junit.jupiter junit-jupiter diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/pom.xml b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/pom.xml index 79e3186aa06f9..a4a896e2a2f50 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/pom.xml +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/pom.xml @@ -49,10 +49,6 @@ io.quarkus quarkus-resteasy-reactive-common-deployment - - io.quarkus - quarkus-resteasy-observability-spi - io.quarkus quarkus-security-deployment diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java index fad7a1c03cbce..6e38445c08172 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java @@ -90,7 +90,7 @@ import io.quarkus.gizmo.ClassCreator; import io.quarkus.gizmo.MethodCreator; import io.quarkus.netty.deployment.MinNettyAllocatorMaxOrderBuildItem; -import io.quarkus.resteasy.observability.spi.RestApplicationPathBuildItem; +import io.quarkus.resteasy.observability.deployment.RestApplicationPathBuildItem; import io.quarkus.resteasy.reactive.common.deployment.ApplicationResultBuildItem; import io.quarkus.resteasy.reactive.common.deployment.FactoryUtils; import io.quarkus.resteasy.reactive.common.deployment.QuarkusFactoryCreator; diff --git a/integration-tests/opentelemetry/src/test/java/io/quarkus/it/opentelemetry/OpenTelemetryTestCase.java b/integration-tests/opentelemetry/src/test/java/io/quarkus/it/opentelemetry/OpenTelemetryTestCase.java index dc78d7e0fb30e..e856f19ae21be 100644 --- a/integration-tests/opentelemetry/src/test/java/io/quarkus/it/opentelemetry/OpenTelemetryTestCase.java +++ b/integration-tests/opentelemetry/src/test/java/io/quarkus/it/opentelemetry/OpenTelemetryTestCase.java @@ -83,8 +83,6 @@ void testResourceTracing() { Assertions.assertEquals("/direct", spanData.get("attr_http.target")); Assertions.assertEquals(directUrl.getAuthority(), spanData.get("attr_http.host")); Assertions.assertEquals("http", spanData.get("attr_http.scheme")); - //TODO Waiting on a templatized route to be available - // Assertions.assertEquals("/direct", spanData.get("attr_http.route")); Assertions.assertEquals("200", spanData.get("attr_http.status_code")); Assertions.assertNotNull(spanData.get("attr_http.client_ip")); Assertions.assertNotNull(spanData.get("attr_http.user_agent")); @@ -122,8 +120,6 @@ void testChainedResourceTracing() { Assertions.assertEquals("/chained", spanData.get("attr_http.target")); Assertions.assertEquals(chainedUrl.getAuthority(), spanData.get("attr_http.host")); Assertions.assertEquals("http", spanData.get("attr_http.scheme")); - //TODO Waiting on a templatized route to be available - // Assertions.assertEquals("/chained", spanData.get("attr_http.route")); Assertions.assertEquals("200", spanData.get("attr_http.status_code")); Assertions.assertNotNull(spanData.get("attr_http.client_ip")); Assertions.assertNotNull(spanData.get("attr_http.user_agent")); @@ -177,8 +173,6 @@ void testTracingWithParentHeaders() { Assertions.assertEquals("/direct", spanData.get("attr_http.target")); Assertions.assertEquals(directUrl.getAuthority(), spanData.get("attr_http.host")); Assertions.assertEquals("http", spanData.get("attr_http.scheme")); - //TODO Waiting on a templatized route to be available - // Assertions.assertEquals("/direct", spanData.get("attr_http.route")); Assertions.assertEquals("200", spanData.get("attr_http.status_code")); Assertions.assertNotNull(spanData.get("attr_http.client_ip")); Assertions.assertNotNull(spanData.get("attr_http.user_agent")); @@ -216,8 +210,6 @@ void testDeepPathNaming() { Assertions.assertEquals("/deep/path", spanData.get("attr_http.target")); Assertions.assertEquals(deepPathUrl.getAuthority(), spanData.get("attr_http.host")); Assertions.assertEquals("http", spanData.get("attr_http.scheme")); - //TODO Waiting on a templatized route to be available - // Assertions.assertEquals("/deep/path", spanData.get("attr_http.route")); Assertions.assertEquals("200", spanData.get("attr_http.status_code")); Assertions.assertNotNull(spanData.get("attr_http.client_ip")); Assertions.assertNotNull(spanData.get("attr_http.user_agent")); @@ -241,8 +233,7 @@ void testPathParameter() { verifyResource(spanData); - //TODO Need templatized route to verify span name is "param/{paramId}" - Assertions.assertEquals("param/12345", spanData.get("name")); + Assertions.assertEquals("param/{paramId}", spanData.get("name")); Assertions.assertEquals(SpanKind.SERVER.toString(), spanData.get("kind")); Assertions.assertTrue((Boolean) spanData.get("ended")); @@ -256,8 +247,7 @@ void testPathParameter() { Assertions.assertEquals("/param/12345", spanData.get("attr_http.target")); Assertions.assertEquals(pathParamUrl.getAuthority(), spanData.get("attr_http.host")); Assertions.assertEquals("http", spanData.get("attr_http.scheme")); - //TODO Waiting on a templatized route to be available - // Assertions.assertEquals("/param/{paramId}", spanData.get("attr_http.route")); + Assertions.assertEquals("/param/{paramId}", spanData.get("attr_http.route")); Assertions.assertEquals("200", spanData.get("attr_http.status_code")); Assertions.assertNotNull(spanData.get("attr_http.client_ip")); Assertions.assertNotNull(spanData.get("attr_http.user_agent"));