From da2cc394a65cf20e7c043de285614e664895d1dc Mon Sep 17 00:00:00 2001 From: conghuhu Date: Sun, 4 Jun 2023 21:48:08 +0800 Subject: [PATCH] refactor: migrate tracing core from boot-start to dubbo deployer --- .artifacts | 1 + dubbo-cluster/pom.xml | 5 - ...che.dubbo.rpc.cluster.filter.ClusterFilter | 1 - .../filter/AbstractObservationFilterTest.java | 83 ------- .../common/constants/LoggerCodeConstants.java | 2 + .../dubbo/config/nested/BaggageConfig.java | 25 +++ .../dubbo/config/nested/ExporterConfig.java | 41 +++- .../config/nested/PropagationConfig.java | 7 + .../dubbo/config/nested/SamplingConfig.java | 7 + dubbo-config/dubbo-config-api/pom.xml | 6 + .../deploy/DefaultApplicationDeployer.java | 117 +++++----- .../DefaultApplicationDeployerTest.java | 9 +- dubbo-dependencies-bom/pom.xml | 17 +- dubbo-distribution/dubbo-all/pom.xml | 10 + dubbo-distribution/dubbo-bom/pom.xml | 7 + dubbo-distribution/dubbo-core-spi/pom.xml | 1 + dubbo-metrics/dubbo-metrics-api/pom.xml | 5 - .../apache/dubbo/metrics/aggregate/Pane.java | 0 .../metrics/aggregate/SlidingWindow.java | 0 .../metrics/utils/MetricsSupportUtil.java | 38 ++++ .../aggregate/TimeWindowAggregatorTest.java | 3 +- dubbo-metrics/dubbo-metrics-default/pom.xml | 5 - .../internal/org.apache.dubbo.rpc.Filter | 2 - dubbo-metrics/dubbo-tracing/pom.xml | 111 +++++++++ ...ractDefaultDubboObservationConvention.java | 8 +- ...faultDubboClientObservationConvention.java | 7 +- ...faultDubboServerObservationConvention.java | 4 +- .../DubboClientObservationConvention.java | 4 +- .../DubboObservationDocumentation.java | 2 +- .../tracing/DubboObservationRegistry.java | 90 ++++++++ .../DubboServerObservationConvention.java | 4 +- .../tracing/context}/DubboClientContext.java | 2 +- .../tracing/context}/DubboServerContext.java | 2 +- .../dubbo/tracing/exporter/TraceExporter.java | 37 +++ .../exporter/TraceExporterFactory.java | 66 ++++++ .../tracing/exporter/otlp/OTlpExporter.java | 66 ++++++ .../exporter/zipkin/ZipkinExporter.java | 60 +++++ .../filter}/ObservationReceiverFilter.java | 19 +- .../filter}/ObservationSenderFilter.java | 23 +- .../tracing/tracer/PropagatorProvider.java | 29 +++ .../tracer/PropagatorProviderFactory.java | 37 +++ .../dubbo/tracing/tracer/TracerProvider.java | 30 +++ .../tracing/tracer/TracerProviderFactory.java | 39 ++++ .../tracer/brave/BravePropagatorProvider.java | 31 +++ .../tracing/tracer/brave/BraveProvider.java | 41 ++++ .../tracer/otel/OTelPropagatorProvider.java | 38 ++++ .../tracer/otel/OpenTelemetryProvider.java | 212 ++++++++++++++++++ .../tracing/utils/ObservationSupportUtil.java | 49 ++++ .../internal/org.apache.dubbo.rpc.Filter | 1 + ...che.dubbo.rpc.cluster.filter.ClusterFilter | 1 + ...tDubboClientObservationConventionTest.java | 8 +- ...tDubboServerObservationConventionTest.java | 9 +- .../apache/dubbo/tracing}/MockInvocation.java | 6 +- .../AbstractObservationFilterTest.java | 8 +- .../ObservationReceiverFilterTest.java | 3 +- .../filter/ObservationSenderFilterTest.java | 14 +- .../tracer/PropagatorProviderFactoryTest.java | 34 +++ .../otel/OTelPropagatorProviderTest.java | 39 ++++ .../otel/OpenTelemetryProviderTest.java | 53 +++++ .../utils/ObservationConventionUtils.java | 7 +- .../utils/ObservationSupportUtilTest.java | 49 ++++ dubbo-metrics/pom.xml | 1 + .../observability/autoconfigure/pom.xml | 6 + .../DubboObservationAutoConfiguration.java | 19 +- .../brave/BraveAutoConfiguration.java | 18 +- .../otel/OpenTelemetryAutoConfiguration.java | 17 +- dubbo-test/dubbo-dependencies-all/pom.xml | 6 +- 67 files changed, 1456 insertions(+), 246 deletions(-) delete mode 100644 dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/AbstractObservationFilterTest.java mode change 100755 => 100644 dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/Pane.java mode change 100755 => 100644 dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/SlidingWindow.java create mode 100644 dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/utils/MetricsSupportUtil.java delete mode 100644 dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter create mode 100644 dubbo-metrics/dubbo-tracing/pom.xml rename dubbo-metrics/{dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/main/java/org/apache/dubbo/tracing}/AbstractDefaultDubboObservationConvention.java (87%) rename dubbo-metrics/{dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/main/java/org/apache/dubbo/tracing}/DefaultDubboClientObservationConvention.java (92%) rename dubbo-metrics/{dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/main/java/org/apache/dubbo/tracing}/DefaultDubboServerObservationConvention.java (94%) rename dubbo-metrics/{dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/main/java/org/apache/dubbo/tracing}/DubboClientObservationConvention.java (92%) rename dubbo-metrics/{dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/main/java/org/apache/dubbo/tracing}/DubboObservationDocumentation.java (98%) create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboObservationRegistry.java rename dubbo-metrics/{dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/main/java/org/apache/dubbo/tracing}/DubboServerObservationConvention.java (92%) rename dubbo-metrics/{dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/main/java/org/apache/dubbo/tracing/context}/DubboClientContext.java (97%) rename dubbo-metrics/{dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/main/java/org/apache/dubbo/tracing/context}/DubboServerContext.java (97%) create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/TraceExporter.java create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/TraceExporterFactory.java create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/otlp/OTlpExporter.java create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinExporter.java rename dubbo-metrics/{dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/main/java/org/apache/dubbo/tracing/filter}/ObservationReceiverFilter.java (80%) rename {dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/support => dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/filter}/ObservationSenderFilter.java (78%) create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/PropagatorProvider.java create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/PropagatorProviderFactory.java create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/TracerProvider.java create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/TracerProviderFactory.java create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/brave/BravePropagatorProvider.java create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/brave/BraveProvider.java create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/otel/OTelPropagatorProvider.java create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProvider.java create mode 100644 dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/ObservationSupportUtil.java create mode 100644 dubbo-metrics/dubbo-tracing/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter create mode 100644 dubbo-metrics/dubbo-tracing/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter rename dubbo-metrics/{dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/test/java/org/apache/dubbo/tracing}/DefaultDubboClientObservationConventionTest.java (94%) rename dubbo-metrics/{dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/test/java/org/apache/dubbo/tracing}/DefaultDubboServerObservationConventionTest.java (93%) rename dubbo-metrics/{dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/test/java/org/apache/dubbo/tracing}/MockInvocation.java (97%) rename dubbo-metrics/{dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/test/java/org/apache/dubbo/tracing/filter}/AbstractObservationFilterTest.java (94%) rename dubbo-metrics/{dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/test/java/org/apache/dubbo/tracing/filter}/ObservationReceiverFilterTest.java (99%) rename {dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster => dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing}/filter/ObservationSenderFilterTest.java (92%) create mode 100644 dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/PropagatorProviderFactoryTest.java create mode 100644 dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OTelPropagatorProviderTest.java create mode 100644 dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProviderTest.java rename dubbo-metrics/{dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/observation => dubbo-tracing/src/test/java/org/apache/dubbo/tracing}/utils/ObservationConventionUtils.java (97%) create mode 100644 dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/utils/ObservationSupportUtilTest.java diff --git a/.artifacts b/.artifacts index 539c51deeda2..e18fed5eb5ca 100644 --- a/.artifacts +++ b/.artifacts @@ -114,4 +114,5 @@ dubbo-nacos-spring-boot-starter dubbo-zookeeper-spring-boot-starter dubbo-zookeeper-curator5-spring-boot-starter dubbo-spring-security +dubbo-tracing dubbo-xds diff --git a/dubbo-cluster/pom.xml b/dubbo-cluster/pom.xml index 130b7e3f7e04..08b83b8ccaf3 100644 --- a/dubbo-cluster/pom.xml +++ b/dubbo-cluster/pom.xml @@ -86,10 +86,5 @@ ${project.parent.version} true - - io.micrometer - micrometer-tracing-integration-test - test - diff --git a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter index cd0a2f44e89a..28a9e7385369 100644 --- a/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter +++ b/dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter @@ -1,5 +1,4 @@ consumercontext=org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter consumer-classloader=org.apache.dubbo.rpc.cluster.filter.support.ConsumerClassLoaderFilter router-snapshot=org.apache.dubbo.rpc.cluster.router.RouterSnapshotFilter -observationsender=org.apache.dubbo.rpc.cluster.filter.support.ObservationSenderFilter metricsClusterFilter=org.apache.dubbo.rpc.cluster.filter.support.MetricsClusterFilter \ No newline at end of file diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/AbstractObservationFilterTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/AbstractObservationFilterTest.java deleted file mode 100644 index 2f293484b42b..000000000000 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/AbstractObservationFilterTest.java +++ /dev/null @@ -1,83 +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.rpc.cluster.filter; - -import io.micrometer.tracing.test.SampleTestRunner; -import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.config.TracingConfig; -import org.apache.dubbo.rpc.AppResponse; -import org.apache.dubbo.rpc.BaseFilter; -import org.apache.dubbo.rpc.Invoker; -import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.model.ApplicationModel; -import org.junit.jupiter.api.AfterEach; - -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; - -abstract class AbstractObservationFilterTest extends SampleTestRunner { - - ApplicationModel applicationModel; - RpcInvocation invocation; - - BaseFilter filter; - - Invoker invoker = mock(Invoker.class); - - static final String INTERFACE_NAME = "org.apache.dubbo.MockInterface"; - static final String METHOD_NAME = "mockMethod"; - static final String GROUP = "mockGroup"; - static final String VERSION = "1.0.0"; - - @AfterEach - public void teardown() { - if (applicationModel != null) { - applicationModel.destroy(); - } - } - - abstract BaseFilter createFilter(ApplicationModel applicationModel); - - void setupConfig() { - ApplicationConfig config = new ApplicationConfig(); - config.setName("MockObservations"); - - applicationModel = ApplicationModel.defaultModel(); - applicationModel.getApplicationConfigManager().setApplication(config); - - invocation = new RpcInvocation(new MockInvocation()); - invocation.addInvokedInvoker(invoker); - - applicationModel.getBeanFactory().registerBean(getObservationRegistry()); - TracingConfig tracingConfig = new TracingConfig(); - tracingConfig.setEnabled(true); - applicationModel.getApplicationConfigManager().setTracing(tracingConfig); - - filter = createFilter(applicationModel); - - given(invoker.invoke(invocation)).willReturn(new AppResponse("success")); - - initParam(); - } - - private void initParam() { - invocation.setTargetServiceUniqueName(GROUP + "/" + INTERFACE_NAME + ":" + VERSION); - invocation.setMethodName(METHOD_NAME); - invocation.setParameterTypes(new Class[] {String.class}); - } - -} diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java index 0a3bfa212576..83e7b62dfae0 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/LoggerCodeConstants.java @@ -92,6 +92,8 @@ public interface LoggerCodeConstants { String VULNERABILITY_WARNING = "0-28"; + String COMMON_NOT_FOUND_TRACER_DEPENDENCY = "0-29"; + // Registry module diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/BaggageConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/BaggageConfig.java index beba9b5ddd24..b39f0ece30d0 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/BaggageConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/BaggageConfig.java @@ -39,6 +39,19 @@ public class BaggageConfig implements Serializable { */ private List remoteFields = new ArrayList<>(); + public BaggageConfig() { + } + + public BaggageConfig(Boolean enabled) { + this.enabled = enabled; + } + + public BaggageConfig(Boolean enabled, Correlation correlation, List remoteFields) { + this.enabled = enabled; + this.correlation = correlation; + this.remoteFields = remoteFields; + } + public Boolean getEnabled() { return enabled; } @@ -76,6 +89,18 @@ public static class Correlation implements Serializable { */ private List fields = new ArrayList<>(); + public Correlation() { + } + + public Correlation(boolean enabled) { + this.enabled = enabled; + } + + public Correlation(boolean enabled, List fields) { + this.enabled = enabled; + this.fields = fields; + } + public boolean isEnabled() { return this.enabled; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/ExporterConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/ExporterConfig.java index 3b621572d034..871a5afbab2b 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/ExporterConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/ExporterConfig.java @@ -17,13 +17,13 @@ package org.apache.dubbo.config.nested; +import org.apache.dubbo.config.support.Nested; + import java.io.Serializable; import java.time.Duration; import java.util.HashMap; import java.util.Map; -import org.apache.dubbo.config.support.Nested; - public class ExporterConfig implements Serializable { @Nested @@ -56,15 +56,28 @@ public static class ZipkinConfig implements Serializable { private String endpoint; /** - * Connection timeout for requests to Zipkin. + * Connection timeout for requests to Zipkin. (seconds) */ private Duration connectTimeout = Duration.ofSeconds(1); /** - * Read timeout for requests to Zipkin. + * Read timeout for requests to Zipkin. (seconds) */ private Duration readTimeout = Duration.ofSeconds(10); + public ZipkinConfig() { + } + + public ZipkinConfig(String endpoint) { + this.endpoint = endpoint; + } + + public ZipkinConfig(String endpoint, Duration connectTimeout, Duration readTimeout) { + this.endpoint = endpoint; + this.connectTimeout = connectTimeout; + this.readTimeout = readTimeout; + } + public String getEndpoint() { return endpoint; } @@ -98,7 +111,7 @@ public static class OtlpConfig implements Serializable { private String endpoint; /** - * The maximum time to wait for the collector to process an exported batch of spans. + * The maximum time to wait for the collector to process an exported batch of spans. (seconds) */ private Duration timeout = Duration.ofSeconds(10); @@ -110,6 +123,24 @@ public static class OtlpConfig implements Serializable { private Map headers = new HashMap<>(); + public OtlpConfig() { + } + + public OtlpConfig(String endpoint) { + this.endpoint = endpoint; + } + + public OtlpConfig(String endpoint, Duration timeout) { + this.endpoint = endpoint; + this.timeout = timeout; + } + + public OtlpConfig(String endpoint, Duration timeout, String compressionMethod) { + this.endpoint = endpoint; + this.timeout = timeout; + this.compressionMethod = compressionMethod; + } + public String getEndpoint() { return endpoint; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/PropagationConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/PropagationConfig.java index 8e523533239e..c574bd0e6d5c 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/PropagationConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/PropagationConfig.java @@ -29,6 +29,13 @@ public class PropagationConfig implements Serializable { */ private String type = W3C; + public PropagationConfig() { + } + + public PropagationConfig(String type) { + this.type = type; + } + public String getType() { return type; } diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/SamplingConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/SamplingConfig.java index a605527190ca..0e98a98b5f53 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/nested/SamplingConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/nested/SamplingConfig.java @@ -25,6 +25,13 @@ public class SamplingConfig implements Serializable { */ private float probability = 0.10f; + public SamplingConfig() { + } + + public SamplingConfig(float probability) { + this.probability = probability; + } + public float getProbability() { return this.probability; } diff --git a/dubbo-config/dubbo-config-api/pom.xml b/dubbo-config/dubbo-config-api/pom.xml index fec345935069..7bd4234ebd04 100644 --- a/dubbo-config/dubbo-config-api/pom.xml +++ b/dubbo-config/dubbo-config-api/pom.xml @@ -72,6 +72,12 @@ ${project.parent.version} + + org.apache.dubbo + dubbo-tracing + ${project.parent.version} + + org.apache.dubbo dubbo-monitor-api diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java index bf8d285681aa..af73f59ad2c2 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java @@ -38,7 +38,6 @@ import org.apache.dubbo.common.threadpool.manager.ExecutorRepository; import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository; import org.apache.dubbo.common.utils.ArrayUtils; -import org.apache.dubbo.common.utils.ClassUtils; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.config.ApplicationConfig; @@ -47,6 +46,7 @@ import org.apache.dubbo.config.MetadataReportConfig; import org.apache.dubbo.config.MetricsConfig; import org.apache.dubbo.config.RegistryConfig; +import org.apache.dubbo.config.TracingConfig; import org.apache.dubbo.config.context.ConfigManager; import org.apache.dubbo.config.utils.CompositeReferenceCache; import org.apache.dubbo.config.utils.ConfigValidationUtils; @@ -60,6 +60,7 @@ import org.apache.dubbo.metrics.report.MetricsReporter; import org.apache.dubbo.metrics.report.MetricsReporterFactory; import org.apache.dubbo.metrics.service.MetricsServiceExporter; +import org.apache.dubbo.metrics.utils.MetricsSupportUtil; import org.apache.dubbo.registry.Registry; import org.apache.dubbo.registry.RegistryFactory; import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils; @@ -70,6 +71,8 @@ import org.apache.dubbo.rpc.model.ProviderModel; import org.apache.dubbo.rpc.model.ScopeModel; import org.apache.dubbo.rpc.model.ScopeModelUtil; +import org.apache.dubbo.tracing.DubboObservationRegistry; +import org.apache.dubbo.tracing.utils.ObservationSupportUtil; import java.io.IOException; import java.util.ArrayList; @@ -152,7 +155,7 @@ public DefaultApplicationDeployer(ApplicationModel applicationModel) { // load spi listener Set deployListeners = applicationModel.getExtensionLoader(ApplicationDeployListener.class) - .getSupportedExtensionInstances(); + .getSupportedExtensionInstances(); for (ApplicationDeployListener listener : deployListeners) { this.addDeployListener(listener); } @@ -226,6 +229,9 @@ public void initialize() { initMetricsService(); + // @since 3.2.3 + initObservationRegistry(); + // @since 2.7.8 startMetadataCenter(); @@ -352,17 +358,17 @@ private void useRegistryAsConfigCenterIfNecessary() { List defaultRegistries = configManager.getDefaultRegistries(); if (defaultRegistries.size() > 0) { defaultRegistries - .stream() - .filter(this::isUsedRegistryAsConfigCenter) - .map(this::registryAsConfigCenter) - .forEach(configCenter -> { - if (configManager.getConfigCenter(configCenter.getId()).isPresent()) { - return; - } - configManager.addConfigCenter(configCenter); - logger.info("use registry as config-center: " + configCenter); + .stream() + .filter(this::isUsedRegistryAsConfigCenter) + .map(this::registryAsConfigCenter) + .forEach(configCenter -> { + if (configManager.getConfigCenter(configCenter.getId()).isPresent()) { + return; + } + configManager.addConfigCenter(configCenter); + logger.info("use registry as config-center: " + configCenter); - }); + }); } } @@ -372,16 +378,16 @@ private void initMetricsService() { } private void initMetricsReporter() { - if (!isSupportMetrics()) { + if (!MetricsSupportUtil.isSupportMetrics()) { return; } DefaultMetricsCollector collector = - applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class); + applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class); Optional configOptional = configManager.getMetrics(); //If no specific metrics type is configured and there is no Prometheus dependency in the dependencies. MetricsConfig metricsConfig = configOptional.orElse(new MetricsConfig(applicationModel)); if (StringUtils.isBlank(metricsConfig.getProtocol())) { - metricsConfig.setProtocol(isSupportPrometheus() ? PROTOCOL_PROMETHEUS : PROTOCOL_DEFAULT); + metricsConfig.setProtocol(MetricsSupportUtil.isSupportPrometheus() ? PROTOCOL_PROMETHEUS : PROTOCOL_DEFAULT); } collector.setCollectEnabled(true); collector.collectApplication(); @@ -409,26 +415,35 @@ private void initMetricsReporter() { } } - public boolean isSupportMetrics() { - return isClassPresent("io.micrometer.core.instrument.MeterRegistry"); - } - - public static boolean isSupportPrometheus() { - return isClassPresent("io.micrometer.prometheus.PrometheusConfig") - && isClassPresent("io.prometheus.client.exporter.BasicAuthHttpConnectionFactory") - && isClassPresent("io.prometheus.client.exporter.HttpConnectionFactory") - && isClassPresent("io.prometheus.client.exporter.PushGateway"); - } - + /** + * init ObservationRegistry(Micrometer) + */ + private void initObservationRegistry() { + if (!ObservationSupportUtil.isSupportObservation()) { + if (logger.isDebugEnabled()) { + logger.debug("Not found micrometer-observation or plz check the version of micrometer-observation version if already introduced, need > 1.10.0"); + } + return; + } + if (!ObservationSupportUtil.isSupportTracing()) { + if (logger.isDebugEnabled()) { + logger.debug("Not found micrometer-tracing dependency, skip init ObservationRegistry."); + } + return; + } + Optional configOptional = configManager.getTracing(); + if (!configOptional.isPresent() || !configOptional.get().getEnabled()) { + return; + } - private static boolean isClassPresent(String className) { - return ClassUtils.isPresent(className, DefaultApplicationDeployer.class.getClassLoader()); + DubboObservationRegistry dubboObservationRegistry = new DubboObservationRegistry(applicationModel, configOptional.get()); + dubboObservationRegistry.initObservationRegistry(); } private boolean isUsedRegistryAsConfigCenter(RegistryConfig registryConfig) { return isUsedRegistryAsCenter(registryConfig, registryConfig::getUseAsConfigCenter, "config", - DynamicConfigurationFactory.class); + DynamicConfigurationFactory.class); } private ConfigCenterConfig registryAsConfigCenter(RegistryConfig registryConfig) { @@ -470,9 +485,9 @@ private void useRegistryAsMetadataCenterIfNecessary() { } Collection metadataConfigsToOverride = originMetadataConfigs - .stream() - .filter(m -> Objects.isNull(m.getAddress())) - .collect(Collectors.toList()); + .stream() + .filter(m -> Objects.isNull(m.getAddress())) + .collect(Collectors.toList()); if (metadataConfigsToOverride.size() > 1) { return; @@ -483,12 +498,12 @@ private void useRegistryAsMetadataCenterIfNecessary() { List defaultRegistries = configManager.getDefaultRegistries(); if (!defaultRegistries.isEmpty()) { defaultRegistries - .stream() - .filter(this::isUsedRegistryAsMetadataCenter) - .map(registryConfig -> registryAsMetadataCenter(registryConfig, metadataConfigToOverride)) - .forEach(metadataReportConfig -> { - overrideMetadataReportConfig(metadataConfigToOverride, metadataReportConfig); - }); + .stream() + .filter(this::isUsedRegistryAsMetadataCenter) + .map(registryConfig -> registryAsMetadataCenter(registryConfig, metadataConfigToOverride)) + .forEach(metadataReportConfig -> { + overrideMetadataReportConfig(metadataConfigToOverride, metadataReportConfig); + }); } } @@ -517,7 +532,7 @@ private void overrideMetadataReportConfig(MetadataReportConfig metadataConfigToO private boolean isUsedRegistryAsMetadataCenter(RegistryConfig registryConfig) { return isUsedRegistryAsCenter(registryConfig, registryConfig::getUseAsMetadataCenter, "metadata", - MetadataReportFactory.class); + MetadataReportFactory.class); } /** @@ -543,13 +558,13 @@ private boolean isUsedRegistryAsCenter(RegistryConfig registryConfig, Supplier extensionClass, String name) { private MetadataReportConfig registryAsMetadataCenter(RegistryConfig registryConfig, MetadataReportConfig originMetadataReportConfig) { MetadataReportConfig metadataReportConfig = originMetadataReportConfig == null ? - new MetadataReportConfig(registryConfig.getApplicationModel()) : originMetadataReportConfig; + new MetadataReportConfig(registryConfig.getApplicationModel()) : originMetadataReportConfig; if (metadataReportConfig.getId() == null) { metadataReportConfig.setId(registryConfig.getId()); } @@ -775,13 +790,13 @@ public void prepareInternalModule() { private void exportMetricsService() { boolean exportMetrics = applicationModel.getApplicationConfigManager().getMetrics() - .map(MetricsConfig::getExportMetricsService).orElse(true); + .map(MetricsConfig::getExportMetricsService).orElse(true); if (exportMetrics) { try { metricsServiceExporter.export(); } catch (Exception e) { logger.error(LoggerCodeConstants.COMMON_METRICS_COLLECTOR_EXCEPTION, "", "", - "exportMetricsService an exception occurred when handle starting event", e); + "exportMetricsService an exception occurred when handle starting event", e); } } } @@ -859,10 +874,10 @@ private DynamicConfiguration prepareEnvironment(ConfigCenterConfig configCenter) // Add metrics MetricsEventBus.publish(ConfigCenterEvent.toChangeEvent(applicationModel, configCenter.getConfigFile(), configCenter.getGroup(), - configCenter.getProtocol(), ConfigChangeType.ADDED.name(), configMap.size())); + configCenter.getProtocol(), ConfigChangeType.ADDED.name(), configMap.size())); if (isNotEmpty(appGroup)) { MetricsEventBus.publish(ConfigCenterEvent.toChangeEvent(applicationModel, appConfigFile, appGroup, - configCenter.getProtocol(), ConfigChangeType.ADDED.name(), appConfigMap.size())); + configCenter.getProtocol(), ConfigChangeType.ADDED.name(), appConfigMap.size())); } } catch (IOException e) { throw new IllegalStateException("Failed to parse configurations from Config Center.", e); @@ -900,10 +915,10 @@ private void registerServiceInstance() { try { registered = true; MetricsEventBus.post(RegistryEvent.toRegisterEvent(applicationModel), - () -> { - ServiceInstanceMetadataUtils.registerMetadataAndInstance(applicationModel); - return null; - } + () -> { + ServiceInstanceMetadataUtils.registerMetadataAndInstance(applicationModel); + return null; + } ); } catch (Exception e) { logger.error(CONFIG_REGISTER_INSTANCE_ERROR, "configuration server disconnected", "", "Register instance error.", e); @@ -1017,7 +1032,7 @@ private void offline() { private void doOffline(ProviderModel.RegisterStatedURL statedURL) { RegistryFactory registryFactory = - statedURL.getRegistryUrl().getOrDefaultApplicationModel().getExtensionLoader(RegistryFactory.class).getAdaptiveExtension(); + statedURL.getRegistryUrl().getOrDefaultApplicationModel().getExtensionLoader(RegistryFactory.class).getAdaptiveExtension(); Registry registry = registryFactory.getRegistry(statedURL.getRegistryUrl()); registry.unregister(statedURL.getProviderUrl()); statedURL.setRegistered(false); diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployerTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployerTest.java index fab3cf577bfb..99f94ebe49ac 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployerTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployerTest.java @@ -18,16 +18,15 @@ package org.apache.dubbo.config.deploy; import org.apache.dubbo.common.utils.Assert; -import org.apache.dubbo.rpc.model.ApplicationModel; -import org.junit.jupiter.api.Test; +import org.apache.dubbo.metrics.utils.MetricsSupportUtil; -import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; class DefaultApplicationDeployerTest { @Test void isSupportPrometheus() { - boolean supportPrometheus = new DefaultApplicationDeployer(ApplicationModel.defaultModel()).isSupportPrometheus(); - Assert.assertTrue(supportPrometheus,"DefaultApplicationDeployer.isSupportPrometheus() should return true"); + boolean supportPrometheus = MetricsSupportUtil.isSupportPrometheus(); + Assert.assertTrue(supportPrometheus, "MetricsSupportUtil.isSupportPrometheus() should return true"); } } diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 446cbae7872e..f61a49e9ad45 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -134,7 +134,8 @@ 1.8.0 0.1.35 1.11.0 - + 1.26.0 + 2.16.4 1.1.1 3.3 0.16.0 @@ -231,6 +232,20 @@ pom import + + io.opentelemetry + opentelemetry-bom + ${opentelemetry.version} + pom + import + + + io.zipkin.reporter2 + zipkin-reporter-bom + ${zipkin-reporter.version} + pom + import + io.netty netty-all diff --git a/dubbo-distribution/dubbo-all/pom.xml b/dubbo-distribution/dubbo-all/pom.xml index 3951a9fd9ddd..76fc002d1c08 100644 --- a/dubbo-distribution/dubbo-all/pom.xml +++ b/dubbo-distribution/dubbo-all/pom.xml @@ -219,6 +219,15 @@ true + + + org.apache.dubbo + dubbo-tracing + ${project.version} + compile + true + + org.apache.dubbo @@ -530,6 +539,7 @@ org.apache.dubbo:dubbo-metrics-metadata org.apache.dubbo:dubbo-metrics-config-center org.apache.dubbo:dubbo-metrics-prometheus + org.apache.dubbo:dubbo-tracing org.apache.dubbo:dubbo-monitor-api org.apache.dubbo:dubbo-monitor-default org.apache.dubbo:dubbo-qos diff --git a/dubbo-distribution/dubbo-bom/pom.xml b/dubbo-distribution/dubbo-bom/pom.xml index 2d163f10e8c5..dac1366414d3 100644 --- a/dubbo-distribution/dubbo-bom/pom.xml +++ b/dubbo-distribution/dubbo-bom/pom.xml @@ -256,6 +256,13 @@ ${project.version} + + + org.apache.dubbo + dubbo-tracing + ${project.version} + + org.apache.dubbo diff --git a/dubbo-distribution/dubbo-core-spi/pom.xml b/dubbo-distribution/dubbo-core-spi/pom.xml index 88939753e9ab..2a441485f855 100644 --- a/dubbo-distribution/dubbo-core-spi/pom.xml +++ b/dubbo-distribution/dubbo-core-spi/pom.xml @@ -134,6 +134,7 @@ org.apache.dubbo:dubbo-metadata-api org.apache.dubbo:dubbo-metrics-api org.apache.dubbo:dubbo-metrics-default + org.apache.dubbo:dubbo-tracing org.apache.dubbo:dubbo-monitor-api org.apache.dubbo:dubbo-registry-api org.apache.dubbo:dubbo-remoting-api diff --git a/dubbo-metrics/dubbo-metrics-api/pom.xml b/dubbo-metrics/dubbo-metrics-api/pom.xml index a35c23839507..3c31ae389c2e 100644 --- a/dubbo-metrics/dubbo-metrics-api/pom.xml +++ b/dubbo-metrics/dubbo-metrics-api/pom.xml @@ -49,10 +49,5 @@ com.tdunning t-digest - - io.micrometer - micrometer-tracing-integration-test - test - diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/Pane.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/Pane.java old mode 100755 new mode 100644 diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/SlidingWindow.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/SlidingWindow.java old mode 100755 new mode 100644 diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/utils/MetricsSupportUtil.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/utils/MetricsSupportUtil.java new file mode 100644 index 000000000000..e0a02f5f04c5 --- /dev/null +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/utils/MetricsSupportUtil.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.metrics.utils; + +import org.apache.dubbo.common.utils.ClassUtils; + +public class MetricsSupportUtil { + + public static boolean isSupportMetrics() { + return isClassPresent("io.micrometer.core.instrument.MeterRegistry"); + } + + public static boolean isSupportPrometheus() { + return isClassPresent("io.micrometer.prometheus.PrometheusConfig") + && isClassPresent("io.prometheus.client.exporter.BasicAuthHttpConnectionFactory") + && isClassPresent("io.prometheus.client.exporter.HttpConnectionFactory") + && isClassPresent("io.prometheus.client.exporter.PushGateway"); + } + + private static boolean isClassPresent(String className) { + return ClassUtils.isPresent(className, MetricsSupportUtil.class.getClassLoader()); + } +} diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowAggregatorTest.java b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowAggregatorTest.java index e0db96730fc3..2a660a5dd4af 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowAggregatorTest.java +++ b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowAggregatorTest.java @@ -17,8 +17,9 @@ package org.apache.dubbo.metrics.aggregate; -import org.junit.Test; + import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import java.util.concurrent.TimeUnit; diff --git a/dubbo-metrics/dubbo-metrics-default/pom.xml b/dubbo-metrics/dubbo-metrics-default/pom.xml index 71be413c6a1c..0d2fd8a6bf50 100644 --- a/dubbo-metrics/dubbo-metrics-default/pom.xml +++ b/dubbo-metrics/dubbo-metrics-default/pom.xml @@ -41,10 +41,5 @@ micrometer-test test - - io.micrometer - micrometer-tracing-integration-test - test - diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter b/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter deleted file mode 100644 index 5ee6c1d455c7..000000000000 --- a/dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter +++ /dev/null @@ -1,2 +0,0 @@ -metrics-beta=org.apache.dubbo.metrics.filter.MetricsFilter -observationreceiver=org.apache.dubbo.metrics.observation.ObservationReceiverFilter \ No newline at end of file diff --git a/dubbo-metrics/dubbo-tracing/pom.xml b/dubbo-metrics/dubbo-tracing/pom.xml new file mode 100644 index 000000000000..e50dae23bd34 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/pom.xml @@ -0,0 +1,111 @@ + + + 4.0.0 + + org.apache.dubbo + dubbo-metrics + ${revision} + ../pom.xml + + + dubbo-tracing + jar + ${project.artifactId} + The tracing module of dubbo project + + + 11 + 11 + UTF-8 + false + + + + + org.apache.dubbo + dubbo-common + ${project.parent.version} + + + org.apache.dubbo + dubbo-cluster + ${project.parent.version} + + + org.apache.dubbo + dubbo-rpc-api + ${project.parent.version} + + + org.apache.dubbo + dubbo-metrics-default + ${project.parent.version} + + + + + io.micrometer + micrometer-core + + + io.micrometer + micrometer-tracing + + + io.micrometer + micrometer-test + test + + + io.micrometer + micrometer-tracing-integration-test + test + + + + + io.micrometer + micrometer-tracing-bridge-otel + true + + + io.micrometer + micrometer-tracing-bridge-brave + true + + + + + io.opentelemetry + opentelemetry-exporter-zipkin + true + + + io.opentelemetry + opentelemetry-exporter-otlp + true + + + io.zipkin.reporter2 + zipkin-reporter-brave + true + + + \ No newline at end of file diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/AbstractDefaultDubboObservationConvention.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/AbstractDefaultDubboObservationConvention.java similarity index 87% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/AbstractDefaultDubboObservationConvention.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/AbstractDefaultDubboObservationConvention.java index 8d8e963868d0..a688a4c8262d 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/AbstractDefaultDubboObservationConvention.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/AbstractDefaultDubboObservationConvention.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing; import io.micrometer.common.KeyValues; import io.micrometer.common.docs.KeyName; @@ -25,9 +25,9 @@ import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.support.RpcUtils; -import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_METHOD; -import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_SERVICE; -import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_SYSTEM; +import static org.apache.dubbo.tracing.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_METHOD; +import static org.apache.dubbo.tracing.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_SERVICE; +import static org.apache.dubbo.tracing.DubboObservationDocumentation.LowCardinalityKeyNames.RPC_SYSTEM; class AbstractDefaultDubboObservationConvention { KeyValues getLowCardinalityKeyValues(Invocation invocation) { diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DefaultDubboClientObservationConvention.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DefaultDubboClientObservationConvention.java similarity index 92% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DefaultDubboClientObservationConvention.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DefaultDubboClientObservationConvention.java index 91e88da2a35b..481861d1f9b3 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DefaultDubboClientObservationConvention.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DefaultDubboClientObservationConvention.java @@ -14,19 +14,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing; import org.apache.dubbo.common.URL; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcContextAttachment; +import org.apache.dubbo.tracing.context.DubboClientContext; import io.micrometer.common.KeyValues; import java.util.List; -import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.NET_PEER_NAME; -import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.NET_PEER_PORT; +import static org.apache.dubbo.tracing.DubboObservationDocumentation.LowCardinalityKeyNames.NET_PEER_NAME; +import static org.apache.dubbo.tracing.DubboObservationDocumentation.LowCardinalityKeyNames.NET_PEER_PORT; /** * Default implementation of the {@link DubboClientObservationConvention}. diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DefaultDubboServerObservationConvention.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DefaultDubboServerObservationConvention.java similarity index 94% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DefaultDubboServerObservationConvention.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DefaultDubboServerObservationConvention.java index adcebdbdac8c..c78be5980691 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DefaultDubboServerObservationConvention.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DefaultDubboServerObservationConvention.java @@ -14,7 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing; + +import org.apache.dubbo.tracing.context.DubboServerContext; import io.micrometer.common.KeyValues; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboClientObservationConvention.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboClientObservationConvention.java similarity index 92% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboClientObservationConvention.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboClientObservationConvention.java index d33164294da5..5bd74dec5050 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboClientObservationConvention.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboClientObservationConvention.java @@ -14,7 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing; + +import org.apache.dubbo.tracing.context.DubboClientContext; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationConvention; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboObservationDocumentation.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboObservationDocumentation.java similarity index 98% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboObservationDocumentation.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboObservationDocumentation.java index 855a2e01e185..cd0dfe3d6173 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboObservationDocumentation.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboObservationDocumentation.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing; import io.micrometer.common.docs.KeyName; import io.micrometer.common.lang.NonNullApi; diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboObservationRegistry.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboObservationRegistry.java new file mode 100644 index 000000000000..a8497d998bc4 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboObservationRegistry.java @@ -0,0 +1,90 @@ +/* + * 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; + +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.JsonUtils; +import org.apache.dubbo.config.TracingConfig; +import org.apache.dubbo.metrics.MetricsGlobalRegistry; +import org.apache.dubbo.metrics.utils.MetricsSupportUtil; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.tracing.tracer.PropagatorProvider; +import org.apache.dubbo.tracing.tracer.PropagatorProviderFactory; +import org.apache.dubbo.tracing.tracer.TracerProvider; +import org.apache.dubbo.tracing.tracer.TracerProviderFactory; + +import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_NOT_FOUND_TRACER_DEPENDENCY; + +public class DubboObservationRegistry { + + private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(DubboObservationRegistry.class); + + private final ApplicationModel applicationModel; + + private final TracingConfig tracingConfig; + + public DubboObservationRegistry(ApplicationModel applicationModel, TracingConfig tracingConfig) { + this.applicationModel = applicationModel; + this.tracingConfig = tracingConfig; + } + + public void initObservationRegistry() { + // If get ObservationRegistry.class from external(eg Spring.), use external. + io.micrometer.observation.ObservationRegistry externalObservationRegistry = applicationModel.getBeanFactory().getBean(io.micrometer.observation.ObservationRegistry.class); + if (externalObservationRegistry != null) { + if (logger.isDebugEnabled()) { + logger.debug("ObservationRegistry.class from external is existed."); + } + return; + } + + if (logger.isDebugEnabled()) { + logger.debug("Tracing config is: " + JsonUtils.toJson(tracingConfig)); + } + + TracerProvider tracerProvider = TracerProviderFactory.getProvider(applicationModel, tracingConfig); + if (tracerProvider == null) { + logger.warn(COMMON_NOT_FOUND_TRACER_DEPENDENCY, "", "", "Can not found OpenTelemetry/Brave tracer dependencies, skip init ObservationRegistry."); + return; + } + // The real tracer will come from tracer implementation (OTel / Brave) + io.micrometer.tracing.Tracer tracer = tracerProvider.getTracer(); + + // The real propagator will come from tracer implementation (OTel / Brave) + PropagatorProvider propagatorProvider = PropagatorProviderFactory.getPropagatorProvider(); + io.micrometer.tracing.propagation.Propagator propagator = propagatorProvider != null ? propagatorProvider.getPropagator() : io.micrometer.tracing.propagation.Propagator.NOOP; + + io.micrometer.observation.ObservationRegistry registry = io.micrometer.observation.ObservationRegistry.create(); + registry.observationConfig() + // set up a first matching handler that creates spans - it comes from Micrometer Tracing. + // set up spans for sending and receiving data over the wire and a default one. + .observationHandler(new io.micrometer.observation.ObservationHandler.FirstMatchingCompositeObservationHandler( + new io.micrometer.tracing.handler.PropagatingSenderTracingObservationHandler<>(tracer, propagator), + new io.micrometer.tracing.handler.PropagatingReceiverTracingObservationHandler<>(tracer, propagator), + new io.micrometer.tracing.handler.DefaultTracingObservationHandler(tracer))); + + if (MetricsSupportUtil.isSupportMetrics()) { + io.micrometer.core.instrument.MeterRegistry meterRegistry = MetricsGlobalRegistry.getCompositeRegistry(applicationModel); + registry.observationConfig().observationHandler(new io.micrometer.core.instrument.observation.DefaultMeterObservationHandler(meterRegistry)); + } + + applicationModel.getBeanFactory().registerBean(registry); + applicationModel.getBeanFactory().registerBean(tracer); + applicationModel.getBeanFactory().registerBean(propagator); + } +} diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboServerObservationConvention.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboServerObservationConvention.java similarity index 92% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboServerObservationConvention.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboServerObservationConvention.java index 678226ee7fa3..0f7917adede9 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboServerObservationConvention.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/DubboServerObservationConvention.java @@ -14,7 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing; + +import org.apache.dubbo.tracing.context.DubboServerContext; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationConvention; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboClientContext.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/context/DubboClientContext.java similarity index 97% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboClientContext.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/context/DubboClientContext.java index 6cd559fa1e9b..f1998bc91a32 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboClientContext.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/context/DubboClientContext.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing.context; import java.util.Objects; diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboServerContext.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/context/DubboServerContext.java similarity index 97% rename from dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboServerContext.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/context/DubboServerContext.java index d4ad9d97f3ab..3e5bd13faed3 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/observation/DubboServerContext.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/context/DubboServerContext.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing.context; import io.micrometer.observation.transport.ReceiverContext; import org.apache.dubbo.rpc.Invocation; 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/exporter/TraceExporter.java new file mode 100644 index 000000000000..9b8f12ee4b60 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/TraceExporter.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.exporter; + +import brave.handler.SpanHandler; +import io.opentelemetry.sdk.trace.export.SpanExporter; + +public interface TraceExporter { + + /** + * for otel + * + * @return + */ + SpanExporter getSpanExporter(); + + /** + * for brave + * + * @return + */ + SpanHandler getSpanHandler(); +} 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 new file mode 100644 index 000000000000..7327cf038e0d --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/TraceExporterFactory.java @@ -0,0 +1,66 @@ +/* + * 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/OTlpExporter.java new file mode 100644 index 000000000000..72da78a79533 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/otlp/OTlpExporter.java @@ -0,0 +1,66 @@ +/* + * 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 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; +import io.opentelemetry.sdk.trace.export.SpanExporter; + +import java.util.Map; + +public class OTlpExporter implements TraceExporter { + + 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() { + OtlpGrpcSpanExporter externalOTlpGrpcSpanExporter = applicationModel.getBeanFactory().getBean(OtlpGrpcSpanExporter.class); + if (externalOTlpGrpcSpanExporter != null) { + return externalOTlpGrpcSpanExporter; + } + OtlpHttpSpanExporter externalOtlpHttpSpanExporter = applicationModel.getBeanFactory().getBean(OtlpHttpSpanExporter.class); + if (externalOtlpHttpSpanExporter != null) { + return externalOtlpHttpSpanExporter; + } + OtlpGrpcSpanExporterBuilder builder = OtlpGrpcSpanExporter.builder() + .setEndpoint(otlpConfig.getEndpoint()) + .setTimeout(otlpConfig.getTimeout()) + .setCompression(otlpConfig.getCompressionMethod()); + for (Map.Entry entry : otlpConfig.getHeaders().entrySet()) { + builder.addHeader(entry.getKey(), entry.getValue()); + } + 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/ZipkinExporter.java new file mode 100644 index 000000000000..c0c00c6fa8e1 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/exporter/zipkin/ZipkinExporter.java @@ -0,0 +1,60 @@ +/* + * 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 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 { + + 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) + .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); + return encoder == null ? SpanBytesEncoder.JSON_V2 : encoder; + } +} diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilter.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/filter/ObservationReceiverFilter.java similarity index 80% rename from dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilter.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/filter/ObservationReceiverFilter.java index 5a33ced4373b..25b7008c673f 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilter.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/filter/ObservationReceiverFilter.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing.filter; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.rpc.BaseFilter; @@ -25,6 +25,10 @@ import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ScopeModelAware; +import org.apache.dubbo.tracing.DefaultDubboServerObservationConvention; +import org.apache.dubbo.tracing.DubboObservationDocumentation; +import org.apache.dubbo.tracing.DubboServerObservationConvention; +import org.apache.dubbo.tracing.context.DubboServerContext; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; @@ -34,7 +38,7 @@ /** * A {@link Filter} that creates an {@link Observation} around the incoming message. */ -@Activate(group = PROVIDER, order = -1, onClass = "io.micrometer.observation.NoopObservationRegistry") +@Activate(group = PROVIDER, order = Integer.MIN_VALUE + 50, onClass = "io.micrometer.observation.NoopObservationRegistry") public class ObservationReceiverFilter implements Filter, BaseFilter.Listener, ScopeModelAware { private ObservationRegistry observationRegistry; @@ -42,12 +46,8 @@ public class ObservationReceiverFilter implements Filter, BaseFilter.Listener, S private DubboServerObservationConvention serverObservationConvention; public ObservationReceiverFilter(ApplicationModel applicationModel) { - applicationModel.getApplicationConfigManager().getTracing().ifPresent(cfg -> { - if (Boolean.TRUE.equals(cfg.getEnabled())) { - observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class); - serverObservationConvention = applicationModel.getBeanFactory().getBean(DubboServerObservationConvention.class); - } - }); + observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class); + serverObservationConvention = applicationModel.getBeanFactory().getBean(DubboServerObservationConvention.class); } @Override @@ -70,6 +70,9 @@ public void onResponse(Result appResponse, Invoker invoker, Invocation invoca if (observation == null) { return; } + if (appResponse != null && appResponse.hasException()) { + observation.error(appResponse.getException()); + } observation.stop(); } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/support/ObservationSenderFilter.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/filter/ObservationSenderFilter.java similarity index 78% rename from dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/support/ObservationSenderFilter.java rename to dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/filter/ObservationSenderFilter.java index 233a5ed35b5c..bce47b7b9a40 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/support/ObservationSenderFilter.java +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/filter/ObservationSenderFilter.java @@ -14,13 +14,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.rpc.cluster.filter.support; +package org.apache.dubbo.tracing.filter; import org.apache.dubbo.common.extension.Activate; -import org.apache.dubbo.metrics.observation.DefaultDubboClientObservationConvention; -import org.apache.dubbo.metrics.observation.DubboClientContext; -import org.apache.dubbo.metrics.observation.DubboClientObservationConvention; -import org.apache.dubbo.metrics.observation.DubboObservationDocumentation; import org.apache.dubbo.rpc.BaseFilter; import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Invocation; @@ -30,6 +26,10 @@ import org.apache.dubbo.rpc.cluster.filter.ClusterFilter; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ScopeModelAware; +import org.apache.dubbo.tracing.DefaultDubboClientObservationConvention; +import org.apache.dubbo.tracing.DubboClientObservationConvention; +import org.apache.dubbo.tracing.DubboObservationDocumentation; +import org.apache.dubbo.tracing.context.DubboClientContext; import io.micrometer.observation.Observation; import io.micrometer.observation.ObservationRegistry; @@ -39,7 +39,7 @@ /** * A {@link Filter} that creates an {@link Observation} around the outgoing message. */ -@Activate(group = CONSUMER, order = -1, onClass = "io.micrometer.observation.NoopObservationRegistry") +@Activate(group = CONSUMER, order = Integer.MIN_VALUE + 50, onClass = "io.micrometer.observation.NoopObservationRegistry") public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listener, ScopeModelAware { private ObservationRegistry observationRegistry; @@ -47,12 +47,8 @@ public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listen private DubboClientObservationConvention clientObservationConvention; public ObservationSenderFilter(ApplicationModel applicationModel) { - applicationModel.getApplicationConfigManager().getTracing().ifPresent(cfg -> { - if (Boolean.TRUE.equals(cfg.getEnabled())) { - observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class); - clientObservationConvention = applicationModel.getBeanFactory().getBean(DubboClientObservationConvention.class); - } - }); + observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class); + clientObservationConvention = applicationModel.getBeanFactory().getBean(DubboClientObservationConvention.class); } @Override @@ -75,6 +71,9 @@ public void onResponse(Result appResponse, Invoker invoker, Invocation invoca if (observation == null) { return; } + if (appResponse != null && appResponse.hasException()) { + observation.error(appResponse.getException()); + } observation.stop(); } diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/PropagatorProvider.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/PropagatorProvider.java new file mode 100644 index 000000000000..dc9b58f4e06c --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/PropagatorProvider.java @@ -0,0 +1,29 @@ +/* + * 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; + +import io.micrometer.tracing.propagation.Propagator; + +public interface PropagatorProvider { + + /** + * The real propagator will come from tracer implementation (OTel / Brave) + * + * @return Propagator + */ + Propagator getPropagator(); +} diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/PropagatorProviderFactory.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/PropagatorProviderFactory.java new file mode 100644 index 000000000000..066cb7ad63d6 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/PropagatorProviderFactory.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.tracer; + +import org.apache.dubbo.tracing.tracer.brave.BravePropagatorProvider; +import org.apache.dubbo.tracing.tracer.otel.OTelPropagatorProvider; +import org.apache.dubbo.tracing.utils.ObservationSupportUtil; + +public class PropagatorProviderFactory { + + public static PropagatorProvider getPropagatorProvider() { + // If support OTel firstly, return OTel, then Brave. + if (ObservationSupportUtil.isSupportOTelTracer()) { + return new OTelPropagatorProvider(); + } + + if (ObservationSupportUtil.isSupportBraveTracer()) { + return new BravePropagatorProvider(); + } + + return null; + } +} diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/TracerProvider.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/TracerProvider.java new file mode 100644 index 000000000000..05305ada67af --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/TracerProvider.java @@ -0,0 +1,30 @@ +/* + * 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; + +import io.micrometer.tracing.Tracer; + +public interface TracerProvider { + + /** + * Tracer of Micrometer. The real tracer will come from tracer implementation (OTel / Brave) + * + * @return Tracer + */ + Tracer getTracer(); + +} diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/TracerProviderFactory.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/TracerProviderFactory.java new file mode 100644 index 000000000000..7e325809cb60 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/TracerProviderFactory.java @@ -0,0 +1,39 @@ +/* + * 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; + +import org.apache.dubbo.config.TracingConfig; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.tracing.tracer.brave.BraveProvider; +import org.apache.dubbo.tracing.tracer.otel.OpenTelemetryProvider; +import org.apache.dubbo.tracing.utils.ObservationSupportUtil; + +public class TracerProviderFactory { + + public static TracerProvider getProvider(ApplicationModel applicationModel, TracingConfig tracingConfig) { + // If support OTel firstly, return OTel, then Brave. + if (ObservationSupportUtil.isSupportOTelTracer()) { + return new OpenTelemetryProvider(applicationModel, tracingConfig); + } + + if (ObservationSupportUtil.isSupportBraveTracer()) { + return new BraveProvider(applicationModel, tracingConfig); + } + + return null; + } +} 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 new file mode 100644 index 000000000000..8560a5b1494e --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/brave/BravePropagatorProvider.java @@ -0,0 +1,31 @@ +/* + * 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.tracing.tracer.PropagatorProvider; + +import io.micrometer.tracing.propagation.Propagator; + + +public class BravePropagatorProvider implements PropagatorProvider { + + @Override + public Propagator getPropagator() { + // TODO impl + return null; + } +} 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 new file mode 100644 index 000000000000..9ab8172b02eb --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/brave/BraveProvider.java @@ -0,0 +1,41 @@ +/* + * 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.config.TracingConfig; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.tracing.tracer.TracerProvider; + +import io.micrometer.tracing.Tracer; + + +public class BraveProvider implements TracerProvider { + + private final ApplicationModel applicationModel; + private final TracingConfig tracingConfig; + + public BraveProvider(ApplicationModel applicationModel, TracingConfig tracingConfig) { + this.applicationModel = applicationModel; + this.tracingConfig = tracingConfig; + } + + @Override + public Tracer getTracer() { + // TODO impl + return null; + } +} diff --git a/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/otel/OTelPropagatorProvider.java b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/otel/OTelPropagatorProvider.java new file mode 100644 index 000000000000..9f537f1e4d65 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/otel/OTelPropagatorProvider.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.otel; + +import org.apache.dubbo.tracing.tracer.PropagatorProvider; + +import io.micrometer.tracing.otel.bridge.OtelPropagator; +import io.micrometer.tracing.propagation.Propagator; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.propagation.ContextPropagators; + +public class OTelPropagatorProvider implements PropagatorProvider { + + private static Propagator propagator; + + @Override + public Propagator getPropagator() { + return propagator; + } + + protected static void createMicrometerPropagator(ContextPropagators contextPropagators, Tracer tracer) { + propagator = new OtelPropagator(contextPropagators, tracer); + } +} 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 new file mode 100644 index 000000000000..36b3c3f19117 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProvider.java @@ -0,0 +1,212 @@ +/* + * 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.otel; + +import org.apache.dubbo.common.Version; +import org.apache.dubbo.common.lang.Nullable; +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.PropagationConfig; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.tracing.exporter.TraceExporterFactory; +import org.apache.dubbo.tracing.tracer.TracerProvider; + +import io.micrometer.tracing.Tracer; +import io.micrometer.tracing.otel.bridge.CompositeSpanExporter; +import io.micrometer.tracing.otel.bridge.EventListener; +import io.micrometer.tracing.otel.bridge.EventPublishingContextWrapper; +import io.micrometer.tracing.otel.bridge.OtelBaggageManager; +import io.micrometer.tracing.otel.bridge.OtelCurrentTraceContext; +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; + +public class OpenTelemetryProvider implements TracerProvider { + + private static final String DEFAULT_APPLICATION_NAME = "dubbo-application"; + private final ApplicationModel applicationModel; + private final TracingConfig tracingConfig; + + private OTelEventPublisher publisher; + private OtelCurrentTraceContext otelCurrentTraceContext; + + public OpenTelemetryProvider(ApplicationModel applicationModel, TracingConfig tracingConfig) { + this.applicationModel = applicationModel; + this.tracingConfig = tracingConfig; + } + + @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()); + + String applicationName = applicationModel.getApplicationConfigManager().getApplication() + .map(ApplicationConfig::getName) + .orElse(DEFAULT_APPLICATION_NAME); + + this.publisher = new OTelEventPublisher(getEventListeners()); + + // [Micrometer Tracing component] A Micrometer Tracing wrapper for OTel + this.otelCurrentTraceContext = createCurrentTraceContext(); + + // [OTel component] SdkTracerProvider is an SDK implementation for TracerProvider + SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder() + .setSampler(getSampler()) + .setResource(Resource.create(Attributes.of(ResourceAttributes.SERVICE_NAME, applicationName))) + .addSpanProcessor(BatchSpanProcessor + .builder(new CompositeSpanExporter(spanExporters, null, null, null)) + .build()) + .build(); + + ContextPropagators otelContextPropagators = createOtelContextPropagators(); + + // [OTel component] The SDK implementation of OpenTelemetry + OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder() + .setTracerProvider(sdkTracerProvider) + .setPropagators(otelContextPropagators) + .build(); + + // [OTel component] Tracer is a component that handles the life-cycle of a span + io.opentelemetry.api.trace.Tracer otelTracer = openTelemetrySdk.getTracerProvider() + .get("org.apache.dubbo", Version.getVersion()); + + OTelPropagatorProvider.createMicrometerPropagator(otelContextPropagators, otelTracer); + + // [Micrometer Tracing component] A Micrometer Tracing wrapper for OTel's Tracer. + return new OtelTracer(otelTracer, otelCurrentTraceContext, publisher, + new OtelBaggageManager(otelCurrentTraceContext, + tracingConfig.getBaggage().getRemoteFields(), + Collections.emptyList())); + } + + /** + * sampler with probability + * + * @return sampler + */ + private Sampler getSampler() { + Sampler rootSampler = Sampler.traceIdRatioBased(tracingConfig.getSampling().getProbability()); + return Sampler.parentBased(rootSampler); + } + + private List getEventListeners() { + List listeners = new ArrayList<>(); + + // [Micrometer Tracing component] A Micrometer Tracing listener for setting up MDC. + Slf4JEventListener slf4JEventListener = new Slf4JEventListener(); + listeners.add(slf4JEventListener); + + if (tracingConfig.getBaggage().getEnabled()) { + // [Micrometer Tracing component] A Micrometer Tracing listener for setting Baggage in MDC. + // Customizable with correlation fields. + Slf4JBaggageEventListener slf4JBaggageEventListener = new Slf4JBaggageEventListener(tracingConfig.getBaggage().getCorrelation().getFields()); + listeners.add(slf4JBaggageEventListener); + } + + return listeners; + } + + private OtelCurrentTraceContext createCurrentTraceContext() { + ContextStorage.addWrapper(new EventPublishingContextWrapper(publisher)); + return new OtelCurrentTraceContext(); + } + + private ContextPropagators createOtelContextPropagators() { + return ContextPropagators.create( + TextMapPropagator.composite( + PropagatorFactory.getPropagator(tracingConfig.getPropagation(), + tracingConfig.getBaggage(), + otelCurrentTraceContext + ))); + } + + static class OTelEventPublisher implements OtelTracer.EventPublisher { + + private final List listeners; + + OTelEventPublisher(List listeners) { + this.listeners = listeners; + } + + @Override + public void publishEvent(Object event) { + for (EventListener listener : this.listeners) { + listener.onEvent(event); + } + } + } + + static class PropagatorFactory { + + public static 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) { + String type = propagationConfig.getType(); + if ("B3".equals(type)) { + return B3Propagator.injectingSingleHeader(); + } else if ("W3C".equals(type)) { + return W3CTraceContextPropagator.getInstance(); + } + return TextMapPropagator.noop(); + } + + private static TextMapPropagator getPropagatorWithBaggage(PropagationConfig propagationConfig, + BaggageConfig baggageConfig, + OtelCurrentTraceContext currentTraceContext) { + String type = propagationConfig.getType(); + if ("B3".equals(type)) { + List remoteFields = baggageConfig.getRemoteFields(); + return TextMapPropagator.composite(B3Propagator.injectingSingleHeader(), + new BaggageTextMapPropagator(remoteFields, + new OtelBaggageManager(currentTraceContext, remoteFields, Collections.emptyList()))); + } else if ("W3C".equals(type)) { + List remoteFields = baggageConfig.getRemoteFields(); + return TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(), + W3CBaggagePropagator.getInstance(), new BaggageTextMapPropagator(remoteFields, + new OtelBaggageManager(currentTraceContext, remoteFields, Collections.emptyList()))); + } + return TextMapPropagator.noop(); + } + } +} 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 new file mode 100644 index 000000000000..4cf8e05edf60 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/java/org/apache/dubbo/tracing/utils/ObservationSupportUtil.java @@ -0,0 +1,49 @@ +/* + * 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.apache.dubbo.common.utils.ClassUtils; + +public class ObservationSupportUtil { + + public static boolean isSupportObservation() { + return isClassPresent("io.micrometer.observation.Observation") + && isClassPresent("io.micrometer.observation.ObservationRegistry") + && isClassPresent("io.micrometer.observation.ObservationHandler"); + } + + public static boolean isSupportTracing() { + return isClassPresent("io.micrometer.tracing.Tracer") + && isClassPresent("io.micrometer.tracing.propagation.Propagator"); + } + + public static boolean isSupportOTelTracer() { + return isClassPresent("io.micrometer.tracing.otel.bridge.OtelTracer") + && isClassPresent("io.opentelemetry.sdk.trace.SdkTracerProvider") + && isClassPresent("io.opentelemetry.api.OpenTelemetry"); + } + + public static boolean isSupportBraveTracer() { + return isClassPresent("io.micrometer.tracing.Tracer") + && isClassPresent("io.micrometer.tracing.brave.bridge.BraveTracer") + && isClassPresent("brave.Tracing"); + } + + private static boolean isClassPresent(String className) { + return ClassUtils.isPresent(className, ObservationSupportUtil.class.getClassLoader()); + } +} diff --git a/dubbo-metrics/dubbo-tracing/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter b/dubbo-metrics/dubbo-tracing/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter new file mode 100644 index 000000000000..a7efac7c5e16 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter @@ -0,0 +1 @@ +observationreceiver=org.apache.dubbo.tracing.filter.ObservationReceiverFilter \ No newline at end of file diff --git a/dubbo-metrics/dubbo-tracing/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter b/dubbo-metrics/dubbo-tracing/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter new file mode 100644 index 000000000000..f13199c6665e --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter @@ -0,0 +1 @@ +observationsender=org.apache.dubbo.tracing.filter.ObservationSenderFilter \ No newline at end of file diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/observation/DefaultDubboClientObservationConventionTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/DefaultDubboClientObservationConventionTest.java similarity index 94% rename from dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/observation/DefaultDubboClientObservationConventionTest.java rename to dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/DefaultDubboClientObservationConventionTest.java index 8b91e2531d55..0f1e641c4a6a 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/observation/DefaultDubboClientObservationConventionTest.java +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/DefaultDubboClientObservationConventionTest.java @@ -14,12 +14,14 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing; -import io.micrometer.common.KeyValues; -import org.apache.dubbo.metrics.observation.utils.ObservationConventionUtils; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcInvocation; +import org.apache.dubbo.tracing.context.DubboClientContext; +import org.apache.dubbo.tracing.utils.ObservationConventionUtils; + +import io.micrometer.common.KeyValues; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/observation/DefaultDubboServerObservationConventionTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/DefaultDubboServerObservationConventionTest.java similarity index 93% rename from dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/observation/DefaultDubboServerObservationConventionTest.java rename to dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/DefaultDubboServerObservationConventionTest.java index faa49457e774..95a755cd9806 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/observation/DefaultDubboServerObservationConventionTest.java +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/DefaultDubboServerObservationConventionTest.java @@ -14,12 +14,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing; -import io.micrometer.common.KeyValues; -import org.apache.dubbo.metrics.observation.utils.ObservationConventionUtils; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcInvocation; +import org.apache.dubbo.tracing.context.DubboClientContext; +import org.apache.dubbo.tracing.context.DubboServerContext; +import org.apache.dubbo.tracing.utils.ObservationConventionUtils; + +import io.micrometer.common.KeyValues; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/MockInvocation.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/MockInvocation.java similarity index 97% rename from dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/MockInvocation.java rename to dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/MockInvocation.java index 8cb43471d83e..cd9c0335dd9f 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/MockInvocation.java +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/MockInvocation.java @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing; import org.apache.dubbo.rpc.AttachmentsAdapter; import org.apache.dubbo.rpc.Invoker; @@ -68,11 +68,11 @@ public String getServiceName() { } public Class[] getParameterTypes() { - return new Class[] {String.class}; + return new Class[]{String.class}; } public Object[] getArguments() { - return new Object[] {"aa"}; + return new Object[]{"aa"}; } public Map getAttachments() { diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/AbstractObservationFilterTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/filter/AbstractObservationFilterTest.java similarity index 94% rename from dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/AbstractObservationFilterTest.java rename to dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/filter/AbstractObservationFilterTest.java index 99bf615947cc..046a0f1f9512 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/AbstractObservationFilterTest.java +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/filter/AbstractObservationFilterTest.java @@ -15,9 +15,8 @@ * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing.filter; -import io.micrometer.tracing.test.SampleTestRunner; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.TracingConfig; import org.apache.dubbo.rpc.AppResponse; @@ -25,6 +24,9 @@ import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcInvocation; import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.tracing.MockInvocation; + +import io.micrometer.tracing.test.SampleTestRunner; import org.junit.jupiter.api.AfterEach; import static org.mockito.BDDMockito.given; @@ -78,7 +80,7 @@ void setupConfig() { private void initParam() { invocation.setTargetServiceUniqueName(GROUP + "/" + INTERFACE_NAME + ":" + VERSION); invocation.setMethodName(METHOD_NAME); - invocation.setParameterTypes(new Class[] {String.class}); + invocation.setParameterTypes(new Class[]{String.class}); } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilterTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/filter/ObservationReceiverFilterTest.java similarity index 99% rename from dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilterTest.java rename to dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/filter/ObservationReceiverFilterTest.java index 1fe702e1939b..4cb02824303e 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/observation/ObservationReceiverFilterTest.java +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/filter/ObservationReceiverFilterTest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.apache.dubbo.metrics.observation; +package org.apache.dubbo.tracing.filter; import io.micrometer.common.KeyValues; import io.micrometer.core.tck.MeterRegistryAssert; @@ -31,6 +31,7 @@ import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.model.ApplicationModel; + import org.assertj.core.api.BDDAssertions; class ObservationReceiverFilterTest extends AbstractObservationFilterTest { diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/ObservationSenderFilterTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/filter/ObservationSenderFilterTest.java similarity index 92% rename from dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/ObservationSenderFilterTest.java rename to dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/filter/ObservationSenderFilterTest.java index 81662034003a..071bc0e978bd 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/ObservationSenderFilterTest.java +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/filter/ObservationSenderFilterTest.java @@ -15,22 +15,22 @@ * limitations under the License. */ -package org.apache.dubbo.rpc.cluster.filter; +package org.apache.dubbo.tracing.filter; -import io.micrometer.common.KeyValues; -import io.micrometer.core.tck.MeterRegistryAssert; -import io.micrometer.tracing.test.SampleTestRunner; -import io.micrometer.tracing.test.simple.SpansAssert; import org.apache.dubbo.common.URL; import org.apache.dubbo.rpc.RpcContext; -import org.apache.dubbo.rpc.cluster.filter.support.ObservationSenderFilter; +import org.apache.dubbo.rpc.cluster.filter.ClusterFilter; import org.apache.dubbo.rpc.model.ApplicationModel; + +import io.micrometer.common.KeyValues; +import io.micrometer.core.tck.MeterRegistryAssert; +import io.micrometer.tracing.test.simple.SpansAssert; import org.assertj.core.api.BDDAssertions; class ObservationSenderFilterTest extends AbstractObservationFilterTest { @Override - public SampleTestRunner.SampleTestRunnerConsumer yourCode() { + public SampleTestRunnerConsumer yourCode() { return (buildingBlocks, meterRegistry) -> { setupConfig(); setupAttachments(); diff --git a/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/PropagatorProviderFactoryTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/PropagatorProviderFactoryTest.java new file mode 100644 index 000000000000..18f1a74e0e4e --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/PropagatorProviderFactoryTest.java @@ -0,0 +1,34 @@ +/* + * 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; + +import org.apache.dubbo.common.utils.Assert; +import org.apache.dubbo.tracing.tracer.otel.OTelPropagatorProvider; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class PropagatorProviderFactoryTest { + + @Test + void testPropagatorProviderFactory() { + PropagatorProvider propagatorProvider = PropagatorProviderFactory.getPropagatorProvider(); + Assert.notNull(propagatorProvider, "PropagatorProvider should not be null"); + assertEquals(OTelPropagatorProvider.class, propagatorProvider.getClass()); + } +} \ 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 new file mode 100644 index 000000000000..83f2cd2df0f3 --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OTelPropagatorProviderTest.java @@ -0,0 +1,39 @@ +/* + * 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.otel; + +import org.apache.dubbo.common.utils.Assert; + +import io.micrometer.tracing.propagation.Propagator; +import io.opentelemetry.api.trace.Tracer; +import io.opentelemetry.context.propagation.ContextPropagators; +import org.junit.jupiter.api.Test; + +import static org.mockito.Mockito.mock; + +class OTelPropagatorProviderTest { + + @Test + void testOTelPropagatorProvider() { + ContextPropagators contextPropagators = mock(ContextPropagators.class); + Tracer tracer = mock(Tracer.class); + OTelPropagatorProvider.createMicrometerPropagator(contextPropagators, tracer); + OTelPropagatorProvider oTelPropagatorProvider = new OTelPropagatorProvider(); + Propagator propagator = oTelPropagatorProvider.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/otel/OpenTelemetryProviderTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProviderTest.java new file mode 100644 index 000000000000..0374912c3aaf --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/tracer/otel/OpenTelemetryProviderTest.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.tracer.otel; + +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.rpc.model.ApplicationModel; +import org.apache.dubbo.tracing.tracer.TracerProvider; +import org.apache.dubbo.tracing.tracer.TracerProviderFactory; + +import io.micrometer.tracing.Tracer; +import io.micrometer.tracing.otel.bridge.OtelTracer; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class OpenTelemetryProviderTest { + + @Test + void testGetTracer() { + TracingConfig tracingConfig = new TracingConfig(); + tracingConfig.setEnabled(true); + ExporterConfig exporterConfig = new ExporterConfig(); + exporterConfig.setZipkinConfig(new ExporterConfig.ZipkinConfig("")); + tracingConfig.setTracingExporter(exporterConfig); + TracerProvider tracerProvider1 = TracerProviderFactory.getProvider(ApplicationModel.defaultModel(), tracingConfig); + Assert.notNull(tracerProvider1, "TracerProvider should not be null."); + Tracer tracer1 = tracerProvider1.getTracer(); + assertEquals(OtelTracer.class, tracer1.getClass()); + + tracingConfig.setBaggage(new BaggageConfig(false)); + TracerProvider tracerProvider2 = TracerProviderFactory.getProvider(ApplicationModel.defaultModel(), tracingConfig); + Assert.notNull(tracerProvider2, "TracerProvider should not be null."); + Tracer tracer2 = tracerProvider2.getTracer(); + assertEquals(OtelTracer.class, tracer2.getClass()); + } +} \ No newline at end of file diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/observation/utils/ObservationConventionUtils.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/utils/ObservationConventionUtils.java similarity index 97% rename from dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/observation/utils/ObservationConventionUtils.java rename to dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/utils/ObservationConventionUtils.java index 4bf2abfa1edb..f0b75c8c2c5c 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/observation/utils/ObservationConventionUtils.java +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/utils/ObservationConventionUtils.java @@ -14,12 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.dubbo.metrics.observation.utils; +package org.apache.dubbo.tracing.utils; -import io.micrometer.common.KeyValue; -import io.micrometer.common.KeyValues; import org.apache.dubbo.common.URL; import org.apache.dubbo.rpc.Invoker; + +import io.micrometer.common.KeyValue; +import io.micrometer.common.KeyValues; import org.mockito.Mockito; import java.lang.reflect.Field; diff --git a/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/utils/ObservationSupportUtilTest.java b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/utils/ObservationSupportUtilTest.java new file mode 100644 index 000000000000..3903053ca8fb --- /dev/null +++ b/dubbo-metrics/dubbo-tracing/src/test/java/org/apache/dubbo/tracing/utils/ObservationSupportUtilTest.java @@ -0,0 +1,49 @@ +/* + * 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.apache.dubbo.common.utils.Assert; + +import org.junit.jupiter.api.Test; + +public class ObservationSupportUtilTest { + + @Test + void testIsSupportObservation() { + boolean supportObservation = ObservationSupportUtil.isSupportObservation(); + Assert.assertTrue(supportObservation, "ObservationSupportUtil.isSupportObservation() should return true"); + } + + @Test + void testIsSupportTracing() { + boolean supportTracing = ObservationSupportUtil.isSupportTracing(); + Assert.assertTrue(supportTracing, "ObservationSupportUtil.isSupportTracing() should return true"); + } + + @Test + void testIsSupportOTelTracer() { + boolean supportOTelTracer = ObservationSupportUtil.isSupportOTelTracer(); + Assert.assertTrue(supportOTelTracer, "ObservationSupportUtil.isSupportOTelTracer() should return true"); + } + + @Test + void testIsSupportBraveTracer() { + boolean supportBraveTracer = ObservationSupportUtil.isSupportBraveTracer(); + Assert.assertTrue(supportBraveTracer, "ObservationSupportUtil.isSupportOTelTracer() should return true"); + } +} diff --git a/dubbo-metrics/pom.xml b/dubbo-metrics/pom.xml index 04abd6e0777e..c10defb8d6df 100644 --- a/dubbo-metrics/pom.xml +++ b/dubbo-metrics/pom.xml @@ -24,6 +24,7 @@ dubbo-metrics-metadata dubbo-metrics-prometheus dubbo-metrics-config-center + dubbo-tracing org.apache.dubbo diff --git a/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/pom.xml b/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/pom.xml index b9e13695564d..e8d997bda9dd 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/pom.xml +++ b/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/pom.xml @@ -137,6 +137,12 @@ ${project.version} true + + org.apache.dubbo + dubbo-config-spring + ${project.version} + true + diff --git a/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java index 37f552fadff3..10ffaa9be1db 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java +++ b/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/DubboObservationAutoConfiguration.java @@ -18,6 +18,7 @@ import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.config.spring.context.event.DubboConfigInitEvent; import org.apache.dubbo.qos.protocol.QosProtocolWrapper; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.spring.boot.observability.autoconfigure.annotation.ConditionalOnDubboTracingEnable; @@ -28,14 +29,15 @@ import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass; +import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; import java.util.Arrays; @@ -46,7 +48,7 @@ @AutoConfiguration(after = DubboMicrometerTracingAutoConfiguration.class, afterName = "org.springframework.boot.actuate.autoconfigure.observation.ObservationAutoConfiguration") @ConditionalOnDubboTracingEnable @ConditionalOnClass(name = {"io.micrometer.observation.Observation", "io.micrometer.tracing.Tracer"}) -public class DubboObservationAutoConfiguration implements BeanFactoryAware, SmartInitializingSingleton { +public class DubboObservationAutoConfiguration implements BeanFactoryAware, ApplicationListener, Ordered { private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(QosProtocolWrapper.class); @@ -79,16 +81,21 @@ public void setBeanFactory(BeanFactory beanFactory) throws BeansException { } @Override - public void afterSingletonsInstantiated() { + public void onApplicationEvent(DubboConfigInitEvent event) { try { applicationModel.getBeanFactory().registerBean(beanFactory.getBean(io.micrometer.observation.ObservationRegistry.class)); - io.micrometer.tracing.Tracer bean = beanFactory.getBean(io.micrometer.tracing.Tracer.class); - applicationModel.getBeanFactory().registerBean(bean); + applicationModel.getBeanFactory().registerBean(beanFactory.getBean(io.micrometer.tracing.Tracer.class)); + applicationModel.getBeanFactory().registerBean(beanFactory.getBean(io.micrometer.tracing.propagation.Propagator.class)); } catch (NoSuchBeanDefinitionException e) { - logger.info("Please use a version of micrometer higher than 1.10.0 :{}" + e.getMessage()); + logger.info("Please use a version of micrometer higher than 1.10.0: " + e.getMessage()); } } + @Override + public int getOrder() { + return HIGHEST_PRECEDENCE; + } + @Configuration(proxyBeanMethods = false) @ConditionalOnClass(MeterRegistry.class) @ConditionalOnMissingClass("io.micrometer.tracing.Tracer") diff --git a/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/brave/BraveAutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/brave/BraveAutoConfiguration.java index 24be95c4ec51..8894b890cbac 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/brave/BraveAutoConfiguration.java +++ b/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/brave/BraveAutoConfiguration.java @@ -16,8 +16,7 @@ */ package org.apache.dubbo.spring.boot.observability.autoconfigure.brave; -import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.rpc.model.ModuleModel; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.spring.boot.autoconfigure.DubboConfigurationProperties; import org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration; import org.apache.dubbo.spring.boot.observability.autoconfigure.ObservabilityUtils; @@ -53,12 +52,12 @@ public class BraveAutoConfiguration { /** * Default value for application name if {@code spring.application.name} is not set. */ - private static final String DEFAULT_APPLICATION_NAME = "application"; + private static final String DEFAULT_APPLICATION_NAME = "dubbo-application"; - private final ModuleModel moduleModel; + private final DubboConfigurationProperties dubboConfigProperties; - public BraveAutoConfiguration(ModuleModel moduleModel) { - this.moduleModel = moduleModel; + public BraveAutoConfiguration(DubboConfigurationProperties dubboConfigProperties) { + this.dubboConfigProperties = dubboConfigProperties; } @Bean @@ -76,9 +75,10 @@ io.micrometer.tracing.brave.bridge.CompositeSpanHandler compositeSpanHandler(Obj public brave.Tracing braveTracing(List spanHandlers, List tracingCustomizers, brave.propagation.CurrentTraceContext currentTraceContext, brave.propagation.Propagation.Factory propagationFactory, brave.sampler.Sampler sampler) { - String applicationName = moduleModel.getApplicationModel().getApplicationConfigManager().getApplication() - .map(ApplicationConfig::getName) - .orElse(DEFAULT_APPLICATION_NAME); + String applicationName = dubboConfigProperties.getApplication().getName(); + if (StringUtils.isEmpty(applicationName)) { + applicationName = DEFAULT_APPLICATION_NAME; + } brave.Tracing.Builder builder = brave.Tracing.newBuilder().currentTraceContext(currentTraceContext).traceId128Bit(true) .supportsJoin(false).propagationFactory(propagationFactory).sampler(sampler) .localServiceName(applicationName); diff --git a/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/otel/OpenTelemetryAutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/otel/OpenTelemetryAutoConfiguration.java index 85babb77f86a..6b4e38f7c9bd 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/otel/OpenTelemetryAutoConfiguration.java +++ b/dubbo-spring-boot/dubbo-spring-boot-starters/observability/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/otel/OpenTelemetryAutoConfiguration.java @@ -18,8 +18,7 @@ import org.apache.dubbo.common.Version; -import org.apache.dubbo.config.ApplicationConfig; -import org.apache.dubbo.rpc.model.ModuleModel; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.spring.boot.autoconfigure.DubboConfigurationProperties; import org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration; import org.apache.dubbo.spring.boot.observability.autoconfigure.ObservabilityUtils; @@ -52,15 +51,12 @@ public class OpenTelemetryAutoConfiguration { /** * Default value for application name if {@code spring.application.name} is not set. */ - private static final String DEFAULT_APPLICATION_NAME = "application"; + private static final String DEFAULT_APPLICATION_NAME = "dubbo-application"; private final DubboConfigurationProperties dubboConfigProperties; - private final ModuleModel moduleModel; - - OpenTelemetryAutoConfiguration(DubboConfigurationProperties dubboConfigProperties, ModuleModel moduleModel) { + OpenTelemetryAutoConfiguration(DubboConfigurationProperties dubboConfigProperties) { this.dubboConfigProperties = dubboConfigProperties; - this.moduleModel = moduleModel; } @Bean @@ -74,9 +70,10 @@ io.opentelemetry.api.OpenTelemetry openTelemetry(io.opentelemetry.sdk.trace.SdkT @ConditionalOnMissingBean io.opentelemetry.sdk.trace.SdkTracerProvider otelSdkTracerProvider(ObjectProvider spanProcessors, io.opentelemetry.sdk.trace.samplers.Sampler sampler) { - String applicationName = moduleModel.getApplicationModel().getApplicationConfigManager().getApplication() - .map(ApplicationConfig::getName) - .orElse(DEFAULT_APPLICATION_NAME); + String applicationName = dubboConfigProperties.getApplication().getName(); + if (StringUtils.isEmpty(applicationName)) { + applicationName = DEFAULT_APPLICATION_NAME; + } io.opentelemetry.sdk.trace.SdkTracerProviderBuilder builder = io.opentelemetry.sdk.trace.SdkTracerProvider.builder().setSampler(sampler) .setResource(io.opentelemetry.sdk.resources.Resource.create(io.opentelemetry.api.common.Attributes.of(io.opentelemetry.semconv.resource.attributes.ResourceAttributes.SERVICE_NAME, applicationName))); spanProcessors.orderedStream().forEach(builder::addSpanProcessor); diff --git a/dubbo-test/dubbo-dependencies-all/pom.xml b/dubbo-test/dubbo-dependencies-all/pom.xml index 526743f36095..991154acbb98 100644 --- a/dubbo-test/dubbo-dependencies-all/pom.xml +++ b/dubbo-test/dubbo-dependencies-all/pom.xml @@ -193,6 +193,11 @@ dubbo-metrics-prometheus ${project.version} + + org.apache.dubbo + dubbo-tracing + ${project.version} + @@ -205,7 +210,6 @@ dubbo-monitor-default ${project.version} - org.apache.dubbo