From e2f8e1aa73c6622de3d3a381729366611f14ae55 Mon Sep 17 00:00:00 2001 From: hiteshkhatri97 Date: Wed, 25 Oct 2023 01:07:37 +0530 Subject: [PATCH] Changes to support jaeger remote sampler --- .../OpenTelemetryLegacyConfigurationTest.java | 2 +- .../config/runtime/TracesRuntimeConfig.java | 2 +- .../opentelemetry-jaeger-remote/pom.xml | 183 ++++++++++++++++++ ...ure.spi.traces.ConfigurableSamplerProvider | 1 + ...pi.traces.ConfigurableSpanExporterProvider | 1 + .../src/main/resources/application.properties | 7 + .../it/opentracing/OTelJaegerRemoteIT.java | 7 + .../it/opentracing/OTelJaegerRemoteTest.java | 131 +++++++++++++ 8 files changed, 332 insertions(+), 2 deletions(-) create mode 100644 integration-tests/opentelemetry-jaeger-remote/pom.xml create mode 100644 integration-tests/opentelemetry-jaeger-remote/src/main/resources/META-INF.services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider create mode 100644 integration-tests/opentelemetry-jaeger-remote/src/main/resources/META-INF.services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider create mode 100644 integration-tests/opentelemetry-jaeger-remote/src/main/resources/application.properties create mode 100644 integration-tests/opentelemetry-jaeger-remote/src/test/java/io/quarkus/it/opentracing/OTelJaegerRemoteIT.java create mode 100644 integration-tests/opentelemetry-jaeger-remote/src/test/java/io/quarkus/it/opentracing/OTelJaegerRemoteTest.java diff --git a/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/OpenTelemetryLegacyConfigurationTest.java b/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/OpenTelemetryLegacyConfigurationTest.java index 775b2157341ef..3067e5df896b1 100644 --- a/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/OpenTelemetryLegacyConfigurationTest.java +++ b/extensions/opentelemetry/deployment/src/test/java/io/quarkus/opentelemetry/deployment/OpenTelemetryLegacyConfigurationTest.java @@ -57,7 +57,7 @@ void config() { assertEquals(TRUE, oTelRuntimeConfig.traces().includeStaticResources()); assertEquals("always_off", oTelBuildConfig.traces().sampler()); assertTrue(oTelRuntimeConfig.traces().samplerArg().isPresent()); - assertEquals(2.0d, oTelRuntimeConfig.traces().samplerArg().get()); + assertEquals("2.0d", oTelRuntimeConfig.traces().samplerArg().get()); assertEquals(FALSE, otlpExporterBuildConfig.enabled()); assertTrue(otlpExporterRuntimeConfig.traces().legacyEndpoint().isPresent()); assertTrue(otlpExporterRuntimeConfig.traces().headers().isPresent()); diff --git a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/runtime/TracesRuntimeConfig.java b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/runtime/TracesRuntimeConfig.java index b1dc033c51bd2..87129f9ba6f00 100644 --- a/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/runtime/TracesRuntimeConfig.java +++ b/extensions/opentelemetry/runtime/src/main/java/io/quarkus/opentelemetry/runtime/config/runtime/TracesRuntimeConfig.java @@ -46,5 +46,5 @@ public interface TracesRuntimeConfig { */ @WithName("sampler.arg") @WithDefault("1.0d") - Optional samplerArg(); + Optional samplerArg(); } diff --git a/integration-tests/opentelemetry-jaeger-remote/pom.xml b/integration-tests/opentelemetry-jaeger-remote/pom.xml new file mode 100644 index 0000000000000..7e4bac37bbb73 --- /dev/null +++ b/integration-tests/opentelemetry-jaeger-remote/pom.xml @@ -0,0 +1,183 @@ + + + + quarkus-integration-tests-parent + io.quarkus + 999-SNAPSHOT + + 4.0.0 + quarkus-integration-test-opentelemetry-jaeger-remote + Quarkus - Integration Tests - Opentelemetry - Jaeger - Remote + + + 2.1.1 + + + + + io.quarkus + quarkus-opentelemetry + + + + + io.quarkus + quarkus-resteasy-reactive-jackson + + + + + io.quarkus + quarkus-rest-client-reactive-jackson + + + + + io.quarkus + quarkus-junit5 + test + + + io.rest-assured + rest-assured + test + + + org.awaitility + awaitility + test + + + org.assertj + assertj-core + test + + + com.fasterxml.jackson.jr + jackson-jr-stree + test + + + com.github.docker-java + docker-java + test + + + org.checkerframework + checker-qual + + + com.sun.activation + jakarta.activation + + + org.slf4j + jcl-over-slf4j + + + + + com.github.docker-java + docker-java-transport-zerodep + test + + + + io.quarkus + quarkus-opentelemetry-deployment + ${project.version} + pom + test + + + * + * + + + + + io.quarkus + quarkus-rest-client-reactive-jackson-deployment + ${project.version} + pom + test + + + * + * + + + + + io.quarkus + quarkus-resteasy-reactive-jackson-deployment + ${project.version} + pom + test + + + * + * + + + + + io.opentelemetry + opentelemetry-sdk-extension-jaeger-remote-sampler + runtime + + + io.opentelemetry + opentelemetry-exporter-jaeger + runtime + + + + + + + src/main/resources + true + + + + + io.quarkus + quarkus-maven-plugin + + + + build + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + + + + native-image + + + native + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + + + + diff --git a/integration-tests/opentelemetry-jaeger-remote/src/main/resources/META-INF.services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider b/integration-tests/opentelemetry-jaeger-remote/src/main/resources/META-INF.services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider new file mode 100644 index 0000000000000..fc64e3bc91469 --- /dev/null +++ b/integration-tests/opentelemetry-jaeger-remote/src/main/resources/META-INF.services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider @@ -0,0 +1 @@ +io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSamplerProvider diff --git a/integration-tests/opentelemetry-jaeger-remote/src/main/resources/META-INF.services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider b/integration-tests/opentelemetry-jaeger-remote/src/main/resources/META-INF.services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider new file mode 100644 index 0000000000000..4c94f1676f81c --- /dev/null +++ b/integration-tests/opentelemetry-jaeger-remote/src/main/resources/META-INF.services/io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider @@ -0,0 +1 @@ +io.opentelemetry.exporter.jaeger.internal.JaegerGrpcSpanExporterProvider diff --git a/integration-tests/opentelemetry-jaeger-remote/src/main/resources/application.properties b/integration-tests/opentelemetry-jaeger-remote/src/main/resources/application.properties new file mode 100644 index 0000000000000..b33889cd15684 --- /dev/null +++ b/integration-tests/opentelemetry-jaeger-remote/src/main/resources/application.properties @@ -0,0 +1,7 @@ +# Setting these for tests explicitly. Not required in normal application +quarkus.application.name=opentelemetry-integration-test-jeager-remote +quarkus.application.version=999-SNAPSHOT + +quarkus.otel.traces.sampler=jaeger_remote +quarkus.otel.traces.sampler.arg=endpoint=http://localhost:14250,pollingInterval=5000,initialSamplingRate=0.9 +quarkus.otel.traces.exporter=jaeger diff --git a/integration-tests/opentelemetry-jaeger-remote/src/test/java/io/quarkus/it/opentracing/OTelJaegerRemoteIT.java b/integration-tests/opentelemetry-jaeger-remote/src/test/java/io/quarkus/it/opentracing/OTelJaegerRemoteIT.java new file mode 100644 index 0000000000000..b02207ba60937 --- /dev/null +++ b/integration-tests/opentelemetry-jaeger-remote/src/test/java/io/quarkus/it/opentracing/OTelJaegerRemoteIT.java @@ -0,0 +1,7 @@ +package io.quarkus.it.opentracing; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +public class OTelJaegerRemoteIT extends OTelJaegerRemoteTest { +} diff --git a/integration-tests/opentelemetry-jaeger-remote/src/test/java/io/quarkus/it/opentracing/OTelJaegerRemoteTest.java b/integration-tests/opentelemetry-jaeger-remote/src/test/java/io/quarkus/it/opentracing/OTelJaegerRemoteTest.java new file mode 100644 index 0000000000000..0adb8d433ec3d --- /dev/null +++ b/integration-tests/opentelemetry-jaeger-remote/src/test/java/io/quarkus/it/opentracing/OTelJaegerRemoteTest.java @@ -0,0 +1,131 @@ +package io.quarkus.it.opentracing; + +import static com.github.dockerjava.api.model.HostConfig.newHostConfig; + +import java.time.Duration; + +import jakarta.inject.Inject; + +import org.awaitility.Awaitility; +import org.eclipse.microprofile.config.ConfigProvider; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.core.TreeNode; +import com.fasterxml.jackson.jr.ob.JSON; +import com.fasterxml.jackson.jr.stree.JacksonJrsTreeCodec; +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.model.ExposedPort; +import com.github.dockerjava.api.model.Ports; +import com.github.dockerjava.core.DefaultDockerClientConfig; +import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.core.DockerClientImpl; +import com.github.dockerjava.transport.DockerHttpClient; +import com.github.dockerjava.zerodep.ZerodepDockerHttpClient; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; +import io.quarkus.test.junit.QuarkusTest; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +@QuarkusTest +public class OTelJaegerRemoteTest { + + private static final OkHttpClient client = new OkHttpClient(); + private static final int QUERY_PORT = 16686; + private static final int COLLECTOR_PORT = 14250; + private static final int HEALTH_PORT = 14269; + private static final String JAEGER_URL = "http://localhost"; + @Inject + OpenTelemetry openTelemetry; + private static final DockerClient dockerClient; + + static { + DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder().build(); + DockerHttpClient httpClient = new ZerodepDockerHttpClient.Builder() + .dockerHost(config.getDockerHost()) + .sslConfig(config.getSSLConfig()) + .build(); + dockerClient = DockerClientImpl.getInstance(config, httpClient); + if (dockerClient.listContainersCmd().exec().stream() + .noneMatch(container -> container.getNames()[0].equals("/jaeger"))) { + ExposedPort queryPort = ExposedPort.tcp(QUERY_PORT); + ExposedPort collectorPort = ExposedPort.tcp(COLLECTOR_PORT); + ExposedPort hostPort = ExposedPort.tcp(HEALTH_PORT); + Ports portBindings = new Ports(); + portBindings.bind(queryPort, Ports.Binding.bindPort(QUERY_PORT)); + portBindings.bind(collectorPort, Ports.Binding.bindPort(COLLECTOR_PORT)); + portBindings.bind(hostPort, Ports.Binding.bindPort(HEALTH_PORT)); + CreateContainerResponse container = dockerClient + .createContainerCmd("ghcr.io/open-telemetry/opentelemetry-java/jaeger:1.32") + .withExposedPorts(queryPort, collectorPort, hostPort) + .withHostConfig(newHostConfig().withPortBindings(portBindings)) + .withName("jaeger") + .exec(); + dockerClient.startContainerCmd(container.getId()).exec(); + } + } + + @AfterAll + static void teardown() { + dockerClient.listContainersCmd().exec() + .forEach(container -> { + dockerClient.stopContainerCmd(container.getId()).exec(); + dockerClient.removeContainerCmd(container.getId()).exec(); + }); + } + + @Test + void testJaegerRemoteIntegration() { + createTestSpan(openTelemetry); + Awaitility.await() + .atMost(Duration.ofSeconds(30)) + .until(OTelJaegerRemoteTest::assertJaegerHaveTrace); + } + + private void createTestSpan(OpenTelemetry openTelemetry) { + Span span = openTelemetry.getTracer(getClass().getCanonicalName()).spanBuilder("Test span").startSpan(); + try (Scope scope = span.makeCurrent()) { + span.addEvent("Test event"); + } catch (Throwable t) { + span.recordException(t); + throw t; + } finally { + span.end(); + } + } + + private static boolean assertJaegerHaveTrace() { + try { + + String serviceName = ConfigProvider.getConfig().getConfigValue("quarkus.application.name").getValue(); + String url = String.format( + "%s/api/traces?service=%s", + String.format(JAEGER_URL + ":%d", QUERY_PORT), + serviceName); + + Request request = new Request.Builder() + .url(url) + .header("Content-Type", "application/json") + .header("Accept", "application/json") + .build(); + + TreeNode json; + try (Response response = client.newCall(request).execute()) { + json = JSON.builder() + .treeCodec(new JacksonJrsTreeCodec()) + .build() + .treeFrom(response.body().byteStream()); + } + + return json.get("data").get(0).get("traceID") != null; + } catch (Exception e) { + return false; + } + } + +}