Skip to content

Commit 0587466

Browse files
authored
Support for different propagators for Jaeger OpenTelemetry integration. (helidon-io#6586) (helidon-io#6611)
* Support for different propagators for Jaeger OpenTelemetry integration. * Added tests to validate the correct propagators are added (cherry picked from commit f5bf1ff) Signed-off-by: Tomas Langer <tomas.langer@oracle.com>
1 parent f2ad935 commit 0587466

5 files changed

Lines changed: 97 additions & 6 deletions

File tree

docs/config/io_helidon_tracing_jaeger_JaegerTracerBuilder.adoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
///////////////////////////////////////////////////////////////////////////////
22

3-
Copyright (c) 2022 Oracle and/or its affiliates.
3+
Copyright (c) 2022, 2023 Oracle and/or its affiliates.
44

55
Licensed under the Apache License, Version 2.0 (the "License");
66
you may not use this file except in compliance with the License.
@@ -60,6 +60,7 @@ This is a standalone configuration type, prefix from configuration root: `tracin
6060
|`port` |int |{nbsp} |Port to use to connect to tracing collector.
6161
Default is defined by each tracing integration.
6262
|`private-key-pem` |xref:{rootdir}/config/io_helidon_common_configurable_Resource.adoc[Resource] |{nbsp} |Private key in PEM format.
63+
|`propagation` |`JAEGER` |addPropagation |Propagation type (`jaeger`, `b3`, `b3_single`, `w3c`). Jaeger is the default, `b3` is for compatibility with Zipkin (using multiple headers), `b3_single` using a single header.
6364
|`protocol` |string |{nbsp} |Protocol to use (such as `http` or `https`) to connect to tracing collector.
6465
Default is defined by each tracing integration.
6566
|`sampler-param` |Number |`1` |The sampler parameter (number).

examples/microprofile/static-content/src/main/resources/META-INF/microprofile-config.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
# web server configuration
1818
# Use a random free port
19-
server.port=0
19+
server.port=8080
2020

2121
# location on classpath (e.g. src/main/resources/WEB in maven)
2222
server.static.classpath.location=/WEB

tracing/jaeger/src/main/java/io/helidon/tracing/jaeger/JaegerTracerBuilder.java

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2022 Oracle and/or its affiliates.
2+
* Copyright (c) 2019, 2023 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,8 +17,12 @@
1717
package io.helidon.tracing.jaeger;
1818

1919
import java.time.Duration;
20+
import java.util.EnumSet;
2021
import java.util.HashMap;
22+
import java.util.List;
2123
import java.util.Map;
24+
import java.util.Objects;
25+
import java.util.Set;
2226
import java.util.logging.Logger;
2327

2428
import io.helidon.config.Config;
@@ -31,11 +35,14 @@
3135

3236
import io.opentelemetry.api.GlobalOpenTelemetry;
3337
import io.opentelemetry.api.OpenTelemetry;
38+
import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
3439
import io.opentelemetry.api.common.Attributes;
3540
import io.opentelemetry.context.propagation.ContextPropagators;
41+
import io.opentelemetry.context.propagation.TextMapPropagator;
3642
import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter;
3743
import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporterBuilder;
3844
import io.opentelemetry.extension.trace.propagation.B3Propagator;
45+
import io.opentelemetry.extension.trace.propagation.JaegerPropagator;
3946
import io.opentelemetry.sdk.OpenTelemetrySdk;
4047
import io.opentelemetry.sdk.resources.Resource;
4148
import io.opentelemetry.sdk.trace.SdkTracerProvider;
@@ -147,6 +154,8 @@ public class JaegerTracerBuilder implements TracerBuilder<JaegerTracerBuilder> {
147154
static final int DEFAULT_HTTP_PORT = 14250;
148155

149156
private final Map<String, String> tags = new HashMap<>();
157+
// this is a backward incompatible change, but the correct choice is Jaeger, not B3
158+
private final Set<PropagationFormat> propagationFormats = EnumSet.noneOf(PropagationFormat.class);
150159
private String serviceName;
151160
private String protocol = "http";
152161
private String host = DEFAULT_HTTP_HOST;
@@ -256,6 +265,13 @@ public JaegerTracerBuilder config(Config config) {
256265
config.get("private-key-pem").as(io.helidon.common.configurable.Resource::create).ifPresent(this::privateKey);
257266
config.get("client-cert-pem").as(io.helidon.common.configurable.Resource::create).ifPresent(this::clientCertificate);
258267
config.get("trusted-cert-pem").as(io.helidon.common.configurable.Resource::create).ifPresent(this::trustedCertificates);
268+
config.get("propagation").asList(String.class)
269+
.ifPresent(propagationStrings -> {
270+
propagationStrings.stream()
271+
.map(String::toUpperCase)
272+
.map(PropagationFormat::valueOf)
273+
.forEach(this::addPropagation);
274+
});
259275

260276
config.get("tags").detach()
261277
.asMap()
@@ -378,6 +394,22 @@ public JaegerTracerBuilder samplerType(SamplerType samplerType) {
378394
return this;
379395
}
380396

397+
/**
398+
* Add propagation format to use.
399+
* Default propagation is {@code b3} and {@code jaeger}, to be compatible both with 3.0 (backward), and with
400+
* 4.x, which uses {@code jaeger} as default.
401+
* If any propagation is specified either in configuration or through this method, defaults will not be honored.
402+
*
403+
* @param propagationFormat propagation value
404+
* @return updated builder instance
405+
*/
406+
@ConfiguredOption(key = "propagation", kind = ConfiguredOption.Kind.LIST, type = PropagationFormat.class, value = "B3,JAEGER")
407+
public JaegerTracerBuilder addPropagation(PropagationFormat propagationFormat) {
408+
Objects.requireNonNull(propagationFormat);
409+
this.propagationFormats.add(propagationFormat);
410+
return this;
411+
}
412+
381413
/**
382414
* Builds the {@link io.helidon.tracing.Tracer} for Jaeger based on the configured parameters.
383415
*
@@ -421,7 +453,7 @@ public Tracer build() {
421453
.setSampler(sampler)
422454
.setResource(serviceName)
423455
.build())
424-
.setPropagators(ContextPropagators.create(B3Propagator.injectingMultiHeaders()))
456+
.setPropagators(ContextPropagators.create(TextMapPropagator.composite(createPropagators())))
425457
.build();
426458

427459
result = HelidonOpenTelemetry.create(ot, ot.getTracer(this.serviceName), tags);
@@ -480,6 +512,28 @@ boolean isEnabled() {
480512
return enabled;
481513
}
482514

515+
List<TextMapPropagator> createPropagators() {
516+
if (propagationFormats.isEmpty()) {
517+
// for backward compatibility, we add B3 if nothing is defined
518+
propagationFormats.add(PropagationFormat.B3);
519+
// and to be compatible with 4.x, we add Jaeger, which is the default for the future
520+
propagationFormats.add(PropagationFormat.JAEGER);
521+
}
522+
return propagationFormats.stream()
523+
.map(JaegerTracerBuilder::mapFormatToPropagator)
524+
.toList();
525+
}
526+
527+
private static TextMapPropagator mapFormatToPropagator(PropagationFormat propagationFormat) {
528+
return switch (propagationFormat) {
529+
case B3 -> B3Propagator.injectingMultiHeaders();
530+
case B3_SINGLE -> B3Propagator.injectingSingleHeader();
531+
case W3C -> W3CBaggagePropagator.getInstance();
532+
// jaeger and unknown are jaeger
533+
default -> JaegerPropagator.getInstance();
534+
};
535+
}
536+
483537
/**
484538
* Sampler type definition.
485539
* Available options are "const", "probabilistic", "ratelimiting" and "remote".
@@ -513,4 +567,26 @@ String config() {
513567
return config;
514568
}
515569
}
570+
571+
/**
572+
* Supported Jaeger trace context propagation formats.
573+
*/
574+
public enum PropagationFormat {
575+
/**
576+
* The Zipkin B3 trace context propagation format using multiple headers.
577+
*/
578+
B3,
579+
/**
580+
* B3 trace context propagation using a single header.
581+
*/
582+
B3_SINGLE,
583+
/**
584+
* The Jaeger trace context propagation format.
585+
*/
586+
JAEGER,
587+
/**
588+
* The W3C trace context propagation format.
589+
*/
590+
W3C
591+
}
516592
}

tracing/jaeger/src/test/java/io/helidon/tracing/jaeger/JaegerTracerBuilderTest.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2019, 2022 Oracle and/or its affiliates.
2+
* Copyright (c) 2019, 2023 Oracle and/or its affiliates.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,19 +16,26 @@
1616

1717
package io.helidon.tracing.jaeger;
1818

19+
import java.util.List;
1920
import java.util.Map;
2021

2122
import io.helidon.config.Config;
2223
import io.helidon.tracing.Tracer;
2324
import io.helidon.tracing.TracerBuilder;
2425

26+
import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
27+
import io.opentelemetry.context.propagation.TextMapPropagator;
28+
import io.opentelemetry.extension.trace.propagation.B3Propagator;
29+
import io.opentelemetry.extension.trace.propagation.JaegerPropagator;
2530
import org.junit.jupiter.api.BeforeAll;
2631
import org.junit.jupiter.api.Test;
2732

33+
import static org.hamcrest.CoreMatchers.instanceOf;
2834
import static org.hamcrest.CoreMatchers.is;
2935
import static org.hamcrest.CoreMatchers.nullValue;
3036
import static org.hamcrest.CoreMatchers.sameInstance;
3137
import static org.hamcrest.MatcherAssert.assertThat;
38+
import static org.hamcrest.Matchers.hasSize;
3239
import static org.junit.jupiter.api.Assertions.assertThrows;
3340

3441
/**
@@ -105,5 +112,11 @@ void testFullHttp() {
105112
"tag6", "741"
106113
)));
107114

115+
List<TextMapPropagator> propagators = jBuilder.createPropagators();
116+
assertThat(propagators, hasSize(3));
117+
118+
assertThat(propagators.get(0), instanceOf(B3Propagator.class));
119+
assertThat(propagators.get(1), instanceOf(JaegerPropagator.class));
120+
assertThat(propagators.get(2), instanceOf(W3CBaggagePropagator.class));
108121
}
109122
}

tracing/jaeger/src/test/resources/application.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Copyright (c) 2019, 2022 Oracle and/or its affiliates.
2+
# Copyright (c) 2019, 2023 Oracle and/or its affiliates.
33
#
44
# Licensed under the Apache License, Version 2.0 (the "License");
55
# you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@ tracing:
3535
path: "/api/traces/mine" # JAEGER_ENDPOINT
3636
sampler-type: "ratio"
3737
sampler-param: 0.5
38+
propagation: ["jaeger", "b3_single", "w3c"]
3839
tags:
3940
tag1: "tag1-value" # JAEGER_TAGS
4041
tag2: "tag2-value" # JAEGER_TAGS

0 commit comments

Comments
 (0)