Skip to content

Commit

Permalink
Support OpenTelemetry @WithSpan in CDI
Browse files Browse the repository at this point in the history
  • Loading branch information
radcortez committed Nov 5, 2021
1 parent 01ce860 commit 62a0a34
Show file tree
Hide file tree
Showing 11 changed files with 450 additions and 4 deletions.
7 changes: 7 additions & 0 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,13 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-instrumentation-bom-alpha</artifactId>
<version>${opentelemetry-alpha.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>

<!-- Oracle JDBC driver -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
package io.quarkus.opentelemetry.deployment;

import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.BooleanSupplier;

import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.DotName;

import io.opentelemetry.extension.annotations.WithSpan;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.arc.deployment.AnnotationsTransformerBuildItem;
import io.quarkus.arc.deployment.InterceptorBindingRegistrarBuildItem;
import io.quarkus.arc.processor.InterceptorBindingRegistrar;
import io.quarkus.deployment.Feature;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
Expand All @@ -19,6 +28,7 @@
import io.quarkus.opentelemetry.runtime.OpenTelemetryProducer;
import io.quarkus.opentelemetry.runtime.OpenTelemetryRecorder;
import io.quarkus.opentelemetry.runtime.QuarkusContextStorage;
import io.quarkus.opentelemetry.runtime.tracing.cdi.WithSpanInterceptor;
import io.quarkus.runtime.LaunchMode;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.vertx.core.deployment.CoreVertxBuildItem;
Expand Down Expand Up @@ -56,6 +66,36 @@ void registerOpenTelemetryContextStorage(
.produce(new ReflectiveClassBuildItem(true, true, QuarkusContextStorage.class));
}

@BuildStep(onlyIf = OpenTelemetryEnabled.class)
void registerWithSpan(
BuildProducer<InterceptorBindingRegistrarBuildItem> interceptorBindingRegistrar,
BuildProducer<AdditionalBeanBuildItem> additionalBeans) {

interceptorBindingRegistrar.produce(new InterceptorBindingRegistrarBuildItem(
new InterceptorBindingRegistrar() {
@Override
public List<InterceptorBinding> getAdditionalBindings() {
return List.of(InterceptorBinding.of(WithSpan.class, Set.of("value", "kind")));
}
}));

additionalBeans.produce(new AdditionalBeanBuildItem(WithSpanInterceptor.class));
}

@BuildStep(onlyIf = OpenTelemetryEnabled.class)
void transformWithSpan(
BuildProducer<AnnotationsTransformerBuildItem> annotationsTransformer) {

annotationsTransformer.produce(new AnnotationsTransformerBuildItem(transformationContext -> {
AnnotationTarget target = transformationContext.getTarget();
if (target.kind().equals(AnnotationTarget.Kind.CLASS)) {
if (target.asClass().name().equals(DotName.createSimple(WithSpanInterceptor.class.getName()))) {
transformationContext.transform().add(DotName.createSimple(WithSpan.class.getName())).done();
}
}
}));
}

@BuildStep(onlyIf = OpenTelemetryEnabled.class)
@Record(ExecutionTime.STATIC_INIT)
void createOpenTelemetry(OpenTelemetryConfig openTelemetryConfig,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package io.quarkus.opentelemetry.deployment;

import static io.opentelemetry.api.trace.SpanKind.INTERNAL;
import static io.opentelemetry.api.trace.SpanKind.SERVER;
import static org.hamcrest.Matchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.List;

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;

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.extension.annotations.WithSpan;
import io.opentelemetry.sdk.trace.data.SpanData;
import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;

public class OpenTelemetryHttpCDITest {
@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest()
.setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class)
.addClass(HelloResource.class)
.addClass(HelloBean.class)
.addClass(TestSpanExporter.class));

@Inject
TestSpanExporter spanExporter;

@Test
void telemetry() {
RestAssured.when()
.get("/hello").then()
.statusCode(200)
.body(is("hello"));

List<SpanData> spanItems = spanExporter.getFinishedSpanItems();
assertEquals(2, spanItems.size());
assertEquals("HelloBean.hello", spanItems.get(0).getName());
assertEquals(INTERNAL, spanItems.get(0).getKind());
assertEquals("hello", spanItems.get(1).getName());
assertEquals(SERVER, spanItems.get(1).getKind());
assertEquals(spanItems.get(0).getParentSpanId(), spanItems.get(1).getSpanId());
}

@Path("/hello")
public static class HelloResource {
@Inject
HelloBean helloBean;

@GET
public String hello() {
return helloBean.hello();
}
}

@ApplicationScoped
public static class HelloBean {
@WithSpan
public String hello() {
return "hello";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package io.quarkus.opentelemetry.deployment;

import static io.opentelemetry.api.trace.SpanKind.INTERNAL;
import static io.opentelemetry.api.trace.SpanKind.SERVER;
import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.List;

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

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

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.extension.annotations.SpanAttribute;
import io.opentelemetry.extension.annotations.WithSpan;
import io.opentelemetry.sdk.trace.data.SpanData;
import io.quarkus.test.QuarkusUnitTest;

public class WithSpanInterceptorTest {
@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest()
.setArchiveProducer(
() -> ShrinkWrap.create(JavaArchive.class).addClass(SpanBean.class).addClass(TestSpanExporter.class));

@Inject
SpanBean spanBean;
@Inject
TestSpanExporter spanExporter;

@AfterEach
void tearDown() {
spanExporter.reset();
}

@Test
void span() {
spanBean.span();
List<SpanData> spanItems = spanExporter.getFinishedSpanItems();
assertEquals(1, spanItems.size());
assertEquals("SpanBean.span", spanItems.get(0).getName());
assertEquals(INTERNAL, spanItems.get(0).getKind());
}

@Test
void spanName() {
spanBean.spanName();
List<SpanData> spanItems = spanExporter.getFinishedSpanItems();
assertEquals(1, spanItems.size());
assertEquals("name", spanItems.get(0).getName());
assertEquals(INTERNAL, spanItems.get(0).getKind());
}

@Test
void spanKind() {
spanBean.spanKind();
List<SpanData> spanItems = spanExporter.getFinishedSpanItems();
assertEquals(1, spanItems.size());
assertEquals("SpanBean.spanKind", spanItems.get(0).getName());
assertEquals(SERVER, spanItems.get(0).getKind());
}

@Test
void spanArgs() {
spanBean.spanArgs("argument");
List<SpanData> spanItems = spanExporter.getFinishedSpanItems();
assertEquals(1, spanItems.size());
assertEquals("SpanBean.spanArgs", spanItems.get(0).getName());
assertEquals(INTERNAL, spanItems.get(0).getKind());
assertEquals("argument", spanItems.get(0).getAttributes().get(AttributeKey.stringKey("arg")));
}

@Test
void spanChild() {
spanBean.spanChild();
List<SpanData> spanItems = spanExporter.getFinishedSpanItems();
assertEquals(2, spanItems.size());

assertEquals("SpanChildBean.spanChild", spanItems.get(0).getName());
assertEquals("SpanBean.spanChild", spanItems.get(1).getName());
assertEquals(spanItems.get(0).getParentSpanId(), spanItems.get(1).getSpanId());
}

@ApplicationScoped
public static class SpanBean {
@WithSpan
public void span() {

}

@WithSpan("name")
public void spanName() {

}

@WithSpan(kind = SERVER)
public void spanKind() {

}

@WithSpan
public void spanArgs(@SpanAttribute(value = "arg") String arg) {

}

@Inject
SpanChildBean spanChildBean;

@WithSpan
public void spanChild() {
spanChildBean.spanChild();
}
}

@ApplicationScoped
public static class SpanChildBean {
@WithSpan
public void spanChild() {

}
}
}
12 changes: 12 additions & 0 deletions extensions/opentelemetry/opentelemetry/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-extension-annotations</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-instrumentation-api</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry.instrumentation</groupId>
<artifactId>opentelemetry-instrumentation-api-annotation-support</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-extension-autoconfigure-spi</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

@ConfigRoot(name = "opentelemetry")
public final class OpenTelemetryConfig {
public static final String INSTRUMENTATION_NAME = "io.quarkus.opentelemetry";

/**
* OpenTelemetry support.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package io.quarkus.opentelemetry.runtime.tracing;

import static io.quarkus.opentelemetry.runtime.OpenTelemetryConfig.INSTRUMENTATION_NAME;

import javax.enterprise.inject.Produces;
import javax.inject.Singleton;

Expand All @@ -25,6 +27,6 @@ public LateBoundSampler getLateBoundSampler() {
@Singleton
@DefaultBean
public Tracer getTracer() {
return GlobalOpenTelemetry.getTracer("io.quarkus.opentelemetry");
return GlobalOpenTelemetry.getTracer(INSTRUMENTATION_NAME);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.quarkus.opentelemetry.runtime.tracing.cdi;

import java.lang.reflect.Method;

final class MethodRequest {
private final Method method;
private final Object[] args;

public MethodRequest(final Method method, final Object[] args) {
this.method = method;
this.args = args;
}

public Method getMethod() {
return method;
}

public Object[] getArgs() {
return args;
}
}
Loading

0 comments on commit 62a0a34

Please sign in to comment.