Skip to content

Commit

Permalink
Use SPI + Bean
Browse files Browse the repository at this point in the history
  • Loading branch information
luneo7 committed Jun 10, 2021
1 parent a1bbce7 commit 3a4903f
Show file tree
Hide file tree
Showing 16 changed files with 353 additions and 194 deletions.
4 changes: 2 additions & 2 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
<opentracing-jdbc.version>0.2.12</opentracing-jdbc.version>
<opentracing-kafka.version>0.1.15</opentracing-kafka.version>
<opentracing-mongo.version>0.1.5</opentracing-mongo.version>
<opentelemetry.version>1.2.0</opentelemetry.version>
<opentelemetry-alpha.version>1.2.0-alpha</opentelemetry-alpha.version>
<opentelemetry.version>1.3.0</opentelemetry.version>
<opentelemetry-alpha.version>1.3.0-alpha</opentelemetry-alpha.version>
<jaeger.version>1.4.0</jaeger.version>
<quarkus-http.version>4.0.0</quarkus-http.version>
<jboss-servlet-api_4.0_spec.version>1.0.0.Final</jboss-servlet-api_4.0_spec.version>
Expand Down
16 changes: 16 additions & 0 deletions extensions/opentelemetry/opentelemetry/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,22 @@
</exclusion>
</exclusions>
</dependency>

<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-extension-aws</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-extension-aws</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-extension-resources</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
import org.jboss.jandex.IndexView;
import org.jboss.jandex.MethodInfo;

import io.opentelemetry.sdk.trace.IdGenerator;
import io.opentelemetry.sdk.trace.SpanProcessor;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.BeanContainerBuildItem;
import io.quarkus.arc.deployment.UnremovableBeanBuildItem;
Expand All @@ -36,6 +38,8 @@
import io.quarkus.vertx.core.deployment.VertxOptionsConsumerBuildItem;

public class TracerProcessor {
private static final DotName ID_GENERATOR = DotName.createSimple(IdGenerator.class.getName());
private static final DotName SAMPLER = DotName.createSimple(Sampler.class.getName());
private static final DotName SPAN_EXPORTER = DotName.createSimple(SpanExporter.class.getName());
private static final DotName SPAN_PROCESSOR = DotName.createSimple(SpanProcessor.class.getName());

Expand Down Expand Up @@ -69,6 +73,12 @@ UnremovableBeanBuildItem ensureProducersAreRetained(

// Find all known SpanExporters and SpanProcessors
Collection<String> knownClasses = new HashSet<>();
knownClasses.add(ID_GENERATOR.toString());
index.getAllKnownImplementors(ID_GENERATOR)
.forEach(classInfo -> knownClasses.add(classInfo.name().toString()));
knownClasses.add(SAMPLER.toString());
index.getAllKnownImplementors(SAMPLER)
.forEach(classInfo -> knownClasses.add(classInfo.name().toString()));
knownClasses.add(SPAN_EXPORTER.toString());
index.getAllKnownImplementors(SPAN_EXPORTER)
.forEach(classInfo -> knownClasses.add(classInfo.name().toString()));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.quarkus.opentelemetry.deployment;

import static org.hamcrest.Matchers.instanceOf;

import java.lang.reflect.InvocationTargetException;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;

import org.hamcrest.MatcherAssert;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.extension.aws.trace.AwsXrayIdGenerator;
import io.opentelemetry.sdk.trace.IdGenerator;
import io.quarkus.test.QuarkusUnitTest;

public class OpenTelemetryIdGeneratorTest {
@RegisterExtension
static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClass(TestUtil.class));

@Inject
OpenTelemetry openTelemetry;

@Test
void test() throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
IdGenerator idGenerator = TestUtil.getIdGenerator(openTelemetry);

MatcherAssert.assertThat(idGenerator, instanceOf(AwsXrayIdGenerator.class));
}

@ApplicationScoped
public static class OtelConfiguration {

@Produces
public IdGenerator idGenerator() {
return AwsXrayIdGenerator.getInstance();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.quarkus.opentelemetry.deployment;

import javax.inject.Inject;

import org.hamcrest.MatcherAssert;
import org.hamcrest.collection.ArrayMatching;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.extension.aws.AwsXrayPropagator;
import io.quarkus.test.QuarkusUnitTest;

public class OpenTelemetryPropagatorsTest {
@RegisterExtension
static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
.overrideConfigKey("quarkus.opentelemetry.propagators", "tracecontext,xray")
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClass(TestUtil.class));

@Inject
OpenTelemetry openTelemetry;

@Test
void test() throws NoSuchFieldException, IllegalAccessException {
TextMapPropagator[] textMapPropagators = TestUtil.getTextMapPropagators(openTelemetry);

MatcherAssert.assertThat(textMapPropagators,
ArrayMatching.arrayContainingInAnyOrder(W3CTraceContextPropagator.getInstance(),
AwsXrayPropagator.getInstance()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package io.quarkus.opentelemetry.deployment;

import static org.hamcrest.Matchers.emptyOrNullString;

import java.lang.reflect.InvocationTargetException;

import javax.inject.Inject;

import org.hamcrest.CoreMatchers;
import org.hamcrest.MatcherAssert;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import io.quarkus.test.QuarkusUnitTest;

public class OpenTelemetryResourceTest {
@RegisterExtension
static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
.overrideConfigKey("quarkus.opentelemetry.tracer.resources", "os")
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClass(TestUtil.class));

@Inject
OpenTelemetry openTelemetry;

@Test
void test() throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Resource resource = TestUtil.getResource(openTelemetry);

MatcherAssert.assertThat(resource.getAttributes().get(ResourceAttributes.OS_TYPE),
CoreMatchers.not(emptyOrNullString()));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package io.quarkus.opentelemetry.deployment;

import static org.hamcrest.Matchers.instanceOf;

import java.lang.reflect.InvocationTargetException;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;

import org.hamcrest.MatcherAssert;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import io.quarkus.test.QuarkusUnitTest;

public class OpenTelemetrySamplerTest {
@RegisterExtension
static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClass(TestUtil.class));

@Inject
OpenTelemetry openTelemetry;

@Test
void test() throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Sampler sampler = TestUtil.getSampler(openTelemetry);

MatcherAssert.assertThat(sampler, instanceOf(Sampler.alwaysOff().getClass()));
}

@ApplicationScoped
public static class OtelConfiguration {

@Produces
public Sampler idGenerator() {
return Sampler.alwaysOff();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package io.quarkus.opentelemetry.deployment;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.TracerProvider;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.IdGenerator;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import io.quarkus.arc.Unremovable;

@Unremovable
public final class TestUtil {
private TestUtil() {
}

public static Object getSharedState(OpenTelemetry openTelemetry)
throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
TracerProvider tracerProvider = openTelemetry.getTracerProvider();
Method unobfuscateMethod = tracerProvider.getClass().getDeclaredMethod("unobfuscate");
unobfuscateMethod.setAccessible(true);
SdkTracerProvider sdkTracerProvider = (SdkTracerProvider) unobfuscateMethod.invoke(tracerProvider);
Field privateSharedStateField = sdkTracerProvider.getClass().getDeclaredField("sharedState");
privateSharedStateField.setAccessible(true);
return privateSharedStateField.get(sdkTracerProvider);
}

public static IdGenerator getIdGenerator(OpenTelemetry openTelemetry)
throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Object sharedState = getSharedState(openTelemetry);
Field privateIdGeneratorField = sharedState.getClass().getDeclaredField("idGenerator");
privateIdGeneratorField.setAccessible(true);
return (IdGenerator) privateIdGeneratorField.get(sharedState);
}

public static Resource getResource(OpenTelemetry openTelemetry)
throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Object sharedState = getSharedState(openTelemetry);
Field privateResourceField = sharedState.getClass().getDeclaredField("resource");
privateResourceField.setAccessible(true);
return (Resource) privateResourceField.get(sharedState);
}

public static Sampler getSampler(OpenTelemetry openTelemetry)
throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Object sharedState = getSharedState(openTelemetry);
Field privateSamplerField = sharedState.getClass().getDeclaredField("sampler");
privateSamplerField.setAccessible(true);
return (Sampler) privateSamplerField.get(sharedState);
}

public static TextMapPropagator[] getTextMapPropagators(OpenTelemetry openTelemetry)
throws NoSuchFieldException, IllegalAccessException {
TextMapPropagator textMapPropagator = openTelemetry.getPropagators().getTextMapPropagator();
System.out.println(textMapPropagator);
Field privatePropagatorsField = textMapPropagator.getClass().getDeclaredField("textPropagators");
privatePropagatorsField.setAccessible(true);
return (TextMapPropagator[]) privatePropagatorsField.get(textMapPropagator);
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
package io.quarkus.opentelemetry.deployment;

import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.semconv.resource.attributes.ResourceAttributes.SERVICE_NAME;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_CLIENT_IP;
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_SCHEME;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_STATUS_CODE;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_TARGET;
import static io.opentelemetry.semconv.trace.attributes.SemanticAttributes.HTTP_USER_AGENT;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
Expand All @@ -24,20 +25,20 @@
import javax.inject.Inject;

import org.hamcrest.MatcherAssert;
import org.hamcrest.collection.ArrayMatching;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.trace.IdGenerator;
import io.opentelemetry.sdk.trace.data.SpanData;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import io.quarkus.runtime.StartupEvent;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;
Expand All @@ -46,9 +47,7 @@
public class VertxOpenTelemetryTest {
@RegisterExtension
static final QuarkusUnitTest unitTest = new QuarkusUnitTest()
.overrideConfigKey("quarkus.opentelemetry.propagators", "trace-context,baggage")
.overrideConfigKey("quarkus.opentelemetry.tracer.resource-attributes", "service.name=test")
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class));
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class).addClass(TestUtil.class));

@Inject
MyExporter myExporter;
Expand All @@ -57,17 +56,16 @@ public class VertxOpenTelemetryTest {
OpenTelemetry openTelemetry;

@Test
void trace() throws NoSuchFieldException, IllegalAccessException {
void trace() throws NoSuchFieldException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
RestAssured.when().get("/tracer").then()
.statusCode(200)
.body(is("Hello Tracer!"));

List<SpanData> spans = myExporter.getFinishedSpanItems();

TextMapPropagator textMapPropagator = openTelemetry.getPropagators().getTextMapPropagator();
Field privatePropagatorsField = textMapPropagator.getClass().getDeclaredField("textPropagators");
privatePropagatorsField.setAccessible(true);
TextMapPropagator[] textMapPropagators = (TextMapPropagator[]) privatePropagatorsField.get(textMapPropagator);
IdGenerator idGenerator = TestUtil.getIdGenerator(openTelemetry);
Sampler sampler = TestUtil.getSampler(openTelemetry);

assertEquals(2, spans.size());
assertEquals("io.quarkus.vertx.opentelemetry", spans.get(0).getName());
Expand All @@ -78,10 +76,9 @@ void trace() throws NoSuchFieldException, IllegalAccessException {
assertEquals("http", spans.get(1).getAttributes().get(HTTP_SCHEME));
assertEquals("localhost:8081", spans.get(1).getAttributes().get(HTTP_HOST));
assertEquals("127.0.0.1", spans.get(1).getAttributes().get(HTTP_CLIENT_IP));
assertEquals("test", spans.get(1).getResource().getAttributes().get(SERVICE_NAME));
MatcherAssert.assertThat(textMapPropagators,
ArrayMatching.arrayContainingInAnyOrder(W3CTraceContextPropagator.getInstance(),
W3CBaggagePropagator.getInstance()));
MatcherAssert.assertThat(textMapPropagator, instanceOf(W3CTraceContextPropagator.getInstance().getClass()));
MatcherAssert.assertThat(idGenerator, instanceOf(IdGenerator.random().getClass()));
MatcherAssert.assertThat(sampler.getClass().getName(), stringContainsInOrder("ParentBasedSampler"));
assertNotNull(spans.get(1).getAttributes().get(HTTP_USER_AGENT));
}

Expand Down
Loading

0 comments on commit 3a4903f

Please sign in to comment.