diff --git a/tracing/providers/opentelemetry/src/main/java/io/helidon/tracing/providers/opentelemetry/OpenTelemetryDataPropagationProvider.java b/tracing/providers/opentelemetry/src/main/java/io/helidon/tracing/providers/opentelemetry/OpenTelemetryDataPropagationProvider.java
index 014c1283c32..1705dc40ea7 100644
--- a/tracing/providers/opentelemetry/src/main/java/io/helidon/tracing/providers/opentelemetry/OpenTelemetryDataPropagationProvider.java
+++ b/tracing/providers/opentelemetry/src/main/java/io/helidon/tracing/providers/opentelemetry/OpenTelemetryDataPropagationProvider.java
@@ -62,7 +62,7 @@ public void propagateData(OpenTelemetryContext context) {
}
/**
- * OpenTelementry context.
+ * OpenTelemetry context.
*/
public static class OpenTelemetryContext {
private final Span span;
diff --git a/tracing/providers/opentracing/src/main/java/io/helidon/tracing/providers/opentracing/OpenTracingTracerProvider.java b/tracing/providers/opentracing/src/main/java/io/helidon/tracing/providers/opentracing/OpenTracingTracerProvider.java
index 2926fa3f385..c3c887be51e 100644
--- a/tracing/providers/opentracing/src/main/java/io/helidon/tracing/providers/opentracing/OpenTracingTracerProvider.java
+++ b/tracing/providers/opentracing/src/main/java/io/helidon/tracing/providers/opentracing/OpenTracingTracerProvider.java
@@ -23,6 +23,8 @@
import io.helidon.common.LazyValue;
import io.helidon.common.Weight;
import io.helidon.common.Weighted;
+import io.helidon.common.config.Config;
+import io.helidon.common.config.GlobalConfig;
import io.helidon.tracing.Span;
import io.helidon.tracing.SpanListener;
import io.helidon.tracing.Tracer;
@@ -35,6 +37,10 @@
/**
* {@link java.util.ServiceLoader} service implementation of {@link io.helidon.tracing.spi.TracerProvider} for Open Tracing
* tracers.
+ *
+ * When dealing with the global tracer, manage both the Helidon one and also the OpenTracing one in concert, whether
+ * defaulting them or assigning them via {@link #global(io.helidon.tracing.Tracer)}.
+ *
*/
@Weight(Weighted.DEFAULT_WEIGHT - 50) // low weight, so it is easy to override
public class OpenTracingTracerProvider implements TracerProvider {
@@ -42,6 +48,19 @@ public class OpenTracingTracerProvider implements TracerProvider {
private static final LazyValue> SPAN_LISTENERS =
LazyValue.create(() -> HelidonServiceLoader.create(ServiceLoader.load(SpanListener.class)).asList());
+ private LazyValue globalHelidonTracer = LazyValue.create(() -> {
+ Config tracingConfig = GlobalConfig.config().get("tracing");
+
+ // Set up to create an explicit OpenTracing tracer only if we have config for tracing, indicating that the user wants
+ // something other than the no-op implementation.
+ if (tracingConfig.exists()) {
+ io.opentracing.Tracer openTracingTracer = OpenTracingTracerBuilder.create(tracingConfig)
+ .build();
+ GlobalTracer.registerIfAbsent(openTracingTracer);
+ }
+ return OpenTracingTracer.create(GlobalTracer.get());
+ });
+
@Override
public TracerBuilder> createBuilder() {
return OpenTracingTracer.builder();
@@ -49,13 +68,17 @@ public TracerBuilder> createBuilder() {
@Override
public Tracer global() {
- return OpenTracingTracer.create(GlobalTracer.get());
+ return globalHelidonTracer.get();
}
@Override
public void global(Tracer tracer) {
if (tracer instanceof OpenTracingTracer opt) {
- GlobalTracer.registerIfAbsent(opt.openTracing());
+ GlobalTracer.registerIfAbsent(() -> {
+ io.opentracing.Tracer openTracingTracer = opt.openTracing();
+ globalHelidonTracer = LazyValue.create(OpenTracingTracer.create(openTracingTracer));
+ return openTracingTracer;
+ });
}
}
diff --git a/tracing/providers/zipkin/pom.xml b/tracing/providers/zipkin/pom.xml
index 080b6061cd4..3e6aa0b9662 100644
--- a/tracing/providers/zipkin/pom.xml
+++ b/tracing/providers/zipkin/pom.xml
@@ -57,6 +57,10 @@
io.opentracing.brave
brave-opentracing
+
+ io.helidon.common
+ helidon-common-context
+
io.helidon.common.features
helidon-common-features-api
@@ -138,17 +142,33 @@
org.apache.maven.plugins
maven-surefire-plugin
-
-
- io.helidon.tracing.providers.tests.TestTracerAndSpanPropagation.java
-
-
+
+
+ default-test
+
+
+ io.helidon.tracing.providers.tests.TestTracerAndSpanPropagation.java
+
+
+
+
+ zipkin-propagation-test
+
+ test
+
+
+
+ io.helidon.tracing.providers.tests.TestTracerAndSpanPropagation.java
+
+
+
+
diff --git a/tracing/providers/zipkin/src/main/java/io/helidon/tracing/providers/zipkin/ZipkinDataPropagationProvider.java b/tracing/providers/zipkin/src/main/java/io/helidon/tracing/providers/zipkin/ZipkinDataPropagationProvider.java
new file mode 100644
index 00000000000..123d32fb83b
--- /dev/null
+++ b/tracing/providers/zipkin/src/main/java/io/helidon/tracing/providers/zipkin/ZipkinDataPropagationProvider.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2024 Oracle and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.helidon.tracing.providers.zipkin;
+
+import io.helidon.common.context.Contexts;
+import io.helidon.common.context.spi.DataPropagationProvider;
+
+import io.opentracing.Scope;
+import io.opentracing.Span;
+import io.opentracing.Tracer;
+import io.opentracing.util.GlobalTracer;
+
+/**
+ * Data propagation provider for the Helidon Zipkin tracing provider.
+ */
+public class ZipkinDataPropagationProvider implements DataPropagationProvider {
+
+ private static final System.Logger LOGGER = System.getLogger(ZipkinDataPropagationProvider.class.getName());
+
+ /**
+ * Creates new provider; public for service loading.
+ */
+ public ZipkinDataPropagationProvider() {
+ }
+
+ @Override
+ public ZipkinContext data() {
+ Tracer tracer = Contexts.context()
+ .flatMap(ctx -> ctx.get(Tracer.class))
+ .orElseGet(GlobalTracer::get);
+ Span span = tracer.activeSpan();
+ return new ZipkinContext(tracer, span);
+ }
+
+ @Override
+ public void propagateData(ZipkinContext data) {
+ if (data != null && data.span != null) {
+ data.scope = data.tracer.activateSpan(data.span);
+ }
+ }
+
+ @Override
+ public void clearData(ZipkinContext data) {
+ if (data != null && data.scope != null) {
+ try {
+ data.scope.close();
+ } catch (Exception e) {
+ LOGGER.log(System.Logger.Level.TRACE, "Cannot close tracing span", e);
+ }
+ }
+ }
+
+ /**
+ * Zipkin-specific propagation context.
+ */
+ static class ZipkinContext {
+
+ private final Tracer tracer;
+ private final Span span;
+ private Scope scope;
+
+ private ZipkinContext(Tracer tracer, Span span) {
+ this.tracer = tracer;
+ this.span = span;
+ }
+ }
+}
diff --git a/tracing/providers/zipkin/src/main/java/io/helidon/tracing/providers/zipkin/ZipkinTracerProvider.java b/tracing/providers/zipkin/src/main/java/io/helidon/tracing/providers/zipkin/ZipkinTracerProvider.java
index 2077f3901bf..fcdc8f2e816 100644
--- a/tracing/providers/zipkin/src/main/java/io/helidon/tracing/providers/zipkin/ZipkinTracerProvider.java
+++ b/tracing/providers/zipkin/src/main/java/io/helidon/tracing/providers/zipkin/ZipkinTracerProvider.java
@@ -48,6 +48,12 @@ public class ZipkinTracerProvider implements OpenTracingProvider {
private static final List TRACING_CONTEXT_PROPAGATION_HEADERS =
List.of(X_OT_SPAN_CONTEXT, X_B3_TRACE_ID, X_B3_SPAN_ID, X_B3_PARENT_SPAN_ID, X_B3_SAMPLED, X_B3_FLAGS);
+ /**
+ * Public constructor for service loading.
+ */
+ public ZipkinTracerProvider() {
+ }
+
@Override
public ZipkinTracerBuilder createBuilder() {
return ZipkinTracerBuilder.create();
diff --git a/tracing/providers/zipkin/src/main/java/module-info.java b/tracing/providers/zipkin/src/main/java/module-info.java
index afc01904698..23d95ba0206 100644
--- a/tracing/providers/zipkin/src/main/java/module-info.java
+++ b/tracing/providers/zipkin/src/main/java/module-info.java
@@ -30,6 +30,7 @@
requires brave.opentracing;
requires brave;
requires io.helidon.common;
+ requires io.helidon.common.context;
requires io.helidon.tracing.providers.opentracing;
requires io.opentracing.noop;
requires io.opentracing.util;
@@ -51,4 +52,6 @@
provides io.helidon.tracing.providers.opentracing.spi.OpenTracingProvider
with io.helidon.tracing.providers.zipkin.ZipkinTracerProvider;
+ provides io.helidon.common.context.spi.DataPropagationProvider
+ with io.helidon.tracing.providers.zipkin.ZipkinDataPropagationProvider;
}
\ No newline at end of file
diff --git a/tracing/providers/zipkin/src/test/resources/application.yaml b/tracing/providers/zipkin/src/test/resources/application.yaml
index 0f359e5fb7e..57a4e673af9 100644
--- a/tracing/providers/zipkin/src/test/resources/application.yaml
+++ b/tracing/providers/zipkin/src/test/resources/application.yaml
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2017, 2023 Oracle and/or its affiliates.
+# Copyright (c) 2017, 2024 Oracle and/or its affiliates.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -45,4 +45,5 @@ tracing:
int-tags:
tag5: 145
tag6: 741
-
+ # With changes to OpenTracing global tracer handling, provide a service name for the Zipkin implementation to use.
+ service: "helidon-test-service"