From 629bee39873295669a482fbfabcf9b31d25526da Mon Sep 17 00:00:00 2001 From: conghuhu <56248584+conghuhu@users.noreply.github.com> Date: Mon, 14 Aug 2023 15:42:40 +0800 Subject: [PATCH] feat: add brave to core (#12814) --- dubbo-metrics/dubbo-tracing/pom.xml | 7 + .../exporter/TraceExporterFactory.java | 66 ------- ...TlpExporter.java => OTlpSpanExporter.java} | 24 +-- ...nExporter.java => ZipkinSpanExporter.java} | 35 +--- .../exporter/zipkin/ZipkinSpanHandler.java | 53 ++++++ .../tracer/brave/BravePropagatorProvider.java | 10 +- .../tracing/tracer/brave/BraveProvider.java | 161 +++++++++++++++++- .../tracer/otel/OpenTelemetryProvider.java | 109 +++++++----- .../ObservationConstants.java} | 20 +-- .../tracing/utils/ObservationSupportUtil.java | 4 + .../dubbo/tracing/utils/PropagationType.java | 44 +++++ .../exporter/otlp/OTlpSpanExporterTest.java | 43 +++++ .../zipkin/ZipkinSpanExporterTest.java | 44 +++++ .../zipkin/ZipkinSpanHandlerTest.java | 42 +++++ .../brave/BravePropagatorProviderTest.java | 38 +++++ .../tracer/brave/BraveProviderTest.java | 86 ++++++++++ .../otel/OTelPropagatorProviderTest.java | 1 + .../otel/OpenTelemetryProviderTest.java | 32 ++++ .../tracing/utils/PropagationTypeTest.java | 37 ++++ 19 files changed, 677 insertions(+), 179 deletions(-) delete mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/TraceExporterFactory.java rename dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/otlp/{OTlpExporter.java => OTlpSpanExporter.java} (77%) rename dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/{ZipkinExporter.java => ZipkinSpanExporter.java} (54%) create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanHandler.java rename dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/{exporter/TraceExporter.java => utils/ObservationConstants.java} (70%) create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/PropagationType.java create mode 100644 dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/exporter/otlp/OTlpSpanExporterTest.java create mode 100644 dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanExporterTest.java create mode 100644 dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanHandlerTest.java create mode 100644 dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/brave/BravePropagatorProviderTest.java create mode 100644 dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/brave/BraveProviderTest.java create mode 100644 dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/utils/PropagationTypeTest.java diff --git a/dubbo-metrics/dubbo-tracing/pom.xml b/dubbo-metrics/dubbo-tracing/pom.xml index e50dae23bd..f6e26215d9 100644 --- a/dubbo-metrics/dubbo-tracing/pom.xml +++ b/dubbo-metrics/dubbo-tracing/pom.xml @@ -107,5 +107,12 @@ zipkin-reporter-brave true + + + + io.zipkin.reporter2 + zipkin-sender-urlconnection + true + \ No newline at end of file diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/TraceExporterFactory.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/TraceExporterFactory.java deleted file mode 100644 index 7327cf038e..0000000000 --- a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/TraceExporterFactory.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.dubbo.tracing.exporter; - -import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; -import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.utils.StringUtils; -import org.apache.dubbo.config.nested.ExporterConfig; -import org.apache.dubbo.rpc.model.ApplicationModel; -import org.apache.dubbo.tracing.exporter.otlp.OTlpExporter; -import org.apache.dubbo.tracing.exporter.zipkin.ZipkinExporter; - -import brave.handler.SpanHandler; -import io.opentelemetry.sdk.trace.export.SpanExporter; - -import java.util.ArrayList; -import java.util.List; - -public class TraceExporterFactory { - - private final static ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(TraceExporterFactory.class); - - /** - * for OTel - */ - public static List getSpanExporters(ApplicationModel applicationModel, ExporterConfig exporterConfig) { - ExporterConfig.ZipkinConfig zipkinConfig = exporterConfig.getZipkinConfig(); - ExporterConfig.OtlpConfig otlpConfig = exporterConfig.getOtlpConfig(); - List res = new ArrayList<>(); - if (zipkinConfig != null && StringUtils.isNotEmpty(zipkinConfig.getEndpoint())) { - ZipkinExporter zipkinExporter = new ZipkinExporter(applicationModel, zipkinConfig); - LOGGER.info("Create zipkin span exporter."); - res.add(zipkinExporter.getSpanExporter()); - } - if (otlpConfig != null && StringUtils.isNotEmpty(otlpConfig.getEndpoint())) { - OTlpExporter otlpExporter = new OTlpExporter(applicationModel, otlpConfig); - LOGGER.info("Create OTlp span exporter."); - res.add(otlpExporter.getSpanExporter()); - } - - return res; - } - - /** - * for Brave - */ - public static List getSpanHandlers(ApplicationModel applicationModel, ExporterConfig exporterConfig) { - List res = new ArrayList<>(); - // TODO brave SpanHandler impl - return res; - } -} diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/otlp/OTlpExporter.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/otlp/OTlpSpanExporter.java similarity index 77% rename from dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/otlp/OTlpExporter.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/otlp/OTlpSpanExporter.java index 72da78a795..2f2a4acd9f 100644 --- a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/otlp/OTlpExporter.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/otlp/OTlpSpanExporter.java @@ -18,9 +18,7 @@ package org.apache.dubbo.tracing.exporter.otlp; import org.apache.dubbo.config.nested.ExporterConfig; import org.apache.dubbo.rpc.model.ApplicationModel; -import org.apache.dubbo.tracing.exporter.TraceExporter; -import brave.handler.SpanHandler; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; @@ -28,18 +26,12 @@ import io.opentelemetry.sdk.trace.export.SpanExporter; import java.util.Map; -public class OTlpExporter implements TraceExporter { +/** + * OTlp span exporter for OTel. + */ +public class OTlpSpanExporter { - private final ApplicationModel applicationModel; - private final ExporterConfig.OtlpConfig otlpConfig; - - public OTlpExporter(ApplicationModel applicationModel, ExporterConfig.OtlpConfig otlpConfig) { - this.applicationModel = applicationModel; - this.otlpConfig = otlpConfig; - } - - @Override - public SpanExporter getSpanExporter() { + public static SpanExporter getSpanExporter(ApplicationModel applicationModel, ExporterConfig.OtlpConfig otlpConfig) { OtlpGrpcSpanExporter externalOTlpGrpcSpanExporter = applicationModel.getBeanFactory().getBean(OtlpGrpcSpanExporter.class); if (externalOTlpGrpcSpanExporter != null) { return externalOTlpGrpcSpanExporter; @@ -57,10 +49,4 @@ public class OTlpExporter implements TraceExporter { } return builder.build(); } - - @Override - public SpanHandler getSpanHandler() { - // OTlp is only belong to OTel. - return null; - } } diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinExporter.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanExporter.java similarity index 54% rename from dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinExporter.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanExporter.java index c0c00c6fa8..e8a7a9f3d1 100644 --- a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinExporter.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanExporter.java @@ -18,43 +18,26 @@ package org.apache.dubbo.tracing.exporter.zipkin; import org.apache.dubbo.config.nested.ExporterConfig; import org.apache.dubbo.rpc.model.ApplicationModel; -import org.apache.dubbo.tracing.exporter.TraceExporter; -import brave.handler.SpanHandler; -import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter; -import io.opentelemetry.sdk.trace.export.SpanExporter; import zipkin2.Span; import zipkin2.codec.BytesEncoder; import zipkin2.codec.SpanBytesEncoder; -public class ZipkinExporter implements TraceExporter { +/** + * Zipkin span exporter for OTel. + */ +public class ZipkinSpanExporter { - private final ApplicationModel applicationModel; - private final ExporterConfig.ZipkinConfig zipkinConfig; - - public ZipkinExporter(ApplicationModel applicationModel, ExporterConfig.ZipkinConfig zipkinConfig) { - this.applicationModel = applicationModel; - this.zipkinConfig = zipkinConfig; - } - - @Override - public SpanExporter getSpanExporter() { - BytesEncoder encoder = getSpanBytesEncoder(); - return ZipkinSpanExporter.builder() - .setEncoder(encoder) + public static io.opentelemetry.sdk.trace.export.SpanExporter getSpanExporter(ApplicationModel applicationModel, ExporterConfig.ZipkinConfig zipkinConfig) { + return io.opentelemetry.exporter.zipkin.ZipkinSpanExporter.builder() + .setEncoder(getSpanBytesEncoder(applicationModel)) .setEndpoint(zipkinConfig.getEndpoint()) .setReadTimeout(zipkinConfig.getReadTimeout()) .build(); } - @Override - public SpanHandler getSpanHandler() { - // TODO SpanHandler of Brave impl - return null; - } - - private BytesEncoder getSpanBytesEncoder() { - BytesEncoder encoder = applicationModel.getBeanFactory().getBean(BytesEncoder.class); + private static BytesEncoder getSpanBytesEncoder(ApplicationModel applicationModel) { + BytesEncoder encoder = applicationModel.getBeanFactory().getBean(BytesEncoder.class); return encoder == null ? SpanBytesEncoder.JSON_V2 : encoder; } } diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanHandler.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanHandler.java new file mode 100644 index 0000000000..f56173a8ad --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanHandler.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.tracing.exporter.zipkin; + +import org.apache.dubbo.config.nested.ExporterConfig; +import org.apache.dubbo.rpc.model.ApplicationModel; + +import brave.handler.SpanHandler; +import zipkin2.Span; +import zipkin2.codec.BytesEncoder; +import zipkin2.codec.SpanBytesEncoder; +import zipkin2.reporter.AsyncReporter; +import zipkin2.reporter.urlconnection.URLConnectionSender; + +/** + * Zipkin span handler for Brave. + */ +public class ZipkinSpanHandler { + + public static SpanHandler getSpanHandler(ApplicationModel applicationModel, ExporterConfig.ZipkinConfig zipkinConfig) { + URLConnectionSender sender = applicationModel.getBeanFactory().getBean(URLConnectionSender.class); + if (sender == null) { + URLConnectionSender.Builder builder = URLConnectionSender.newBuilder(); + builder.connectTimeout((int) zipkinConfig.getConnectTimeout().toMillis()); + builder.readTimeout((int) zipkinConfig.getReadTimeout().toMillis()); + builder.endpoint(zipkinConfig.getEndpoint()); + + sender = builder.build(); + } + + AsyncReporter spanReporter = AsyncReporter.builder(sender).build(getSpanBytesEncoder(applicationModel)); + return zipkin2.reporter.brave.ZipkinSpanHandler.newBuilder(spanReporter).build(); + } + + private static BytesEncoder getSpanBytesEncoder(ApplicationModel applicationModel) { + BytesEncoder encoder = applicationModel.getBeanFactory().getBean(BytesEncoder.class); + return encoder == null ? SpanBytesEncoder.JSON_V2 : encoder; + } +} diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/brave/BravePropagatorProvider.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/brave/BravePropagatorProvider.java index 8560a5b149..56e23d3670 100644 --- a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/brave/BravePropagatorProvider.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/brave/BravePropagatorProvider.java @@ -18,14 +18,20 @@ package org.apache.dubbo.tracing.tracer.brave; import org.apache.dubbo.tracing.tracer.PropagatorProvider; +import io.micrometer.tracing.brave.bridge.BravePropagator; import io.micrometer.tracing.propagation.Propagator; public class BravePropagatorProvider implements PropagatorProvider { + private static Propagator propagator; + @Override public Propagator getPropagator() { - // TODO impl - return null; + return propagator; + } + + protected static void createMicrometerPropagator(brave.Tracing tracing) { + propagator = new BravePropagator(tracing); } } diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/brave/BraveProvider.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/brave/BraveProvider.java index 9ab8172b02..9f178f400b 100644 --- a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/brave/BraveProvider.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/brave/BraveProvider.java @@ -16,15 +16,40 @@ */ package org.apache.dubbo.tracing.tracer.brave; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.TracingConfig; +import org.apache.dubbo.config.nested.BaggageConfig; +import org.apache.dubbo.config.nested.ExporterConfig; import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.tracing.exporter.zipkin.ZipkinSpanHandler; import org.apache.dubbo.tracing.tracer.TracerProvider; +import org.apache.dubbo.tracing.utils.PropagationType; +import io.micrometer.tracing.CurrentTraceContext; import io.micrometer.tracing.Tracer; +import io.micrometer.tracing.brave.bridge.BraveBaggageManager; +import io.micrometer.tracing.brave.bridge.BraveCurrentTraceContext; +import io.micrometer.tracing.brave.bridge.BraveTracer; +import io.micrometer.tracing.brave.bridge.W3CPropagation; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +import static org.apache.dubbo.tracing.utils.ObservationConstants.DEFAULT_APPLICATION_NAME; +import static org.apache.dubbo.tracing.utils.ObservationSupportUtil.isSupportBraveURLSender; public class BraveProvider implements TracerProvider { + private final static ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(BraveProvider.class); + + private static final BraveBaggageManager BRAVE_BAGGAGE_MANAGER = new BraveBaggageManager(); + private final ApplicationModel applicationModel; private final TracingConfig tracingConfig; @@ -35,7 +60,139 @@ public class BraveProvider implements TracerProvider { @Override public Tracer getTracer() { - // TODO impl - return null; + // [Brave component] SpanHandler is a component that gets called when a span is finished. + List spanHandlerList = getSpanHandlers(); + + String applicationName = applicationModel.getApplicationConfigManager().getApplication() + .map(ApplicationConfig::getName) + .orElse(DEFAULT_APPLICATION_NAME); + + // [Brave component] CurrentTraceContext is a Brave component that allows you to + // retrieve the current TraceContext. + brave.propagation.ThreadLocalCurrentTraceContext braveCurrentTraceContext = brave.propagation.ThreadLocalCurrentTraceContext.newBuilder() + .addScopeDecorator(correlationScopeDecorator()) // Brave's automatic MDC setup + .build(); + + // [Micrometer Tracing component] A Micrometer Tracing wrapper for Brave's CurrentTraceContext + CurrentTraceContext bridgeContext = new BraveCurrentTraceContext(braveCurrentTraceContext); + + + // [Brave component] Tracing is the root component that allows to configure the + // tracer, handlers, context propagation etc. + brave.Tracing.Builder builder = brave.Tracing.newBuilder() + .currentTraceContext(braveCurrentTraceContext) + .supportsJoin(false) + .traceId128Bit(true) + .localServiceName(applicationName) + // For Baggage to work you need to provide a list of fields to propagate + .propagationFactory(PropagatorFactory.getPropagationFactory(tracingConfig)) + .sampler(getSampler()); + spanHandlerList.forEach(builder::addSpanHandler); + + brave.Tracing tracing = builder.build(); + + BravePropagatorProvider.createMicrometerPropagator(tracing); + + // [Brave component] Tracer is a component that handles the life-cycle of a span + brave.Tracer braveTracer = tracing.tracer(); + + // [Micrometer Tracing component] A Micrometer Tracing wrapper for Brave's Tracer + return new BraveTracer(braveTracer, bridgeContext, BRAVE_BAGGAGE_MANAGER); + } + + private List getSpanHandlers() { + ExporterConfig exporterConfig = tracingConfig.getTracingExporter(); + List res = new ArrayList<>(); + if (!isSupportBraveURLSender()) { + return res; + } + ExporterConfig.ZipkinConfig zipkinConfig = exporterConfig.getZipkinConfig(); + if (zipkinConfig != null && StringUtils.isNotEmpty(zipkinConfig.getEndpoint())) { + LOGGER.info("Create zipkin span handler."); + res.add(ZipkinSpanHandler.getSpanHandler(applicationModel, zipkinConfig)); + } + return res; + } + + private brave.sampler.Sampler getSampler() { + return brave.sampler.Sampler.create(tracingConfig.getSampling().getProbability()); + } + + private Optional correlationFieldsCorrelationScopeCustomizer() { + BaggageConfig.Correlation correlation = tracingConfig.getBaggage().getCorrelation(); + boolean enabled = correlation.isEnabled(); + if (!enabled) { + return Optional.empty(); + } + return Optional.of((builder) -> { + List correlationFields = correlation.getFields(); + for (String field : correlationFields) { + builder.add(brave.baggage.CorrelationScopeConfig.SingleCorrelationField.newBuilder(brave.baggage.BaggageField.create(field)) + .flushOnUpdate().build()); + } + }); + } + + private brave.propagation.CurrentTraceContext.ScopeDecorator correlationScopeDecorator() { + brave.baggage.CorrelationScopeDecorator.Builder builder = brave.context.slf4j.MDCScopeDecorator.newBuilder(); + correlationFieldsCorrelationScopeCustomizer().ifPresent((customizer) -> customizer.customize(builder)); + return builder.build(); + } + + static class PropagatorFactory { + + public static brave.propagation.Propagation.Factory getPropagationFactory(TracingConfig tracingConfig) { + BaggageConfig baggageConfig = tracingConfig.getBaggage(); + if (baggageConfig == null || !baggageConfig.getEnabled()) { + return getPropagationFactoryWithoutBaggage(tracingConfig); + } + return getPropagationFactoryWithBaggage(tracingConfig); + } + + private static brave.propagation.Propagation.Factory getPropagationFactoryWithoutBaggage(TracingConfig tracingConfig) { + PropagationType propagationType = PropagationType.forValue(tracingConfig.getPropagation().getType()); + if (PropagationType.W3C == propagationType) { + return new io.micrometer.tracing.brave.bridge.W3CPropagation(); + } else { + // Brave default propagation is B3 + return brave.propagation.B3Propagation.newFactoryBuilder().injectFormat(brave.propagation.B3Propagation.Format.SINGLE_NO_PARENT).build(); + } + } + + private static brave.propagation.Propagation.Factory getPropagationFactoryWithBaggage(TracingConfig tracingConfig) { + PropagationType propagationType = PropagationType.forValue(tracingConfig.getPropagation().getType()); + brave.propagation.Propagation.Factory delegate; + if (PropagationType.W3C == propagationType) { + delegate = new W3CPropagation(BRAVE_BAGGAGE_MANAGER, Collections.emptyList()); + } else { + // Brave default propagation is B3 + delegate = brave.propagation.B3Propagation.newFactoryBuilder().injectFormat(brave.propagation.B3Propagation.Format.SINGLE_NO_PARENT).build(); + } + return getBaggageFactoryBuilder(delegate, tracingConfig).build(); + } + + private static brave.baggage.BaggagePropagation.FactoryBuilder getBaggageFactoryBuilder(brave.propagation.Propagation.Factory delegate, TracingConfig tracingConfig) { + brave.baggage.BaggagePropagation.FactoryBuilder builder = brave.baggage.BaggagePropagation.newFactoryBuilder(delegate); + + getBaggagePropagationCustomizers(tracingConfig).forEach((customizer) -> customizer.customize(builder)); + return builder; + } + + private static List getBaggagePropagationCustomizers(TracingConfig tracingConfig) { + List res = new ArrayList<>(); + if (tracingConfig.getBaggage().getCorrelation().isEnabled()) { + res.add(remoteFieldsBaggagePropagationCustomizer(tracingConfig)); + } + return res; + } + + private static brave.baggage.BaggagePropagationCustomizer remoteFieldsBaggagePropagationCustomizer(TracingConfig tracingConfig) { + return (builder) -> { + List remoteFields = tracingConfig.getBaggage().getRemoteFields(); + for (String fieldName : remoteFields) { + builder.add(brave.baggage.BaggagePropagationConfig.SingleBaggageField.remote(brave.baggage.BaggageField.create(fieldName))); + } + }; + } } } diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProvider.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProvider.java index 36b3c3f191..bf00771b99 100644 --- a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProvider.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProvider.java @@ -18,13 +18,19 @@ package org.apache.dubbo.tracing.tracer.otel; import org.apache.dubbo.common.Version; import org.apache.dubbo.common.lang.Nullable; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.TracingConfig; import org.apache.dubbo.config.nested.BaggageConfig; +import org.apache.dubbo.config.nested.ExporterConfig; import org.apache.dubbo.config.nested.PropagationConfig; import org.apache.dubbo.rpc.model.ApplicationModel; -import org.apache.dubbo.tracing.exporter.TraceExporterFactory; +import org.apache.dubbo.tracing.exporter.otlp.OTlpSpanExporter; +import org.apache.dubbo.tracing.exporter.zipkin.ZipkinSpanExporter; import org.apache.dubbo.tracing.tracer.TracerProvider; +import org.apache.dubbo.tracing.utils.PropagationType; import io.micrometer.tracing.Tracer; import io.micrometer.tracing.otel.bridge.CompositeSpanExporter; @@ -36,28 +42,17 @@ import io.micrometer.tracing.otel.bridge.OtelTracer; import io.micrometer.tracing.otel.bridge.Slf4JBaggageEventListener; import io.micrometer.tracing.otel.bridge.Slf4JEventListener; import io.micrometer.tracing.otel.propagation.BaggageTextMapPropagator; -import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; -import io.opentelemetry.api.common.Attributes; -import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; -import io.opentelemetry.context.ContextStorage; -import io.opentelemetry.context.propagation.ContextPropagators; -import io.opentelemetry.context.propagation.TextMapPropagator; -import io.opentelemetry.extension.trace.propagation.B3Propagator; -import io.opentelemetry.sdk.OpenTelemetrySdk; -import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.sdk.trace.SdkTracerProvider; -import io.opentelemetry.sdk.trace.export.BatchSpanProcessor; -import io.opentelemetry.sdk.trace.export.SpanExporter; -import io.opentelemetry.sdk.trace.samplers.Sampler; -import io.opentelemetry.semconv.resource.attributes.ResourceAttributes; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import static org.apache.dubbo.tracing.utils.ObservationConstants.DEFAULT_APPLICATION_NAME; + public class OpenTelemetryProvider implements TracerProvider { - private static final String DEFAULT_APPLICATION_NAME = "dubbo-application"; + private final static ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(OpenTelemetryProvider.class); + private final ApplicationModel applicationModel; private final TracingConfig tracingConfig; @@ -72,7 +67,7 @@ public class OpenTelemetryProvider implements TracerProvider { @Override public Tracer getTracer() { // [OTel component] SpanExporter is a component that gets called when a span is finished. - List spanExporters = TraceExporterFactory.getSpanExporters(applicationModel, tracingConfig.getTracingExporter()); + List spanExporters = getSpanExporters(); String applicationName = applicationModel.getApplicationConfigManager().getApplication() .map(ApplicationConfig::getName) @@ -84,18 +79,18 @@ public class OpenTelemetryProvider implements TracerProvider { this.otelCurrentTraceContext = createCurrentTraceContext(); // [OTel component] SdkTracerProvider is an SDK implementation for TracerProvider - SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() + io.opentelemetry.sdk.trace.SdkTracerProvider sdkTracerProvider = io.opentelemetry.sdk.trace.SdkTracerProvider.builder() .setSampler(getSampler()) - .setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName))) - .addSpanProcessor(BatchSpanProcessor + .setResource(io.opentelemetry.sdk.resources.Resource.create(io.opentelemetry.api.common.Attributes.of(io.opentelemetry.semconv.resource.attributes.ResourceAttributes.SERVICE_NAME, applicationName))) + .addSpanProcessor(io.opentelemetry.sdk.trace.export.BatchSpanProcessor .builder(new CompositeSpanExporter(spanExporters, null, null, null)) .build()) .build(); - ContextPropagators otelContextPropagators = createOtelContextPropagators(); + io.opentelemetry.context.propagation.ContextPropagators otelContextPropagators = createOtelContextPropagators(); // [OTel component] The SDK implementation of OpenTelemetry - OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder() + io.opentelemetry.sdk.OpenTelemetrySdk openTelemetrySdk = io.opentelemetry.sdk.OpenTelemetrySdk.builder() .setTracerProvider(sdkTracerProvider) .setPropagators(otelContextPropagators) .build(); @@ -113,14 +108,31 @@ public class OpenTelemetryProvider implements TracerProvider { Collections.emptyList())); } + private List getSpanExporters() { + ExporterConfig exporterConfig = tracingConfig.getTracingExporter(); + ExporterConfig.ZipkinConfig zipkinConfig = exporterConfig.getZipkinConfig(); + ExporterConfig.OtlpConfig otlpConfig = exporterConfig.getOtlpConfig(); + List res = new ArrayList<>(); + if (zipkinConfig != null && StringUtils.isNotEmpty(zipkinConfig.getEndpoint())) { + LOGGER.info("Create zipkin span exporter."); + res.add(ZipkinSpanExporter.getSpanExporter(applicationModel, zipkinConfig)); + } + if (otlpConfig != null && StringUtils.isNotEmpty(otlpConfig.getEndpoint())) { + LOGGER.info("Create OTlp span exporter."); + res.add(OTlpSpanExporter.getSpanExporter(applicationModel, otlpConfig)); + } + + return res; + } + /** * sampler with probability * * @return sampler */ - private Sampler getSampler() { - Sampler rootSampler = Sampler.traceIdRatioBased(tracingConfig.getSampling().getProbability()); - return Sampler.parentBased(rootSampler); + private io.opentelemetry.sdk.trace.samplers.Sampler getSampler() { + io.opentelemetry.sdk.trace.samplers.Sampler rootSampler = io.opentelemetry.sdk.trace.samplers.Sampler.traceIdRatioBased(tracingConfig.getSampling().getProbability()); + return io.opentelemetry.sdk.trace.samplers.Sampler.parentBased(rootSampler); } private List getEventListeners() { @@ -141,13 +153,13 @@ public class OpenTelemetryProvider implements TracerProvider { } private OtelCurrentTraceContext createCurrentTraceContext() { - ContextStorage.addWrapper(new EventPublishingContextWrapper(publisher)); + io.opentelemetry.context.ContextStorage.addWrapper(new EventPublishingContextWrapper(publisher)); return new OtelCurrentTraceContext(); } - private ContextPropagators createOtelContextPropagators() { - return ContextPropagators.create( - TextMapPropagator.composite( + private io.opentelemetry.context.propagation.ContextPropagators createOtelContextPropagators() { + return io.opentelemetry.context.propagation.ContextPropagators.create( + io.opentelemetry.context.propagation.TextMapPropagator.composite( PropagatorFactory.getPropagator(tracingConfig.getPropagation(), tracingConfig.getBaggage(), otelCurrentTraceContext @@ -172,41 +184,44 @@ public class OpenTelemetryProvider implements TracerProvider { static class PropagatorFactory { - public static TextMapPropagator getPropagator(PropagationConfig propagationConfig, - @Nullable BaggageConfig baggageConfig, - @Nullable OtelCurrentTraceContext currentTraceContext) { + public static io.opentelemetry.context.propagation.TextMapPropagator getPropagator(PropagationConfig propagationConfig, + @Nullable BaggageConfig baggageConfig, + @Nullable OtelCurrentTraceContext currentTraceContext) { if (baggageConfig == null || !baggageConfig.getEnabled()) { return getPropagatorWithoutBaggage(propagationConfig); } return getPropagatorWithBaggage(propagationConfig, baggageConfig, currentTraceContext); } - private static TextMapPropagator getPropagatorWithoutBaggage(PropagationConfig propagationConfig) { + private static io.opentelemetry.context.propagation.TextMapPropagator getPropagatorWithoutBaggage(PropagationConfig propagationConfig) { String type = propagationConfig.getType(); - if ("B3".equals(type)) { - return B3Propagator.injectingSingleHeader(); - } else if ("W3C".equals(type)) { - return W3CTraceContextPropagator.getInstance(); + PropagationType propagationType = PropagationType.forValue(type); + + if (PropagationType.B3 == propagationType) { + return io.opentelemetry.extension.trace.propagation.B3Propagator.injectingSingleHeader(); + } else if (PropagationType.W3C == propagationType) { + return io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator.getInstance(); } - return TextMapPropagator.noop(); + return io.opentelemetry.context.propagation.TextMapPropagator.noop(); } - private static TextMapPropagator getPropagatorWithBaggage(PropagationConfig propagationConfig, - BaggageConfig baggageConfig, - OtelCurrentTraceContext currentTraceContext) { + private static io.opentelemetry.context.propagation.TextMapPropagator getPropagatorWithBaggage(PropagationConfig propagationConfig, + BaggageConfig baggageConfig, + OtelCurrentTraceContext currentTraceContext) { String type = propagationConfig.getType(); - if ("B3".equals(type)) { + PropagationType propagationType = PropagationType.forValue(type); + if (PropagationType.B3 == propagationType) { List remoteFields = baggageConfig.getRemoteFields(); - return TextMapPropagator.composite(B3Propagator.injectingSingleHeader(), + return io.opentelemetry.context.propagation.TextMapPropagator.composite(io.opentelemetry.extension.trace.propagation.B3Propagator.injectingSingleHeader(), new BaggageTextMapPropagator(remoteFields, new OtelBaggageManager(currentTraceContext, remoteFields, Collections.emptyList()))); - } else if ("W3C".equals(type)) { + } else if (PropagationType.W3C == propagationType) { List remoteFields = baggageConfig.getRemoteFields(); - return TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(), - W3CBaggagePropagator.getInstance(), new BaggageTextMapPropagator(remoteFields, + return io.opentelemetry.context.propagation.TextMapPropagator.composite(io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator.getInstance(), + io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator.getInstance(), new BaggageTextMapPropagator(remoteFields, new OtelBaggageManager(currentTraceContext, remoteFields, Collections.emptyList()))); } - return TextMapPropagator.noop(); + return io.opentelemetry.context.propagation.TextMapPropagator.noop(); } } } diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/TraceExporter.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/ObservationConstants.java similarity index 70% rename from dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/TraceExporter.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/ObservationConstants.java index 9b8f12ee4b..819e6ac44b 100644 --- a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/TraceExporter.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/ObservationConstants.java @@ -14,24 +14,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.tracing.exporter; -import brave.handler.SpanHandler; -import io.opentelemetry.sdk.trace.export.SpanExporter; +package org.apache.dubbo.tracing.utils; -public interface TraceExporter { +public class ObservationConstants { - /** - * for otel - * - * @return - */ - SpanExporter getSpanExporter(); - - /** - * for brave - * - * @return - */ - SpanHandler getSpanHandler(); + public static final String DEFAULT_APPLICATION_NAME = "dubbo-application"; } diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/ObservationSupportUtil.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/ObservationSupportUtil.java index 4cf8e05edf..72a77556eb 100644 --- a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/ObservationSupportUtil.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/ObservationSupportUtil.java @@ -43,6 +43,10 @@ public class ObservationSupportUtil { && isClassPresent("brave.Tracing"); } + public static boolean isSupportBraveURLSender() { + return isClassPresent("zipkin2.reporter.urlconnection.URLConnectionSender"); + } + private static boolean isClassPresent(String className) { return ClassUtils.isPresent(className, ObservationSupportUtil.class.getClassLoader()); } diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/PropagationType.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/PropagationType.java new file mode 100644 index 0000000000..8ed5c56135 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/PropagationType.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.tracing.utils; + +public enum PropagationType { + + W3C("W3C"), + B3("B3"); + + private final String value; + + PropagationType(String type) { + this.value = type; + } + + public String getValue() { + return value; + } + + public static PropagationType forValue(String value) { + PropagationType[] values = values(); + for (PropagationType type : values) { + if (type.getValue().equals(value)) { + return type; + } + } + return null; + } +} diff --git a/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/exporter/otlp/OTlpSpanExporterTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/exporter/otlp/OTlpSpanExporterTest.java new file mode 100644 index 0000000000..a57933ea2e --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/exporter/otlp/OTlpSpanExporterTest.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.tracing.exporter.otlp; + +import org.apache.dubbo.config.nested.ExporterConfig; +import org.apache.dubbo.rpc.model.ApplicationModel; + +import io.opentelemetry.sdk.trace.export.SpanExporter; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.time.Duration; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class OTlpSpanExporterTest { + + @Test + void getSpanExporter() { + ExporterConfig.OtlpConfig otlpConfig = mock(ExporterConfig.OtlpConfig.class); + when(otlpConfig.getEndpoint()).thenReturn("http://localhost:9411/api/v2/spans"); + when(otlpConfig.getTimeout()).thenReturn(Duration.ofSeconds(5)); + when(otlpConfig.getCompressionMethod()).thenReturn("gzip"); + + SpanExporter spanExporter = OTlpSpanExporter.getSpanExporter(ApplicationModel.defaultModel(), otlpConfig); + Assertions.assertNotNull(spanExporter); + } +} \ No newline at end of file diff --git a/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanExporterTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanExporterTest.java new file mode 100644 index 0000000000..c6bd0922e0 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanExporterTest.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.tracing.exporter.zipkin; + +import org.apache.dubbo.config.nested.ExporterConfig; +import org.apache.dubbo.rpc.model.ApplicationModel; + +import io.opentelemetry.sdk.trace.export.SpanExporter; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.time.Duration; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + + +class ZipkinSpanExporterTest { + + @Test + void getSpanExporter() { + ExporterConfig.ZipkinConfig zipkinConfig = mock(ExporterConfig.ZipkinConfig.class); + when(zipkinConfig.getEndpoint()).thenReturn("http://localhost:9411/api/v2/spans"); + when(zipkinConfig.getConnectTimeout()).thenReturn(Duration.ofSeconds(5)); + when(zipkinConfig.getReadTimeout()).thenReturn(Duration.ofSeconds(5)); + + SpanExporter spanExporter = ZipkinSpanExporter.getSpanExporter(ApplicationModel.defaultModel(), zipkinConfig); + Assertions.assertNotNull(spanExporter); + } +} \ No newline at end of file diff --git a/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanHandlerTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanHandlerTest.java new file mode 100644 index 0000000000..b30b2a8f04 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinSpanHandlerTest.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.tracing.exporter.zipkin; + +import org.apache.dubbo.config.nested.ExporterConfig; +import org.apache.dubbo.rpc.model.ApplicationModel; + +import brave.handler.SpanHandler; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.time.Duration; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class ZipkinSpanHandlerTest { + + @Test + void getSpanHandler() { + ExporterConfig.ZipkinConfig zipkinConfig = mock(ExporterConfig.ZipkinConfig.class); + when(zipkinConfig.getEndpoint()).thenReturn("http://localhost:9411/api/v2/spans"); + when(zipkinConfig.getConnectTimeout()).thenReturn(Duration.ofSeconds(5)); + + SpanHandler spanHandler = ZipkinSpanHandler.getSpanHandler(ApplicationModel.defaultModel(), zipkinConfig); + Assertions.assertNotNull(spanHandler); + } +} \ No newline at end of file diff --git a/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/brave/BravePropagatorProviderTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/brave/BravePropagatorProviderTest.java new file mode 100644 index 0000000000..b9c6c32489 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/brave/BravePropagatorProviderTest.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.tracing.tracer.brave; + +import org.apache.dubbo.common.utils.Assert; + +import brave.Tracing; +import io.micrometer.tracing.propagation.Propagator; +import org.junit.jupiter.api.Test; + +import static org.mockito.Mockito.mock; + +class BravePropagatorProviderTest { + + @Test + void testBravePropagatorProvider() { + Tracing tracing = mock(Tracing.class); + BravePropagatorProvider.createMicrometerPropagator(tracing); + + BravePropagatorProvider bravePropagatorProvider = new BravePropagatorProvider(); + Propagator propagator = bravePropagatorProvider.getPropagator(); + Assert.notNull(propagator, "Propagator don't be null."); + } +} \ No newline at end of file diff --git a/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/brave/BraveProviderTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/brave/BraveProviderTest.java new file mode 100644 index 0000000000..a622a3c6a1 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/brave/BraveProviderTest.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.tracing.tracer.brave; + +import org.apache.dubbo.common.utils.Assert; +import org.apache.dubbo.config.TracingConfig; +import org.apache.dubbo.config.nested.BaggageConfig; +import org.apache.dubbo.config.nested.ExporterConfig; +import org.apache.dubbo.config.nested.PropagationConfig; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.tracing.utils.PropagationType; + +import brave.propagation.Propagation; +import io.micrometer.tracing.Tracer; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class BraveProviderTest { + + @Test + void testGetTracer() { + TracingConfig tracingConfig = new TracingConfig(); + tracingConfig.setEnabled(true); + ExporterConfig exporterConfig = new ExporterConfig(); + exporterConfig.setZipkinConfig(new ExporterConfig.ZipkinConfig("")); + tracingConfig.setTracingExporter(exporterConfig); + + BraveProvider braveProvider = new BraveProvider(ApplicationModel.defaultModel(), tracingConfig); + Tracer tracer = braveProvider.getTracer(); + Assert.notNull(tracer, "Tracer should not be null."); + assertEquals(io.micrometer.tracing.brave.bridge.BraveTracer.class, tracer.getClass()); + } + + @Test + void testGetPropagator() { + TracingConfig tracingConfig = mock(TracingConfig.class); + PropagationConfig propagationConfig = mock(PropagationConfig.class); + when(tracingConfig.getPropagation()).thenReturn(propagationConfig); + BaggageConfig baggageConfig = mock(BaggageConfig.class); + when(tracingConfig.getBaggage()).thenReturn(baggageConfig); + + // no baggage + when(baggageConfig.getEnabled()).thenReturn(Boolean.FALSE); + + when(propagationConfig.getType()).thenReturn(PropagationType.W3C.getValue()); + Propagation.Factory w3cPropagationFactoryWithoutBaggage = BraveProvider.PropagatorFactory.getPropagationFactory(tracingConfig); + assertEquals(io.micrometer.tracing.brave.bridge.W3CPropagation.class, w3cPropagationFactoryWithoutBaggage.getClass()); + + when(propagationConfig.getType()).thenReturn(PropagationType.B3.getValue()); + Propagation.Factory b3PropagationFactoryWithoutBaggage = BraveProvider.PropagatorFactory.getPropagationFactory(tracingConfig); + Assert.notNull(b3PropagationFactoryWithoutBaggage, "b3PropagationFactoryWithoutBaggage should not be null."); + + // with baggage + when(baggageConfig.getEnabled()).thenReturn(Boolean.TRUE); + BaggageConfig.Correlation correlation = mock(BaggageConfig.Correlation.class); + when(correlation.isEnabled()).thenReturn(Boolean.TRUE); + when(baggageConfig.getCorrelation()).thenReturn(correlation); + List remoteFields = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + remoteFields.add("test-hd-" + i); + } + when(baggageConfig.getRemoteFields()).thenReturn(remoteFields); + Propagation.Factory propagationFactoryWithBaggage = BraveProvider.PropagatorFactory.getPropagationFactory(tracingConfig); + Assert.notNull(propagationFactoryWithBaggage, "propagationFactoryWithBaggage should not be null."); + } +} \ No newline at end of file diff --git a/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OTelPropagatorProviderTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OTelPropagatorProviderTest.java index 83f2cd2df0..24b1e3f11d 100644 --- a/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OTelPropagatorProviderTest.java +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OTelPropagatorProviderTest.java @@ -23,6 +23,7 @@ import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.propagation.ContextPropagators; import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; class OTelPropagatorProviderTest { diff --git a/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProviderTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProviderTest.java index 0374912c3a..b48c624cd8 100644 --- a/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProviderTest.java +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProviderTest.java @@ -20,15 +20,23 @@ import org.apache.dubbo.common.utils.Assert; import org.apache.dubbo.config.TracingConfig; import org.apache.dubbo.config.nested.BaggageConfig; import org.apache.dubbo.config.nested.ExporterConfig; +import org.apache.dubbo.config.nested.PropagationConfig; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.tracing.tracer.TracerProvider; import org.apache.dubbo.tracing.tracer.TracerProviderFactory; +import org.apache.dubbo.tracing.utils.PropagationType; import io.micrometer.tracing.Tracer; +import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext; import io.micrometer.tracing.otel.bridge.OtelTracer; +import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.context.propagation.TextMapPropagator; +import io.opentelemetry.extension.trace.propagation.B3Propagator; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; class OpenTelemetryProviderTest { @@ -50,4 +58,28 @@ class OpenTelemetryProviderTest { Tracer tracer2 = tracerProvider2.getTracer(); assertEquals(OtelTracer.class, tracer2.getClass()); } + + @Test + void testGetPropagator() { + PropagationConfig propagationConfig = mock(PropagationConfig.class); + BaggageConfig baggageConfig = mock(BaggageConfig.class); + OtelCurrentTraceContext otelCurrentTraceContext = mock(OtelCurrentTraceContext.class); + + when(baggageConfig.getEnabled()).thenReturn(Boolean.FALSE); + + when(propagationConfig.getType()).thenReturn(PropagationType.B3.getValue()); + TextMapPropagator b3PropagatorWithoutBaggage = OpenTelemetryProvider.PropagatorFactory.getPropagator(propagationConfig, baggageConfig, otelCurrentTraceContext); + assertEquals(B3Propagator.class, b3PropagatorWithoutBaggage.getClass()); + + when(propagationConfig.getType()).thenReturn(PropagationType.W3C.getValue()); + TextMapPropagator w3cPropagatorWithoutBaggage = OpenTelemetryProvider.PropagatorFactory.getPropagator(propagationConfig, baggageConfig, otelCurrentTraceContext); + assertEquals(W3CTraceContextPropagator.class, w3cPropagatorWithoutBaggage.getClass()); + + + when(baggageConfig.getEnabled()).thenReturn(Boolean.TRUE); + TextMapPropagator propagatorWithBaggage = OpenTelemetryProvider.PropagatorFactory.getPropagator(propagationConfig, baggageConfig, otelCurrentTraceContext); + Assert.notNull(propagatorWithBaggage, "PropagatorWithBaggage should not be null"); + } + + } \ No newline at end of file diff --git a/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/utils/PropagationTypeTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/utils/PropagationTypeTest.java new file mode 100644 index 0000000000..857c7a84f3 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/utils/PropagationTypeTest.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.tracing.utils; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class PropagationTypeTest { + + @Test + void forValue() { + PropagationType propagationType1 = PropagationType.forValue("W3C"); + assertEquals(PropagationType.W3C, propagationType1); + + PropagationType propagationType2 = PropagationType.forValue("B3"); + assertEquals(PropagationType.B3, propagationType2); + + PropagationType propagationType3 = PropagationType.forValue("B33"); + assertNull(propagationType3); + } +} \ No newline at end of file