Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for different propagators for Jaeger OpenTelemetry #6611

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
///////////////////////////////////////////////////////////////////////////////

Copyright (c) 2022 Oracle and/or its affiliates.
Copyright (c) 2022, 2023 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.
Expand Down Expand Up @@ -60,6 +60,7 @@ This is a standalone configuration type, prefix from configuration root: `tracin
|`port` |int |{nbsp} |Port to use to connect to tracing collector.
Default is defined by each tracing integration.
|`private-key-pem` |xref:{rootdir}/config/io_helidon_common_configurable_Resource.adoc[Resource] |{nbsp} |Private key in PEM format.
|`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.
|`protocol` |string |{nbsp} |Protocol to use (such as `http` or `https`) to connect to tracing collector.
Default is defined by each tracing integration.
|`sampler-param` |Number |`1` |The sampler parameter (number).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

# web server configuration
# Use a random free port
server.port=0
server.port=8080
tomas-langer marked this conversation as resolved.
Show resolved Hide resolved

# location on classpath (e.g. src/main/resources/WEB in maven)
server.static.classpath.location=/WEB
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2022 Oracle and/or its affiliates.
* Copyright (c) 2019, 2023 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.
Expand All @@ -17,8 +17,12 @@
package io.helidon.tracing.jaeger;

import java.time.Duration;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.logging.Logger;

import io.helidon.config.Config;
Expand All @@ -31,11 +35,14 @@

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter;
import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporterBuilder;
import io.opentelemetry.extension.trace.propagation.B3Propagator;
import io.opentelemetry.extension.trace.propagation.JaegerPropagator;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
Expand Down Expand Up @@ -147,6 +154,8 @@ public class JaegerTracerBuilder implements TracerBuilder<JaegerTracerBuilder> {
static final int DEFAULT_HTTP_PORT = 14250;

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

config.get("tags").detach()
.asMap()
Expand Down Expand Up @@ -378,6 +394,22 @@ public JaegerTracerBuilder samplerType(SamplerType samplerType) {
return this;
}

/**
* Add propagation format to use.
* Default propagation is {@code b3} and {@code jaeger}, to be compatible both with 3.0 (backward), and with
* 4.x, which uses {@code jaeger} as default.
* If any propagation is specified either in configuration or through this method, defaults will not be honored.
*
* @param propagationFormat propagation value
* @return updated builder instance
*/
@ConfiguredOption(key = "propagation", kind = ConfiguredOption.Kind.LIST, type = PropagationFormat.class, value = "B3,JAEGER")
public JaegerTracerBuilder addPropagation(PropagationFormat propagationFormat) {
Objects.requireNonNull(propagationFormat);
this.propagationFormats.add(propagationFormat);
return this;
}

/**
* Builds the {@link io.helidon.tracing.Tracer} for Jaeger based on the configured parameters.
*
Expand Down Expand Up @@ -421,7 +453,7 @@ public Tracer build() {
.setSampler(sampler)
.setResource(serviceName)
.build())
.setPropagators(ContextPropagators.create(B3Propagator.injectingMultiHeaders()))
.setPropagators(ContextPropagators.create(TextMapPropagator.composite(createPropagators())))
.build();

result = HelidonOpenTelemetry.create(ot, ot.getTracer(this.serviceName), tags);
Expand Down Expand Up @@ -480,6 +512,28 @@ boolean isEnabled() {
return enabled;
}

List<TextMapPropagator> createPropagators() {
if (propagationFormats.isEmpty()) {
// for backward compatibility, we add B3 if nothing is defined
propagationFormats.add(PropagationFormat.B3);
// and to be compatible with 4.x, we add Jaeger, which is the default for the future
propagationFormats.add(PropagationFormat.JAEGER);
}
return propagationFormats.stream()
.map(JaegerTracerBuilder::mapFormatToPropagator)
.toList();
}

private static TextMapPropagator mapFormatToPropagator(PropagationFormat propagationFormat) {
return switch (propagationFormat) {
case B3 -> B3Propagator.injectingMultiHeaders();
case B3_SINGLE -> B3Propagator.injectingSingleHeader();
case W3C -> W3CBaggagePropagator.getInstance();
// jaeger and unknown are jaeger
default -> JaegerPropagator.getInstance();
};
}

/**
* Sampler type definition.
* Available options are "const", "probabilistic", "ratelimiting" and "remote".
Expand Down Expand Up @@ -513,4 +567,26 @@ String config() {
return config;
}
}

/**
* Supported Jaeger trace context propagation formats.
*/
public enum PropagationFormat {
/**
* The Zipkin B3 trace context propagation format using multiple headers.
*/
B3,
/**
* B3 trace context propagation using a single header.
*/
B3_SINGLE,
/**
* The Jaeger trace context propagation format.
*/
JAEGER,
/**
* The W3C trace context propagation format.
*/
W3C
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2022 Oracle and/or its affiliates.
* Copyright (c) 2019, 2023 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.
Expand All @@ -16,19 +16,26 @@

package io.helidon.tracing.jaeger;

import java.util.List;
import java.util.Map;

import io.helidon.config.Config;
import io.helidon.tracing.Tracer;
import io.helidon.tracing.TracerBuilder;

import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.extension.trace.propagation.B3Propagator;
import io.opentelemetry.extension.trace.propagation.JaegerPropagator;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.CoreMatchers.sameInstance;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.jupiter.api.Assertions.assertThrows;

/**
Expand Down Expand Up @@ -105,5 +112,11 @@ void testFullHttp() {
"tag6", "741"
)));

List<TextMapPropagator> propagators = jBuilder.createPropagators();
assertThat(propagators, hasSize(3));

assertThat(propagators.get(0), instanceOf(B3Propagator.class));
assertThat(propagators.get(1), instanceOf(JaegerPropagator.class));
assertThat(propagators.get(2), instanceOf(W3CBaggagePropagator.class));
}
}
3 changes: 2 additions & 1 deletion tracing/jaeger/src/test/resources/application.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2019, 2022 Oracle and/or its affiliates.
# Copyright (c) 2019, 2023 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.
Expand Down Expand Up @@ -35,6 +35,7 @@ tracing:
path: "/api/traces/mine" # JAEGER_ENDPOINT
sampler-type: "ratio"
sampler-param: 0.5
propagation: ["jaeger", "b3_single", "w3c"]
tags:
tag1: "tag1-value" # JAEGER_TAGS
tag2: "tag2-value" # JAEGER_TAGS
Expand Down