diff --git a/bom/application/pom.xml b/bom/application/pom.xml
index 9c76144b44a8f..16d6bda2e4159 100644
--- a/bom/application/pom.xml
+++ b/bom/application/pom.xml
@@ -2859,6 +2859,11 @@
jaeger-thrift
${jaeger.version}
+
+ io.jaegertracing
+ jaeger-zipkin
+ ${jaeger.version}
+
com.h2database
h2
diff --git a/extensions/jaeger/deployment/pom.xml b/extensions/jaeger/deployment/pom.xml
index d016032ea322d..a388dedc6ddfa 100644
--- a/extensions/jaeger/deployment/pom.xml
+++ b/extensions/jaeger/deployment/pom.xml
@@ -41,6 +41,11 @@
quarkus-smallrye-metrics-deployment
test
+
+ org.mockito
+ mockito-inline
+ test
+
diff --git a/extensions/jaeger/deployment/src/test/java/io/quarkus/jaeger/test/QuarkusJaegerTracerTest.java b/extensions/jaeger/deployment/src/test/java/io/quarkus/jaeger/test/QuarkusJaegerTracerTest.java
new file mode 100644
index 0000000000000..acb636355bdd0
--- /dev/null
+++ b/extensions/jaeger/deployment/src/test/java/io/quarkus/jaeger/test/QuarkusJaegerTracerTest.java
@@ -0,0 +1,73 @@
+package io.quarkus.jaeger.test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+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;
+
+public class QuarkusJaegerTracerTest {
+
+ @Test
+ public void withzipkinCompatibilityMode() {
+
+ try (MockedStatic 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.setZipkinCompatibilityMode(true);
+ tracer.setEndpoint("http://localhost");
+ tracer.toString();
+ tracer.close();
+
+ ArgumentCaptor argument = ArgumentCaptor.forClass(Reporter.class);
+ Mockito.verify(mockedBuilder).withReporter(argument.capture());
+ assertEquals(ZipkinV2Reporter.class, argument.getValue().getClass());
+ }
+
+ }
+
+ @Test
+ public void withoutZipkinCompatibilityMode() {
+ try (MockedStatic 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 argument = ArgumentCaptor.forClass(Reporter.class);
+ Mockito.verify(mockedBuilder).withReporter(argument.capture());
+ assertNull(argument.getValue());
+ }
+ }
+
+}
diff --git a/extensions/jaeger/runtime/pom.xml b/extensions/jaeger/runtime/pom.xml
index f7a3c3b1a6375..a9f27ebaca708 100644
--- a/extensions/jaeger/runtime/pom.xml
+++ b/extensions/jaeger/runtime/pom.xml
@@ -32,6 +32,20 @@
+
+ io.jaegertracing
+ jaeger-zipkin
+
+
+ commons-logging
+ commons-logging
+
+
+ javax.annotation
+ javax.annotation-api
+
+
+
jakarta.activation
diff --git a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/JaegerConfig.java b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/JaegerConfig.java
index d01892100ec28..d5ca8f2419fe1 100644
--- a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/JaegerConfig.java
+++ b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/JaegerConfig.java
@@ -118,4 +118,9 @@ public class JaegerConfig {
@ConfigItem(defaultValue = "true")
public Boolean logTraceContext;
+ /**
+ * Whether the jaeger should run in zipkin compatibility mode
+ */
+ @ConfigItem
+ public Optional zipkinCompatibilityMode;
}
diff --git a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/JaegerDeploymentRecorder.java b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/JaegerDeploymentRecorder.java
index 7140d386f2219..06df5e573cc71 100644
--- a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/JaegerDeploymentRecorder.java
+++ b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/JaegerDeploymentRecorder.java
@@ -62,6 +62,9 @@ private synchronized void registerTracer(JaegerConfig jaeger, ApplicationConfig
private void initTracerConfig(JaegerConfig jaeger) {
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);
@@ -79,6 +82,9 @@ 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);
+ if (jaeger.zipkinCompatibilityMode.isPresent()) {
+ quarkusTracer.setZipkinCompatibilityMode(jaeger.zipkinCompatibilityMode.get());
+ }
}
private void initTracerProperty(String property, Optional value, Function accessor) {
diff --git a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/QuarkusJaegerTracer.java b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/QuarkusJaegerTracer.java
index 49f64a7ee2b24..fad5e7ecece66 100644
--- a/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/QuarkusJaegerTracer.java
+++ b/extensions/jaeger/runtime/src/main/java/io/quarkus/jaeger/runtime/QuarkusJaegerTracer.java
@@ -3,6 +3,7 @@
import io.jaegertracing.Configuration;
import io.jaegertracing.internal.JaegerTracer;
import io.jaegertracing.spi.MetricsFactory;
+import io.jaegertracing.zipkin.ZipkinV2Reporter;
import io.opentracing.Scope;
import io.opentracing.ScopeManager;
import io.opentracing.Span;
@@ -10,6 +11,8 @@
import io.opentracing.Tracer;
import io.opentracing.propagation.Format;
import io.opentracing.util.ThreadLocalScopeManager;
+import zipkin2.reporter.AsyncReporter;
+import zipkin2.reporter.urlconnection.URLConnectionSender;
public class QuarkusJaegerTracer implements Tracer {
@@ -17,6 +20,8 @@ public class QuarkusJaegerTracer implements Tracer {
private boolean logTraceContext;
private MetricsFactory metricsFactory;
+ private boolean zipkinCompatibilityMode = false;
+ private String endpoint = null;
private final ScopeManager scopeManager = new ScopeManager() {
@@ -71,10 +76,15 @@ private Tracer tracer() {
if (tracer == null) {
synchronized (this) {
if (tracer == null) {
+ ZipkinV2Reporter reporter = null;
+ if (zipkinCompatibilityMode) {
+ reporter = new ZipkinV2Reporter(AsyncReporter.create(URLConnectionSender.create(endpoint)));
+ }
tracer = Configuration.fromEnv()
.withMetricsFactory(metricsFactory)
.getTracerBuilder()
.withScopeManager(scopeManager)
+ .withReporter(reporter)
.build();
}
}
@@ -124,4 +134,12 @@ public Span activeSpan() {
public Scope activateSpan(final Span span) {
return tracer.activateSpan(span);
}
+
+ public void setZipkinCompatibilityMode(boolean zipkinCompatibilityMode) {
+ this.zipkinCompatibilityMode = zipkinCompatibilityMode;
+ }
+
+ public void setEndpoint(String endpoint) {
+ this.endpoint = endpoint;
+ }
}