|
1 | 1 | /* |
2 | | - * Copyright (c) 2019, 2022 Oracle and/or its affiliates. |
| 2 | + * Copyright (c) 2019, 2023 Oracle and/or its affiliates. |
3 | 3 | * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | * you may not use this file except in compliance with the License. |
|
17 | 17 | package io.helidon.tracing.jaeger; |
18 | 18 |
|
19 | 19 | import java.time.Duration; |
| 20 | +import java.util.EnumSet; |
20 | 21 | import java.util.HashMap; |
| 22 | +import java.util.List; |
21 | 23 | import java.util.Map; |
| 24 | +import java.util.Objects; |
| 25 | +import java.util.Set; |
22 | 26 | import java.util.logging.Logger; |
23 | 27 |
|
24 | 28 | import io.helidon.config.Config; |
|
31 | 35 |
|
32 | 36 | import io.opentelemetry.api.GlobalOpenTelemetry; |
33 | 37 | import io.opentelemetry.api.OpenTelemetry; |
| 38 | +import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; |
34 | 39 | import io.opentelemetry.api.common.Attributes; |
35 | 40 | import io.opentelemetry.context.propagation.ContextPropagators; |
| 41 | +import io.opentelemetry.context.propagation.TextMapPropagator; |
36 | 42 | import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter; |
37 | 43 | import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporterBuilder; |
38 | 44 | import io.opentelemetry.extension.trace.propagation.B3Propagator; |
| 45 | +import io.opentelemetry.extension.trace.propagation.JaegerPropagator; |
39 | 46 | import io.opentelemetry.sdk.OpenTelemetrySdk; |
40 | 47 | import io.opentelemetry.sdk.resources.Resource; |
41 | 48 | import io.opentelemetry.sdk.trace.SdkTracerProvider; |
@@ -147,6 +154,8 @@ public class JaegerTracerBuilder implements TracerBuilder<JaegerTracerBuilder> { |
147 | 154 | static final int DEFAULT_HTTP_PORT = 14250; |
148 | 155 |
|
149 | 156 | 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); |
150 | 159 | private String serviceName; |
151 | 160 | private String protocol = "http"; |
152 | 161 | private String host = DEFAULT_HTTP_HOST; |
@@ -256,6 +265,13 @@ public JaegerTracerBuilder config(Config config) { |
256 | 265 | config.get("private-key-pem").as(io.helidon.common.configurable.Resource::create).ifPresent(this::privateKey); |
257 | 266 | config.get("client-cert-pem").as(io.helidon.common.configurable.Resource::create).ifPresent(this::clientCertificate); |
258 | 267 | 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 | + }); |
259 | 275 |
|
260 | 276 | config.get("tags").detach() |
261 | 277 | .asMap() |
@@ -378,6 +394,22 @@ public JaegerTracerBuilder samplerType(SamplerType samplerType) { |
378 | 394 | return this; |
379 | 395 | } |
380 | 396 |
|
| 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 | + |
381 | 413 | /** |
382 | 414 | * Builds the {@link io.helidon.tracing.Tracer} for Jaeger based on the configured parameters. |
383 | 415 | * |
@@ -421,7 +453,7 @@ public Tracer build() { |
421 | 453 | .setSampler(sampler) |
422 | 454 | .setResource(serviceName) |
423 | 455 | .build()) |
424 | | - .setPropagators(ContextPropagators.create(B3Propagator.injectingMultiHeaders())) |
| 456 | + .setPropagators(ContextPropagators.create(TextMapPropagator.composite(createPropagators()))) |
425 | 457 | .build(); |
426 | 458 |
|
427 | 459 | result = HelidonOpenTelemetry.create(ot, ot.getTracer(this.serviceName), tags); |
@@ -480,6 +512,28 @@ boolean isEnabled() { |
480 | 512 | return enabled; |
481 | 513 | } |
482 | 514 |
|
| 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 | + |
483 | 537 | /** |
484 | 538 | * Sampler type definition. |
485 | 539 | * Available options are "const", "probabilistic", "ratelimiting" and "remote". |
@@ -513,4 +567,26 @@ String config() { |
513 | 567 | return config; |
514 | 568 | } |
515 | 569 | } |
| 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 | + } |
516 | 592 | } |
0 commit comments