From 78d30674b331b7d619b78a875921899dce15771e Mon Sep 17 00:00:00 2001 From: mun711 Date: Sat, 25 Jun 2022 23:49:57 +0300 Subject: [PATCH] Support exclusion of non-application URIs if custom Sampler is used --- .../OpenTelemetryCustomSamplerBeanTest.java | 93 +++++++++++++++++++ .../runtime/tracing/TracerRecorder.java | 28 ++---- .../runtime/tracing/TracerRuntimeConfig.java | 6 -- .../runtime/tracing/TracerUtil.java | 12 ++- 4 files changed, 111 insertions(+), 28 deletions(-) create mode 100644 extensions/opentelemetry/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/OpenTelemetryCustomSamplerBeanTest.java diff --git a/extensions/opentelemetry/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/OpenTelemetryCustomSamplerBeanTest.java b/extensions/opentelemetry/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/OpenTelemetryCustomSamplerBeanTest.java new file mode 100644 index 0000000000000..f2ad5ddd4ba26 --- /dev/null +++ b/extensions/opentelemetry/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/OpenTelemetryCustomSamplerBeanTest.java @@ -0,0 +1,93 @@ +package io.quarkus.opentelemetry.deployment; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.stringContainsInOrder; + +import java.lang.reflect.InvocationTargetException; +import java.util.List; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Produces; +import javax.inject.Inject; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.SpanKind; +import io.opentelemetry.context.Context; +import io.opentelemetry.sdk.trace.data.LinkData; +import io.opentelemetry.sdk.trace.samplers.Sampler; +import io.opentelemetry.sdk.trace.samplers.SamplingResult; +import io.quarkus.test.QuarkusUnitTest; +import io.restassured.RestAssured; + +public class OpenTelemetryCustomSamplerBeanTest { + + private static final String TEST_SAMPLER = "testSampler"; + + @RegisterExtension + static final QuarkusUnitTest unitTest = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addClass(TracerRouter.class) + .addClass(TestSpanExporter.class) + .addClass(TestUtil.class)); + + @Inject + OpenTelemetry openTelemetry; + + @Inject + TestSpanExporter testSpanExporter; + + @Test + void testHealthEndpointNotTraced() { + RestAssured.when().get("/q/health").then() + .statusCode(200) + .body(containsString("\"status\": \"UP\"")); + + RestAssured.when().get("/q/health/live").then() + .statusCode(200) + .body(containsString("\"status\": \"UP\"")); + + RestAssured.when().get("/q/health/ready").then() + .statusCode(200) + .body(containsString("\"status\": \"UP\"")); + + RestAssured.when().get("/tracer").then() + .statusCode(200) + .body(is("Hello Tracer!")); + + testSpanExporter.assertSpanCount(2); + } + + @Test + void test() throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException { + Sampler sampler = TestUtil.getSampler(openTelemetry); + + assertThat(sampler.getDescription(), stringContainsInOrder(TEST_SAMPLER)); + } + + @ApplicationScoped + public static class OtelConfiguration { + + @Produces + public Sampler sampler() { + return new Sampler() { + @Override + public SamplingResult shouldSample(Context context, String s, String s1, SpanKind spanKind, + Attributes attributes, + List list) { + return SamplingResult.recordAndSample(); + } + + @Override + public String getDescription() { + return TEST_SAMPLER; + } + }; + } + } +} diff --git a/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/TracerRecorder.java b/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/TracerRecorder.java index fece75003a48d..8999089073115 100644 --- a/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/TracerRecorder.java +++ b/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/TracerRecorder.java @@ -2,7 +2,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Optional; import java.util.function.Consumer; import javax.enterprise.inject.Any; @@ -140,25 +139,14 @@ public void setupSampler( List dropStaticResources) { LateBoundSampler lateBoundSampler = CDI.current().select(LateBoundSampler.class, Any.Literal.INSTANCE).get(); - Optional samplerBean = CDI.current() - .select(Sampler.class, Any.Literal.INSTANCE) - .stream() - .filter(o -> !(o instanceof LateBoundSampler)) - .findFirst(); - - // Define Sampler using bean if present - if (samplerBean.isPresent()) { - lateBoundSampler.setSamplerDelegate(samplerBean.get()); - } else { - List dropNames = new ArrayList<>(); - if (config.suppressNonApplicationUris) { - dropNames.addAll(dropNonApplicationUris); - } - if (!config.includeStaticResources) { - dropNames.addAll(dropStaticResources); - } - // Define Sampler using config - lateBoundSampler.setSamplerDelegate(TracerUtil.mapSampler(config.sampler, dropNames)); + List dropNames = new ArrayList<>(); + if (config.suppressNonApplicationUris) { + dropNames.addAll(dropNonApplicationUris); } + if (!config.includeStaticResources) { + dropNames.addAll(dropStaticResources); + } + Sampler samplerBean = TracerUtil.mapSampler(config.sampler, dropNames); + lateBoundSampler.setSamplerDelegate(samplerBean); } } diff --git a/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/TracerRuntimeConfig.java b/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/TracerRuntimeConfig.java index 82fe315eaa6b7..21955fdcc0cea 100644 --- a/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/TracerRuntimeConfig.java +++ b/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/TracerRuntimeConfig.java @@ -26,9 +26,6 @@ public class TracerRuntimeConfig { * Suppress non-application uris from trace collection. * This will suppress tracing of `/q` endpoints. *

- * Providing a custom {@code io.opentelemetry.sdk.trace.samplers.Sampler} CDI Bean - * will ignore this setting. - *

* Suppressing non-application uris is enabled by default. */ @ConfigItem(defaultValue = "true") @@ -37,9 +34,6 @@ public class TracerRuntimeConfig { /** * Include static resources from trace collection. *

- * Providing a custom {@code io.opentelemetry.sdk.trace.samplers.Sampler} CDI Bean - * will ignore this setting. - *

* Include static resources is disabled by default. */ @ConfigItem(defaultValue = "false") diff --git a/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/TracerUtil.java b/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/TracerUtil.java index 7c575e20f6439..632e649c87a01 100644 --- a/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/TracerUtil.java +++ b/extensions/opentelemetry/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/tracing/TracerUtil.java @@ -3,6 +3,9 @@ import java.util.List; import java.util.Optional; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.spi.CDI; + import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.sdk.resources.Resource; @@ -34,8 +37,13 @@ private static Sampler getBaseSampler(String samplerName, Optional ratio } } - public static Sampler mapSampler(TracerRuntimeConfig.SamplerConfig samplerConfig, List dropNames) { - Sampler sampler = getBaseSampler(samplerConfig.samplerName, samplerConfig.ratio); + public static Sampler mapSampler(TracerRuntimeConfig.SamplerConfig samplerConfig, + List dropNames) { + Sampler sampler = CDI.current() + .select(Sampler.class, Any.Literal.INSTANCE) + .stream() + .filter(o -> !(o instanceof LateBoundSampler)) + .findFirst().orElseGet(() -> getBaseSampler(samplerConfig.samplerName, samplerConfig.ratio)); if (!dropNames.isEmpty()) { sampler = new DropNamesSampler(sampler, dropNames);