Revert "refactor: migrate tracing core from boot-start to dubbo deployer (#12453)"

This reverts commit a613cae2
This commit is contained in:
Albumen Kevin 2023-06-20 10:02:30 +08:00
parent 8ad792c287
commit ea35f7ed5c
67 changed files with 250 additions and 1452 deletions

View File

@ -114,5 +114,4 @@ dubbo-nacos-spring-boot-starter
dubbo-zookeeper-spring-boot-starter
dubbo-zookeeper-curator5-spring-boot-starter
dubbo-spring-security
dubbo-tracing
dubbo-xds

View File

@ -86,5 +86,10 @@
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-integration-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -14,9 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.filter;
package org.apache.dubbo.rpc.cluster.filter.support;
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;
@ -26,10 +30,6 @@ import org.apache.dubbo.rpc.RpcException;
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 @@ import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
/**
* A {@link Filter} that creates an {@link Observation} around the outgoing message.
*/
@Activate(group = CONSUMER, order = Integer.MIN_VALUE + 50, onClass = "io.micrometer.observation.NoopObservationRegistry")
@Activate(group = CONSUMER, order = -1, onClass = "io.micrometer.observation.NoopObservationRegistry")
public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listener, ScopeModelAware {
private ObservationRegistry observationRegistry;
@ -47,8 +47,12 @@ public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listen
private DubboClientObservationConvention clientObservationConvention;
public ObservationSenderFilter(ApplicationModel applicationModel) {
observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class);
clientObservationConvention = applicationModel.getBeanFactory().getBean(DubboClientObservationConvention.class);
applicationModel.getApplicationConfigManager().getTracing().ifPresent(cfg -> {
if (Boolean.TRUE.equals(cfg.getEnabled())) {
observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class);
clientObservationConvention = applicationModel.getBeanFactory().getBean(DubboClientObservationConvention.class);
}
});
}
@Override
@ -71,9 +75,6 @@ public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listen
if (observation == null) {
return;
}
if (appResponse != null && appResponse.hasException()) {
observation.error(appResponse.getException());
}
observation.stop();
}

View File

@ -1,4 +1,5 @@
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

View File

@ -0,0 +1,84 @@
/*
* 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 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 io.micrometer.tracing.test.SampleTestRunner;
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});
}
}

View File

@ -15,22 +15,23 @@
* limitations under the License.
*/
package org.apache.dubbo.tracing.filter;
package org.apache.dubbo.rpc.cluster.filter;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
import org.apache.dubbo.rpc.cluster.filter.support.ObservationSenderFilter;
import org.apache.dubbo.rpc.model.ApplicationModel;
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.assertj.core.api.BDDAssertions;
class ObservationSenderFilterTest extends AbstractObservationFilterTest {
@Override
public SampleTestRunnerConsumer yourCode() {
public SampleTestRunner.SampleTestRunnerConsumer yourCode() {
return (buildingBlocks, meterRegistry) -> {
setupConfig();
setupAttachments();

View File

@ -92,8 +92,6 @@ public interface LoggerCodeConstants {
String VULNERABILITY_WARNING = "0-28";
String COMMON_NOT_FOUND_TRACER_DEPENDENCY = "0-29";
// Registry module

View File

@ -39,19 +39,6 @@ public class BaggageConfig implements Serializable {
*/
private List<String> remoteFields = new ArrayList<>();
public BaggageConfig() {
}
public BaggageConfig(Boolean enabled) {
this.enabled = enabled;
}
public BaggageConfig(Boolean enabled, Correlation correlation, List<String> remoteFields) {
this.enabled = enabled;
this.correlation = correlation;
this.remoteFields = remoteFields;
}
public Boolean getEnabled() {
return enabled;
}
@ -89,18 +76,6 @@ public class BaggageConfig implements Serializable {
*/
private List<String> fields = new ArrayList<>();
public Correlation() {
}
public Correlation(boolean enabled) {
this.enabled = enabled;
}
public Correlation(boolean enabled, List<String> fields) {
this.enabled = enabled;
this.fields = fields;
}
public boolean isEnabled() {
return this.enabled;
}

View File

@ -56,28 +56,15 @@ public class ExporterConfig implements Serializable {
private String endpoint;
/**
* Connection timeout for requests to Zipkin. (seconds)
* Connection timeout for requests to Zipkin.
*/
private Duration connectTimeout = Duration.ofSeconds(1);
/**
* Read timeout for requests to Zipkin. (seconds)
* Read timeout for requests to Zipkin.
*/
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;
}
@ -111,7 +98,7 @@ public class ExporterConfig implements Serializable {
private String endpoint;
/**
* The maximum time to wait for the collector to process an exported batch of spans. (seconds)
* The maximum time to wait for the collector to process an exported batch of spans.
*/
private Duration timeout = Duration.ofSeconds(10);
@ -123,24 +110,6 @@ public class ExporterConfig implements Serializable {
private Map<String, String> 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;
}

View File

@ -29,13 +29,6 @@ public class PropagationConfig implements Serializable {
*/
private String type = W3C;
public PropagationConfig() {
}
public PropagationConfig(String type) {
this.type = type;
}
public String getType() {
return type;
}

View File

@ -25,13 +25,6 @@ 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;
}

View File

@ -72,12 +72,6 @@
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-tracing</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-monitor-api</artifactId>

View File

@ -38,6 +38,7 @@ import org.apache.dubbo.common.logger.LoggerFactory;
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;
@ -46,7 +47,6 @@ import org.apache.dubbo.config.DubboShutdownHook;
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,7 +60,6 @@ import org.apache.dubbo.metrics.report.DefaultMetricsReporterFactory;
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;
@ -71,8 +70,6 @@ import org.apache.dubbo.rpc.model.ModuleServiceRepository;
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;
@ -155,7 +152,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
// load spi listener
Set<ApplicationDeployListener> deployListeners = applicationModel.getExtensionLoader(ApplicationDeployListener.class)
.getSupportedExtensionInstances();
.getSupportedExtensionInstances();
for (ApplicationDeployListener listener : deployListeners) {
this.addDeployListener(listener);
}
@ -229,9 +226,6 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
initMetricsService();
// @since 3.2.3
initObservationRegistry();
// @since 2.7.8
startMetadataCenter();
@ -358,17 +352,17 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
List<RegistryConfig> 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);
});
});
}
}
@ -378,16 +372,16 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
}
private void initMetricsReporter() {
if (!MetricsSupportUtil.isSupportMetrics()) {
if (!isSupportMetrics()) {
return;
}
DefaultMetricsCollector collector =
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class);
applicationModel.getBeanFactory().getBean(DefaultMetricsCollector.class);
Optional<MetricsConfig> 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(MetricsSupportUtil.isSupportPrometheus() ? PROTOCOL_PROMETHEUS : PROTOCOL_DEFAULT);
metricsConfig.setProtocol(isSupportPrometheus() ? PROTOCOL_PROMETHEUS : PROTOCOL_DEFAULT);
}
collector.setCollectEnabled(true);
collector.collectApplication();
@ -415,35 +409,26 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
}
}
/**
* 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<TracingConfig> configOptional = configManager.getTracing();
if (!configOptional.isPresent() || !configOptional.get().getEnabled()) {
return;
}
public boolean isSupportMetrics() {
return isClassPresent("io.micrometer.core.instrument.MeterRegistry");
}
DubboObservationRegistry dubboObservationRegistry = new DubboObservationRegistry(applicationModel, configOptional.get());
dubboObservationRegistry.initObservationRegistry();
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, DefaultApplicationDeployer.class.getClassLoader());
}
private boolean isUsedRegistryAsConfigCenter(RegistryConfig registryConfig) {
return isUsedRegistryAsCenter(registryConfig, registryConfig::getUseAsConfigCenter, "config",
DynamicConfigurationFactory.class);
DynamicConfigurationFactory.class);
}
private ConfigCenterConfig registryAsConfigCenter(RegistryConfig registryConfig) {
@ -485,9 +470,9 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
}
Collection<MetadataReportConfig> 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;
@ -498,12 +483,12 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
List<RegistryConfig> 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);
});
}
}
@ -532,7 +517,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
private boolean isUsedRegistryAsMetadataCenter(RegistryConfig registryConfig) {
return isUsedRegistryAsCenter(registryConfig, registryConfig::getUseAsMetadataCenter, "metadata",
MetadataReportFactory.class);
MetadataReportFactory.class);
}
/**
@ -558,13 +543,13 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
supported = supportsExtension(extensionClass, protocol);
if (logger.isInfoEnabled()) {
logger.info(format("No value is configured in the registry, the %s extension[name : %s] %s as the %s center"
, extensionClass.getSimpleName(), protocol, supported ? "supports" : "does not support", centerType));
, extensionClass.getSimpleName(), protocol, supported ? "supports" : "does not support", centerType));
}
}
if (logger.isInfoEnabled()) {
logger.info(format("The registry[%s] will be %s as the %s center", registryConfig,
supported ? "used" : "not used", centerType));
supported ? "used" : "not used", centerType));
}
return supported;
}
@ -587,7 +572,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
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());
}
@ -790,13 +775,13 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
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);
}
}
}
@ -874,10 +859,10 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
// 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);
@ -915,10 +900,10 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
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);
@ -1032,7 +1017,7 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
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);

View File

@ -18,7 +18,7 @@
package org.apache.dubbo.config.deploy;
import org.apache.dubbo.common.utils.Assert;
import org.apache.dubbo.metrics.utils.MetricsSupportUtil;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.Test;
@ -26,7 +26,7 @@ class DefaultApplicationDeployerTest {
@Test
void isSupportPrometheus() {
boolean supportPrometheus = MetricsSupportUtil.isSupportPrometheus();
Assert.assertTrue(supportPrometheus, "MetricsSupportUtil.isSupportPrometheus() should return true");
boolean supportPrometheus = new DefaultApplicationDeployer(ApplicationModel.defaultModel()).isSupportPrometheus();
Assert.assertTrue(supportPrometheus,"DefaultApplicationDeployer.isSupportPrometheus() should return true");
}
}

View File

@ -134,8 +134,7 @@
<protostuff_version>1.8.0</protostuff_version>
<envoy_api_version>0.1.35</envoy_api_version>
<micrometer.version>1.11.1</micrometer.version>
<opentelemetry.version>1.26.0</opentelemetry.version>
<zipkin-reporter.version>2.16.4</zipkin-reporter.version>
<micrometer-tracing.version>1.1.2</micrometer-tracing.version>
<t_digest.version>3.3</t_digest.version>
<prometheus_client.version>0.16.0</prometheus_client.version>
@ -232,20 +231,6 @@
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>${opentelemetry.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-bom</artifactId>
<version>${zipkin-reporter.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>

View File

@ -219,15 +219,6 @@
<optional>true</optional>
</dependency>
<!-- tracing -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-tracing</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<!-- monitor -->
<dependency>
<groupId>org.apache.dubbo</groupId>
@ -539,7 +530,6 @@
<include>org.apache.dubbo:dubbo-metrics-metadata</include>
<include>org.apache.dubbo:dubbo-metrics-config-center</include>
<include>org.apache.dubbo:dubbo-metrics-prometheus</include>
<include>org.apache.dubbo:dubbo-tracing</include>
<include>org.apache.dubbo:dubbo-monitor-api</include>
<include>org.apache.dubbo:dubbo-monitor-default</include>
<include>org.apache.dubbo:dubbo-qos</include>

View File

@ -256,13 +256,6 @@
<version>${project.version}</version>
</dependency>
<!-- tracing -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-tracing</artifactId>
<version>${project.version}</version>
</dependency>
<!-- monitor -->
<dependency>
<groupId>org.apache.dubbo</groupId>

View File

@ -134,7 +134,6 @@
<include>org.apache.dubbo:dubbo-metadata-api</include>
<include>org.apache.dubbo:dubbo-metrics-api</include>
<include>org.apache.dubbo:dubbo-metrics-default</include>
<include>org.apache.dubbo:dubbo-tracing</include>
<include>org.apache.dubbo:dubbo-monitor-api</include>
<include>org.apache.dubbo:dubbo-registry-api</include>
<include>org.apache.dubbo:dubbo-remoting-api</include>

View File

@ -49,5 +49,10 @@
<groupId>com.tdunning</groupId>
<artifactId>t-digest</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-integration-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -14,20 +14,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
import io.micrometer.common.KeyValues;
import io.micrometer.common.docs.KeyName;
import io.micrometer.common.lang.Nullable;
package org.apache.dubbo.metrics.observation;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.support.RpcUtils;
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;
import io.micrometer.common.KeyValues;
import io.micrometer.common.docs.KeyName;
import io.micrometer.common.lang.Nullable;
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;
class AbstractDefaultDubboObservationConvention {
KeyValues getLowCardinalityKeyValues(Invocation invocation) {

View File

@ -14,20 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
package org.apache.dubbo.metrics.observation;
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.tracing.DubboObservationDocumentation.LowCardinalityKeyNames.NET_PEER_NAME;
import static org.apache.dubbo.tracing.DubboObservationDocumentation.LowCardinalityKeyNames.NET_PEER_PORT;
import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.NET_PEER_NAME;
import static org.apache.dubbo.metrics.observation.DubboObservationDocumentation.LowCardinalityKeyNames.NET_PEER_PORT;
/**
* Default implementation of the {@link DubboClientObservationConvention}.

View File

@ -14,9 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
import org.apache.dubbo.tracing.context.DubboServerContext;
package org.apache.dubbo.metrics.observation;
import io.micrometer.common.KeyValues;

View File

@ -14,14 +14,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.context;
package org.apache.dubbo.metrics.observation;
import java.util.Objects;
import io.micrometer.observation.transport.SenderContext;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import io.micrometer.observation.transport.SenderContext;
import java.util.Objects;
/**
* Provider context for RPC.
*/

View File

@ -14,9 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
import org.apache.dubbo.tracing.context.DubboClientContext;
package org.apache.dubbo.metrics.observation;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationConvention;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
package org.apache.dubbo.metrics.observation;
import io.micrometer.common.docs.KeyName;
import io.micrometer.common.lang.NonNullApi;

View File

@ -14,12 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.context;
package org.apache.dubbo.metrics.observation;
import io.micrometer.observation.transport.ReceiverContext;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import io.micrometer.observation.transport.ReceiverContext;
/**
* Consumer context for RPC.
*/

View File

@ -14,9 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
import org.apache.dubbo.tracing.context.DubboServerContext;
package org.apache.dubbo.metrics.observation;
import io.micrometer.observation.Observation;
import io.micrometer.observation.ObservationConvention;

View File

@ -1,38 +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.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());
}
}

View File

@ -17,9 +17,8 @@
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;

View File

@ -14,12 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
package org.apache.dubbo.metrics.observation;
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;

View File

@ -14,13 +14,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
package org.apache.dubbo.metrics.observation;
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;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.utils;
package org.apache.dubbo.metrics.observation.utils;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.Invoker;

View File

@ -41,5 +41,10 @@
<artifactId>micrometer-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-integration-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.filter;
package org.apache.dubbo.metrics.observation;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.BaseFilter;
@ -25,10 +25,6 @@ import org.apache.dubbo.rpc.Result;
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;
@ -38,7 +34,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
/**
* A {@link Filter} that creates an {@link Observation} around the incoming message.
*/
@Activate(group = PROVIDER, order = Integer.MIN_VALUE + 50, onClass = "io.micrometer.observation.NoopObservationRegistry")
@Activate(group = PROVIDER, order = -1, onClass = "io.micrometer.observation.NoopObservationRegistry")
public class ObservationReceiverFilter implements Filter, BaseFilter.Listener, ScopeModelAware {
private ObservationRegistry observationRegistry;
@ -46,8 +42,12 @@ public class ObservationReceiverFilter implements Filter, BaseFilter.Listener, S
private DubboServerObservationConvention serverObservationConvention;
public ObservationReceiverFilter(ApplicationModel applicationModel) {
observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class);
serverObservationConvention = applicationModel.getBeanFactory().getBean(DubboServerObservationConvention.class);
applicationModel.getApplicationConfigManager().getTracing().ifPresent(cfg -> {
if (Boolean.TRUE.equals(cfg.getEnabled())) {
observationRegistry = applicationModel.getBeanFactory().getBean(ObservationRegistry.class);
serverObservationConvention = applicationModel.getBeanFactory().getBean(DubboServerObservationConvention.class);
}
});
}
@Override
@ -70,9 +70,6 @@ public class ObservationReceiverFilter implements Filter, BaseFilter.Listener, S
if (observation == null) {
return;
}
if (appResponse != null && appResponse.hasException()) {
observation.error(appResponse.getException());
}
observation.stop();
}

View File

@ -0,0 +1,2 @@
metrics-beta=org.apache.dubbo.metrics.filter.MetricsFilter
observationreceiver=org.apache.dubbo.metrics.observation.ObservationReceiverFilter

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
package org.apache.dubbo.tracing.filter;
package org.apache.dubbo.metrics.observation;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.TracingConfig;
@ -24,7 +24,6 @@ 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.apache.dubbo.tracing.MockInvocation;
import io.micrometer.tracing.test.SampleTestRunner;
import org.junit.jupiter.api.AfterEach;
@ -80,7 +79,7 @@ abstract class AbstractObservationFilterTest extends SampleTestRunner {
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});
}
}

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
package org.apache.dubbo.metrics.observation;
import org.apache.dubbo.rpc.AttachmentsAdapter;
import org.apache.dubbo.rpc.Invoker;
@ -68,11 +68,11 @@ public class MockInvocation extends RpcInvocation {
}
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<String, String> getAttachments() {

View File

@ -15,13 +15,8 @@
* limitations under the License.
*/
package org.apache.dubbo.tracing.filter;
package org.apache.dubbo.metrics.observation;
import io.micrometer.common.KeyValues;
import io.micrometer.core.tck.MeterRegistryAssert;
import io.micrometer.tracing.Span;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.test.simple.SpansAssert;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.rpc.AppResponse;
import org.apache.dubbo.rpc.Filter;
@ -32,6 +27,11 @@ import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.model.ApplicationModel;
import io.micrometer.common.KeyValues;
import io.micrometer.core.tck.MeterRegistryAssert;
import io.micrometer.tracing.Span;
import io.micrometer.tracing.Tracer;
import io.micrometer.tracing.test.simple.SpansAssert;
import org.assertj.core.api.BDDAssertions;
class ObservationReceiverFilterTest extends AbstractObservationFilterTest {

View File

@ -1,111 +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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>dubbo-tracing</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>The tracing module of dubbo project</description>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<skip_maven_deploy>false</skip_maven_deploy>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-common</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-cluster</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metrics-default</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- micrometer -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-core</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-integration-test</artifactId>
<scope>test</scope>
</dependency>
<!-- bridge -->
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
<optional>true</optional>
</dependency>
<!-- exporter -->
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-zipkin</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@ -1,90 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing;
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);
}
}

View File

@ -1,37 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.exporter;
import brave.handler.SpanHandler;
import io.opentelemetry.sdk.trace.export.SpanExporter;
public interface TraceExporter {
/**
* for otel
*
* @return
*/
SpanExporter getSpanExporter();
/**
* for brave
*
* @return
*/
SpanHandler getSpanHandler();
}

View File

@ -1,66 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.exporter;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.nested.ExporterConfig;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.tracing.exporter.otlp.OTlpExporter;
import org.apache.dubbo.tracing.exporter.zipkin.ZipkinExporter;
import brave.handler.SpanHandler;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.util.ArrayList;
import java.util.List;
public class TraceExporterFactory {
private final static ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(TraceExporterFactory.class);
/**
* for OTel
*/
public static List<SpanExporter> getSpanExporters(ApplicationModel applicationModel, ExporterConfig exporterConfig) {
ExporterConfig.ZipkinConfig zipkinConfig = exporterConfig.getZipkinConfig();
ExporterConfig.OtlpConfig otlpConfig = exporterConfig.getOtlpConfig();
List<SpanExporter> 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<SpanHandler> getSpanHandlers(ApplicationModel applicationModel, ExporterConfig exporterConfig) {
List<SpanHandler> res = new ArrayList<>();
// TODO brave SpanHandler impl
return res;
}
}

View File

@ -1,66 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.exporter.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<String, String> 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;
}
}

View File

@ -1,60 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.exporter.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<Span> 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<Span> getSpanBytesEncoder() {
BytesEncoder<Span> encoder = applicationModel.getBeanFactory().getBean(BytesEncoder.class);
return encoder == null ? SpanBytesEncoder.JSON_V2 : encoder;
}
}

View File

@ -1,29 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.tracer;
import io.micrometer.tracing.propagation.Propagator;
public interface PropagatorProvider {
/**
* The real propagator will come from tracer implementation (OTel / Brave)
*
* @return Propagator
*/
Propagator getPropagator();
}

View File

@ -1,37 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.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;
}
}

View File

@ -1,30 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.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();
}

View File

@ -1,39 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.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;
}
}

View File

@ -1,31 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.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;
}
}

View File

@ -1,41 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.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;
}
}

View File

@ -1,38 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.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);
}
}

View File

@ -1,212 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.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<SpanExporter> 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<EventListener> getEventListeners() {
List<EventListener> 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<EventListener> listeners;
OTelEventPublisher(List<EventListener> 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<String> remoteFields = baggageConfig.getRemoteFields();
return TextMapPropagator.composite(B3Propagator.injectingSingleHeader(),
new BaggageTextMapPropagator(remoteFields,
new OtelBaggageManager(currentTraceContext, remoteFields, Collections.emptyList())));
} else if ("W3C".equals(type)) {
List<String> remoteFields = baggageConfig.getRemoteFields();
return TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(),
W3CBaggagePropagator.getInstance(), new BaggageTextMapPropagator(remoteFields,
new OtelBaggageManager(currentTraceContext, remoteFields, Collections.emptyList())));
}
return TextMapPropagator.noop();
}
}
}

View File

@ -1,49 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.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());
}
}

View File

@ -1 +0,0 @@
observationreceiver=org.apache.dubbo.tracing.filter.ObservationReceiverFilter

View File

@ -1 +0,0 @@
observationsender=org.apache.dubbo.tracing.filter.ObservationSenderFilter

View File

@ -1,34 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.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());
}
}

View File

@ -1,39 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.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.");
}
}

View File

@ -1,53 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.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());
}
}

View File

@ -1,49 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.tracing.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");
}
}

View File

@ -24,7 +24,6 @@
<module>dubbo-metrics-metadata</module>
<module>dubbo-metrics-prometheus</module>
<module>dubbo-metrics-config-center</module>
<module>dubbo-tracing</module>
</modules>
<parent>
<groupId>org.apache.dubbo</groupId>

View File

@ -137,12 +137,6 @@
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-spring</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<!-- prometheus client -->
<dependency>

View File

@ -18,7 +18,6 @@ package org.apache.dubbo.spring.boot.observability.autoconfigure;
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;
@ -29,15 +28,14 @@ import org.springframework.beans.factory.BeanFactory;
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;
@ -48,7 +46,7 @@ import java.util.Arrays;
@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, ApplicationListener<DubboConfigInitEvent>, Ordered {
public class DubboObservationAutoConfiguration implements BeanFactoryAware, SmartInitializingSingleton {
private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(QosProtocolWrapper.class);
@ -81,21 +79,16 @@ public class DubboObservationAutoConfiguration implements BeanFactoryAware, Appl
}
@Override
public void onApplicationEvent(DubboConfigInitEvent event) {
public void afterSingletonsInstantiated() {
try {
applicationModel.getBeanFactory().registerBean(beanFactory.getBean(io.micrometer.observation.ObservationRegistry.class));
applicationModel.getBeanFactory().registerBean(beanFactory.getBean(io.micrometer.tracing.Tracer.class));
applicationModel.getBeanFactory().registerBean(beanFactory.getBean(io.micrometer.tracing.propagation.Propagator.class));
io.micrometer.tracing.Tracer bean = beanFactory.getBean(io.micrometer.tracing.Tracer.class);
applicationModel.getBeanFactory().registerBean(bean);
} 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")

View File

@ -16,7 +16,8 @@
*/
package org.apache.dubbo.spring.boot.observability.autoconfigure.brave;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.rpc.model.ModuleModel;
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,12 +53,12 @@ public class BraveAutoConfiguration {
/**
* Default value for application name if {@code spring.application.name} is not set.
*/
private static final String DEFAULT_APPLICATION_NAME = "dubbo-application";
private static final String DEFAULT_APPLICATION_NAME = "application";
private final DubboConfigurationProperties dubboConfigProperties;
private final ModuleModel moduleModel;
public BraveAutoConfiguration(DubboConfigurationProperties dubboConfigProperties) {
this.dubboConfigProperties = dubboConfigProperties;
public BraveAutoConfiguration(ModuleModel moduleModel) {
this.moduleModel = moduleModel;
}
@Bean
@ -75,10 +76,9 @@ public class BraveAutoConfiguration {
public brave.Tracing braveTracing(List<brave.handler.SpanHandler> spanHandlers,
List<brave.TracingCustomizer> tracingCustomizers, brave.propagation.CurrentTraceContext currentTraceContext,
brave.propagation.Propagation.Factory propagationFactory, brave.sampler.Sampler sampler) {
String applicationName = dubboConfigProperties.getApplication().getName();
if (StringUtils.isEmpty(applicationName)) {
applicationName = DEFAULT_APPLICATION_NAME;
}
String applicationName = moduleModel.getApplicationModel().getApplicationConfigManager().getApplication()
.map(ApplicationConfig::getName)
.orElse(DEFAULT_APPLICATION_NAME);
brave.Tracing.Builder builder = brave.Tracing.newBuilder().currentTraceContext(currentTraceContext).traceId128Bit(true)
.supportsJoin(false).propagationFactory(propagationFactory).sampler(sampler)
.localServiceName(applicationName);

View File

@ -18,7 +18,8 @@ package org.apache.dubbo.spring.boot.observability.autoconfigure.otel;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.rpc.model.ModuleModel;
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;
@ -51,12 +52,15 @@ public class OpenTelemetryAutoConfiguration {
/**
* Default value for application name if {@code spring.application.name} is not set.
*/
private static final String DEFAULT_APPLICATION_NAME = "dubbo-application";
private static final String DEFAULT_APPLICATION_NAME = "application";
private final DubboConfigurationProperties dubboConfigProperties;
OpenTelemetryAutoConfiguration(DubboConfigurationProperties dubboConfigProperties) {
private final ModuleModel moduleModel;
OpenTelemetryAutoConfiguration(DubboConfigurationProperties dubboConfigProperties, ModuleModel moduleModel) {
this.dubboConfigProperties = dubboConfigProperties;
this.moduleModel = moduleModel;
}
@Bean
@ -70,10 +74,9 @@ public class OpenTelemetryAutoConfiguration {
@ConditionalOnMissingBean
io.opentelemetry.sdk.trace.SdkTracerProvider otelSdkTracerProvider(ObjectProvider<io.opentelemetry.sdk.trace.SpanProcessor> spanProcessors,
io.opentelemetry.sdk.trace.samplers.Sampler sampler) {
String applicationName = dubboConfigProperties.getApplication().getName();
if (StringUtils.isEmpty(applicationName)) {
applicationName = DEFAULT_APPLICATION_NAME;
}
String applicationName = moduleModel.getApplicationModel().getApplicationConfigManager().getApplication()
.map(ApplicationConfig::getName)
.orElse(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);

View File

@ -193,11 +193,6 @@
<artifactId>dubbo-metrics-prometheus</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-tracing</artifactId>
<version>${project.version}</version>
</dependency>
<!-- monitor -->
<dependency>
@ -210,6 +205,7 @@
<artifactId>dubbo-monitor-default</artifactId>
<version>${project.version}</version>
</dependency>
<!-- native -->
<dependency>
<groupId>org.apache.dubbo</groupId>