Skip to content

Commit

Permalink
Merge pull request #18313 from raulvaldoleiros/18278
Browse files Browse the repository at this point in the history
Add zipkin compatibility mode to open-tracing
  • Loading branch information
kenfinnigan authored Jul 16, 2021
2 parents dc60271 + 351c9ab commit 9ef5c49
Show file tree
Hide file tree
Showing 21 changed files with 570 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .github/native-tests.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
{
"category": "Misc3",
"timeout": 65,
"test-modules": "kubernetes-client, openshift-client, smallrye-config, smallrye-graphql, smallrye-graphql-client, smallrye-metrics",
"test-modules": "kubernetes-client, openshift-client, smallrye-config, smallrye-graphql, smallrye-graphql-client, smallrye-metrics, smallrye-opentracing",
"os-name": "ubuntu-latest"
},
{
Expand Down
15 changes: 15 additions & 0 deletions bom/application/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2884,6 +2884,21 @@
<artifactId>jaeger-thrift</artifactId>
<version>${jaeger.version}</version>
</dependency>
<dependency>
<groupId>io.jaegertracing</groupId>
<artifactId>jaeger-zipkin</artifactId>
<version>${jaeger.version}</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
<exclusion>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
Expand Down
21 changes: 21 additions & 0 deletions docs/src/main/asciidoc/opentracing.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,27 @@ Following the link:mongodb[MongoDB guide], the command listener will be register
quarkus.mongodb.tracing.enabled=true
----

=== Zipkin compatibility mode

To enable it, add the following dependency to your pom.xml:

[source, xml]
----
<dependency>
<groupId>io.jaegertracing</groupId>
<artifactId>jaeger-zipkin</artifactId>
</dependency>
----

It contains the dependencies to convert the request to zipkin format.
The zipkin compatibility mode will be activated after defining the config property as follows:

[source, properties]
----
# Enable zipkin compatibility mode
quarkus.jaeger.zipkin.compatibility-mode=true
----

[[configuration-reference]]
== Jaeger Configuration Reference

Expand Down
11 changes: 10 additions & 1 deletion extensions/jaeger/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,22 @@
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc-deployment</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-metrics-deployment</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.jaegertracing</groupId>
<artifactId>jaeger-zipkin</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import io.quarkus.jaeger.runtime.JaegerBuildTimeConfig;
import io.quarkus.jaeger.runtime.JaegerConfig;
import io.quarkus.jaeger.runtime.JaegerDeploymentRecorder;
import io.quarkus.jaeger.runtime.ZipkinConfig;
import io.quarkus.runtime.ApplicationConfig;
import io.quarkus.runtime.metrics.MetricsFactory;

Expand All @@ -29,18 +30,18 @@ void setVersion(JaegerDeploymentRecorder jdr) {
@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
ExtensionSslNativeSupportBuildItem setupTracer(JaegerDeploymentRecorder jdr, JaegerBuildTimeConfig buildTimeConfig,
JaegerConfig jaeger,
ApplicationConfig appConfig, Optional<MetricsCapabilityBuildItem> metricsCapability) {
JaegerConfig jaeger, ApplicationConfig appConfig, Optional<MetricsCapabilityBuildItem> metricsCapability,
ZipkinConfig zipkinConfig) {

if (buildTimeConfig.enabled) {
if (buildTimeConfig.metricsEnabled && metricsCapability.isPresent()) {
if (metricsCapability.get().metricsSupported(MetricsFactory.MICROMETER)) {
jdr.registerTracerWithMicrometerMetrics(jaeger, appConfig);
jdr.registerTracerWithMicrometerMetrics(jaeger, appConfig, zipkinConfig);
} else {
jdr.registerTracerWithMpMetrics(jaeger, appConfig);
jdr.registerTracerWithMpMetrics(jaeger, appConfig, zipkinConfig);
}
} else {
jdr.registerTracerWithoutMetrics(jaeger, appConfig);
jdr.registerTracerWithoutMetrics(jaeger, appConfig, zipkinConfig);
}
}

Expand All @@ -58,7 +59,6 @@ public ReflectiveClassBuildItem reflectiveClasses() {
return ReflectiveClassBuildItem
.builder("io.jaegertracing.internal.samplers.http.SamplingStrategyResponse",
"io.jaegertracing.internal.samplers.http.ProbabilisticSamplingStrategy")
.finalFieldsWritable(true)
.build();
.finalFieldsWritable(true).build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.quarkus.jaeger.deployment;

import java.util.function.BooleanSupplier;

import io.quarkus.arc.deployment.AdditionalBeanBuildItem;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.jaeger.runtime.JaegerDeploymentRecorder;
import io.quarkus.jaeger.runtime.ZipkinConfig;
import io.quarkus.jaeger.runtime.ZipkinReporterProvider;

public class ZipkinProcessor {

static final String REGISTRY_CLASS_NAME = "zipkin2.reporter.urlconnection.URLConnectionSender";
static final Class<?> REGISTRY_CLASS = JaegerDeploymentRecorder.getClassForName(REGISTRY_CLASS_NAME);

public static class ZipkinEnabled implements BooleanSupplier {
ZipkinConfig config;

public boolean getAsBoolean() {
return REGISTRY_CLASS != null && config.compatibilityMode;
}
}

@BuildStep(onlyIf = ZipkinEnabled.class)
void addZipkinClasses(BuildProducer<AdditionalBeanBuildItem> additionalBeans) {

// Add Zipkin classes
additionalBeans.produce(AdditionalBeanBuildItem.builder().addBeanClass(ZipkinReporterProvider.class)
.setUnremovable().build());

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package io.quarkus.jaeger.test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

import javax.enterprise.inject.Default;
import javax.enterprise.inject.Instance;
import javax.enterprise.inject.spi.CDI;

import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.MockedStatic;
import org.mockito.Mockito;

import io.jaegertracing.Configuration;
import io.jaegertracing.internal.JaegerTracer;
import io.jaegertracing.internal.JaegerTracer.Builder;
import io.jaegertracing.spi.Reporter;
import io.jaegertracing.zipkin.ZipkinV2Reporter;
import io.opentracing.Tracer;
import io.quarkus.jaeger.runtime.QuarkusJaegerTracer;
import io.quarkus.jaeger.runtime.ReporterFactory;
import io.quarkus.jaeger.runtime.ZipkinReporterFactoryImpl;

public class QuarkusJaegerTracerTest {

@Test
@SuppressWarnings("unchecked")
public void withzipkinCompatibilityMode() {

try (MockedStatic<Configuration> mockedStaticConfiguration = Mockito.mockStatic(Configuration.class);
MockedStatic<CDI> mockedStaticCDI = Mockito.mockStatic(CDI.class)) {

CDI<Object> mockedCDI = (CDI<Object>) Mockito.mock(CDI.class);

mockedStaticCDI.when(() -> CDI.current()).thenReturn(mockedCDI);

Instance instanceCDI = Mockito.mock(Instance.class);
Mockito.when(instanceCDI.isAmbiguous()).thenReturn(false);
Mockito.when(instanceCDI.isUnsatisfied()).thenReturn(false);
Mockito.when(instanceCDI.get()).thenReturn(new ZipkinReporterFactoryImpl());
Mockito.when(mockedCDI.select(ReporterFactory.class, Default.Literal.INSTANCE)).thenReturn(instanceCDI);

Configuration mockedInstanceConfiguration = Mockito.mock(Configuration.class);
Builder mockedBuilder = Mockito.mock(Builder.class);
Tracer mockedTracer = Mockito.mock(JaegerTracer.class);

mockedStaticConfiguration.when(() -> Configuration.fromEnv()).thenReturn(mockedInstanceConfiguration);
mockedStaticConfiguration.when(() -> mockedInstanceConfiguration.withMetricsFactory(Mockito.any()))
.thenReturn(mockedInstanceConfiguration);
mockedStaticConfiguration.when(() -> mockedInstanceConfiguration.getTracerBuilder())
.thenReturn(mockedBuilder);
mockedStaticConfiguration.when(() -> mockedBuilder.withScopeManager(Mockito.any()))
.thenReturn(mockedBuilder);
mockedStaticConfiguration.when(() -> mockedBuilder.withReporter(Mockito.any())).thenReturn(mockedBuilder);
mockedStaticConfiguration.when(() -> mockedBuilder.build()).thenReturn(mockedTracer);

QuarkusJaegerTracer tracer = new QuarkusJaegerTracer();
tracer.setZipkinCompatibilityMode(true);
tracer.setEndpoint("http://localhost");
tracer.toString();
tracer.close();

ArgumentCaptor<Reporter> argument = ArgumentCaptor.forClass(Reporter.class);
Mockito.verify(mockedBuilder).withReporter(argument.capture());
assertEquals(ZipkinV2Reporter.class, argument.getValue().getClass());
}

}

@Test
public void withoutZipkinCompatibilityMode() {
try (MockedStatic<Configuration> mockedStaticConfiguration = Mockito.mockStatic(Configuration.class)) {
Configuration mockedInstanceConfiguration = Mockito.mock(Configuration.class);
Builder mockedBuilder = Mockito.mock(Builder.class);
Tracer mockedTracer = Mockito.mock(JaegerTracer.class);

mockedStaticConfiguration.when(() -> Configuration.fromEnv()).thenReturn(mockedInstanceConfiguration);
mockedStaticConfiguration.when(() -> mockedInstanceConfiguration.withMetricsFactory(Mockito.any()))
.thenReturn(mockedInstanceConfiguration);
mockedStaticConfiguration.when(() -> mockedInstanceConfiguration.getTracerBuilder())
.thenReturn(mockedBuilder);
mockedStaticConfiguration.when(() -> mockedBuilder.withScopeManager(Mockito.any()))
.thenReturn(mockedBuilder);
mockedStaticConfiguration.when(() -> mockedBuilder.withReporter(Mockito.any())).thenReturn(mockedBuilder);
mockedStaticConfiguration.when(() -> mockedBuilder.build()).thenReturn(mockedTracer);

QuarkusJaegerTracer tracer = new QuarkusJaegerTracer();
tracer.toString();
tracer.close();

ArgumentCaptor<Reporter> argument = ArgumentCaptor.forClass(Reporter.class);
Mockito.verify(mockedBuilder).withReporter(argument.capture());
assertNull(argument.getValue());
}
}

}
9 changes: 9 additions & 0 deletions extensions/jaeger/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<dependency>
<groupId>io.jaegertracing</groupId>
<artifactId>jaeger-zipkin</artifactId>
<optional>true</optional>
</dependency>
<!-- transitive dependency from jaeger-thrift, consider removing once we move to jaeger 1.x -->
<dependency>
<groupId>jakarta.activation</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,29 +25,33 @@ public void setJaegerVersion(String version) {
}

/* RUNTIME_INIT */
public void registerTracerWithoutMetrics(JaegerConfig jaeger, ApplicationConfig appConfig) {
registerTracer(jaeger, appConfig, new NoopMetricsFactory());
public void registerTracerWithoutMetrics(JaegerConfig jaeger, ApplicationConfig appConfig,
ZipkinConfig zipkinConfig) {
registerTracer(jaeger, appConfig, new NoopMetricsFactory(), zipkinConfig);
}

/* RUNTIME_INIT */
public void registerTracerWithMpMetrics(JaegerConfig jaeger, ApplicationConfig appConfig) {
registerTracer(jaeger, appConfig, new QuarkusJaegerMpMetricsFactory());
public void registerTracerWithMpMetrics(JaegerConfig jaeger, ApplicationConfig appConfig,
ZipkinConfig zipkinConfig) {
registerTracer(jaeger, appConfig, new QuarkusJaegerMpMetricsFactory(), zipkinConfig);
}

/* RUNTIME_INIT */
public void registerTracerWithMicrometerMetrics(JaegerConfig jaeger, ApplicationConfig appConfig) {
registerTracer(jaeger, appConfig, new QuarkusJaegerMicrometerFactory());
public void registerTracerWithMicrometerMetrics(JaegerConfig jaeger, ApplicationConfig appConfig,
ZipkinConfig zipkinConfig) {
registerTracer(jaeger, appConfig, new QuarkusJaegerMicrometerFactory(), zipkinConfig);
}

private synchronized void registerTracer(JaegerConfig jaeger, ApplicationConfig appConfig, MetricsFactory metricsFactory) {
private synchronized void registerTracer(JaegerConfig jaeger, ApplicationConfig appConfig,
MetricsFactory metricsFactory, ZipkinConfig zipkinConfig) {
if (!jaeger.serviceName.isPresent()) {
if (appConfig.name.isPresent()) {
jaeger.serviceName = appConfig.name;
} else {
jaeger.serviceName = UNKNOWN_SERVICE_NAME;
}
}
initTracerConfig(jaeger);
initTracerConfig(jaeger, zipkinConfig);
quarkusTracer.setMetricsFactory(metricsFactory);
quarkusTracer.reset();
// register Quarkus tracer to GlobalTracer.
Expand All @@ -60,8 +64,11 @@ private synchronized void registerTracer(JaegerConfig jaeger, ApplicationConfig
}
}

private void initTracerConfig(JaegerConfig jaeger) {
private void initTracerConfig(JaegerConfig jaeger, ZipkinConfig zipkinConfig) {
initTracerProperty("JAEGER_ENDPOINT", jaeger.endpoint, uri -> uri.toString());
if (jaeger.endpoint.isPresent()) {
quarkusTracer.setEndpoint(jaeger.endpoint.get().toString());
}
initTracerProperty("JAEGER_AUTH_TOKEN", jaeger.authToken, token -> token);
initTracerProperty("JAEGER_USER", jaeger.user, user -> user);
initTracerProperty("JAEGER_PASSWORD", jaeger.password, pw -> pw);
Expand All @@ -79,6 +86,7 @@ private void initTracerConfig(JaegerConfig jaeger) {
initTracerProperty("JAEGER_PROPAGATION", jaeger.propagation, format -> format.toString());
initTracerProperty("JAEGER_SENDER_FACTORY", jaeger.senderFactory, sender -> sender);
quarkusTracer.setLogTraceContext(jaeger.logTraceContext);
quarkusTracer.setZipkinCompatibilityMode(zipkinConfig.compatibilityMode);
}

private <T> void initTracerProperty(String property, Optional<T> value, Function<T, String> accessor) {
Expand All @@ -92,4 +100,15 @@ private void initTracerProperty(String property, OptionalInt value, Function<Int
System.setProperty(property, accessor.apply(Integer.valueOf(value.getAsInt())));
}
}

public static Class<?> getClassForName(String className) {
Class<?> clazz = null;
try {
clazz = Class.forName(className, false, Thread.currentThread().getContextClassLoader());
} catch (ClassNotFoundException e) {
// Ignore exception
}
log.debugf("getClass: TCCL: %s ## %s : %s", Thread.currentThread().getContextClassLoader(), className, (clazz != null));
return clazz;
}
}
Loading

0 comments on commit 9ef5c49

Please sign in to comment.