feat: add tracing config (#11959)

* feat: add TracingConfig

* fix: fix conflict

* fix: fix enum nested error

* fix: fix unit test
This commit is contained in:
conghuhu 2023-03-30 10:23:23 +08:00 committed by GitHub
parent 547678e684
commit 8fc267ba9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 607 additions and 365 deletions

View File

@ -42,13 +42,17 @@ import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
@Activate(group = CONSUMER, order = -1, onClass = "io.micrometer.observation.NoopObservationRegistry")
public class ObservationSenderFilter implements ClusterFilter, BaseFilter.Listener, ScopeModelAware {
private final ObservationRegistry observationRegistry;
private ObservationRegistry observationRegistry;
private final DubboClientObservationConvention clientObservationConvention;
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

View File

@ -18,6 +18,7 @@ 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;
@ -62,6 +63,9 @@ abstract class AbstractObservationFilterTest extends SampleTestRunner {
invocation.addInvokedInvoker(invoker);
applicationModel.getBeanFactory().registerBean(getObservationRegistry());
TracingConfig tracingConfig = new TracingConfig();
tracingConfig.setEnabled(true);
applicationModel.getApplicationConfigManager().setTracing(tracingConfig);
filter = createFilter(applicationModel);

View File

@ -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.config;
import org.apache.dubbo.config.nested.BaggageConfig;
import org.apache.dubbo.config.nested.PropagationConfig;
import org.apache.dubbo.config.nested.SamplingConfig;
import org.apache.dubbo.config.support.Nested;
import org.apache.dubbo.rpc.model.ApplicationModel;
/**
* TracingConfig
*/
public class TracingConfig extends AbstractConfig {
private static final long serialVersionUID = -9089919311611546383L;
private Boolean enabled = false;
/**
* Sampling configuration.
*/
@Nested
private SamplingConfig sampling = new SamplingConfig();
/**
* Baggage configuration.
*/
@Nested
private BaggageConfig baggage = new BaggageConfig();
/**
* Propagation configuration.
*/
@Nested
private PropagationConfig propagation = new PropagationConfig();
public TracingConfig() {
}
public TracingConfig(ApplicationModel applicationModel) {
super(applicationModel);
}
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public SamplingConfig getSampling() {
return sampling;
}
public void setSampling(SamplingConfig sampling) {
this.sampling = sampling;
}
public BaggageConfig getBaggage() {
return baggage;
}
public void setBaggage(BaggageConfig baggage) {
this.baggage = baggage;
}
public PropagationConfig getPropagation() {
return propagation;
}
public void setPropagation(PropagationConfig propagation) {
this.propagation = propagation;
}
}

View File

@ -39,6 +39,7 @@ import org.apache.dubbo.config.ReferenceConfigBase;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfigBase;
import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
@ -92,6 +93,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
uniqueConfigTypes.add(ApplicationConfig.class);
uniqueConfigTypes.add(MonitorConfig.class);
uniqueConfigTypes.add(MetricsConfig.class);
uniqueConfigTypes.add(TracingConfig.class);
uniqueConfigTypes.add(SslConfig.class);
// unique config in each module
@ -127,7 +129,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
// dubbo.config.ignore-duplicated-interface
String ignoreDuplicatedInterfaceStr = (String) configuration
.getProperty(ConfigKeys.DUBBO_CONFIG_IGNORE_DUPLICATED_INTERFACE);
.getProperty(ConfigKeys.DUBBO_CONFIG_IGNORE_DUPLICATED_INTERFACE);
if (ignoreDuplicatedInterfaceStr != null) {
this.ignoreDuplicatedInterface = Boolean.parseBoolean(ignoreDuplicatedInterfaceStr);
}
@ -192,7 +194,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
* @throws IllegalStateException
*/
private <C extends AbstractConfig> C addIfAbsent(C config, Map<String, C> configsMap)
throws IllegalStateException {
throws IllegalStateException {
if (config == null || configsMap == null) {
return config;
@ -216,8 +218,8 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
if (existedConfig != null && !isEquals(existedConfig, config)) {
String type = config.getClass().getSimpleName();
logger.warn(COMMON_UNEXPECTED_EXCEPTION, "", "", String.format("Duplicate %s found, there already has one default %s or more than two %ss have the same id, " +
"you can try to give each %s a different id, override previous config with later config. id: %s, prev: %s, later: %s",
type, type, type, type, key, existedConfig, config));
"you can try to give each %s a different id, override previous config with later config. id: %s, prev: %s, later: %s",
type, type, type, type, key, existedConfig, config));
}
// override existed config if any
@ -252,7 +254,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
return null;
} else if (size > 1) {
throw new IllegalStateException("Expected single instance of " + configType + ", but found " + size +
" instances, please remove redundant configs. instances: " + configsMap.values());
" instances, please remove redundant configs. instances: " + configsMap.values());
}
return (C) configsMap.values().iterator().next();
}
@ -335,11 +337,11 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
// try to find config by name
if (ReflectUtils.hasMethod(cls, CONFIG_NAME_READ_METHOD)) {
List<C> list = configsMap.values().stream()
.filter(cfg -> name.equals(getConfigName(cfg)))
.collect(Collectors.toList());
.filter(cfg -> name.equals(getConfigName(cfg)))
.collect(Collectors.toList());
if (list.size() > 1) {
throw new IllegalStateException("Found more than one config by name: " + name +
", instances: " + list + ". Please remove redundant configs or get config by id.");
", instances: " + list + ". Please remove redundant configs or get config by id.");
} else if (list.size() == 1) {
return list.get(0);
}
@ -364,8 +366,8 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
// 2. find equal config
prevConfig = values.stream()
.filter(val -> isEquals(val, config))
.findFirst();
.filter(val -> isEquals(val, config))
.findFirst();
return prevConfig;
}
@ -408,18 +410,18 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
static <C extends AbstractConfig> List<C> getDefaultConfigs(Map<String, C> configsMap) {
// find isDefault() == true
List<C> list = configsMap.values()
.stream()
.filter(c -> TRUE.equals(AbstractConfigManager.isDefaultConfig(c)))
.collect(Collectors.toList());
.stream()
.filter(c -> TRUE.equals(AbstractConfigManager.isDefaultConfig(c)))
.collect(Collectors.toList());
if (list.size() > 0) {
return list;
}
// find isDefault() == null
list = configsMap.values()
.stream()
.filter(c -> AbstractConfigManager.isDefaultConfig(c) == null)
.collect(Collectors.toList());
.stream()
.filter(c -> AbstractConfigManager.isDefaultConfig(c) == null)
.collect(Collectors.toList());
return list;
// exclude isDefault() == false
@ -430,7 +432,7 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
C oldOne = configsMap.values().iterator().next();
String configName = oldOne.getClass().getSimpleName();
String msgPrefix = "Duplicate Configs found for " + configName + ", only one unique " + configName +
" is allowed for one application. previous: " + oldOne + ", later: " + config + ". According to config mode [" + configMode + "], ";
" is allowed for one application. previous: " + oldOne + ", later: " + config + ". According to config mode [" + configMode + "], ";
switch (configMode) {
case STRICT: {
if (!isEquals(oldOne, config)) {
@ -625,9 +627,10 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
*/
protected <T extends AbstractConfig> boolean isRequired(Class<T> clazz) {
if (clazz == RegistryConfig.class ||
clazz == MetadataReportConfig.class ||
clazz == MonitorConfig.class ||
clazz == MetricsConfig.class) {
clazz == MetadataReportConfig.class ||
clazz == MonitorConfig.class ||
clazz == MetricsConfig.class ||
clazz == TracingConfig.class) {
return false;
}
return true;

View File

@ -32,6 +32,7 @@ import org.apache.dubbo.config.MonitorConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.Arrays;
@ -59,8 +60,8 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
public ConfigManager(ApplicationModel applicationModel) {
super(applicationModel, Arrays.asList(ApplicationConfig.class, MonitorConfig.class,
MetricsConfig.class, SslConfig.class, ProtocolConfig.class, RegistryConfig.class, ConfigCenterConfig.class,
MetadataReportConfig.class));
MetricsConfig.class, SslConfig.class, ProtocolConfig.class, RegistryConfig.class, ConfigCenterConfig.class,
MetadataReportConfig.class, TracingConfig.class));
}
@ -105,6 +106,15 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
return ofNullable(getSingleConfig(getTagName(MetricsConfig.class)));
}
@DisableInject
public void setTracing(TracingConfig tracing) {
addConfig(tracing);
}
public Optional<TracingConfig> getTracing() {
return ofNullable(getSingleConfig(getTagName(TracingConfig.class)));
}
@DisableInject
public void setSsl(SslConfig sslConfig) {
addConfig(sslConfig);
@ -223,6 +233,7 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
getApplication().ifPresent(ApplicationConfig::refresh);
getMonitor().ifPresent(MonitorConfig::refresh);
getMetrics().ifPresent(MetricsConfig::refresh);
getTracing().ifPresent(TracingConfig::refresh);
getSsl().ifPresent(SslConfig::refresh);
getProtocols().forEach(ProtocolConfig::refresh);
@ -243,6 +254,8 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
// load dubbo.metrics.xxx
loadConfigsOfTypeFromProps(MetricsConfig.class);
loadConfigsOfTypeFromProps(TracingConfig.class);
// load multiple config types:
// load dubbo.protocols.xxx
loadConfigsOfTypeFromProps(ProtocolConfig.class);
@ -269,12 +282,13 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
private void checkConfigs() {
// check config types (ignore metadata-center)
List<Class<? extends AbstractConfig>> multipleConfigTypes = Arrays.asList(
ApplicationConfig.class,
ProtocolConfig.class,
RegistryConfig.class,
MonitorConfig.class,
MetricsConfig.class,
SslConfig.class);
ApplicationConfig.class,
ProtocolConfig.class,
RegistryConfig.class,
MonitorConfig.class,
MetricsConfig.class,
TracingConfig.class,
SslConfig.class);
for (Class<? extends AbstractConfig> configType : multipleConfigTypes) {
checkDefaultAndValidateConfigs(configType);
@ -290,7 +304,7 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE
ProtocolConfig prevProtocol = protocolPortMap.get(port);
if (prevProtocol != null) {
throw new IllegalStateException("Duplicated port used by protocol configs, port: " + port +
", configs: " + Arrays.asList(prevProtocol, protocol));
", configs: " + Arrays.asList(prevProtocol, protocol));
}
protocolPortMap.put(port, protocol);
}

View File

@ -36,6 +36,7 @@ import org.apache.dubbo.config.ReferenceConfigBase;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfigBase;
import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.rpc.model.ModuleModel;
import java.util.Arrays;
@ -352,6 +353,10 @@ public class ModuleConfigManager extends AbstractConfigManager implements Module
return applicationConfigManager.getMetrics();
}
public Optional<TracingConfig> getTracing() {
return applicationConfigManager.getTracing();
}
public Optional<SslConfig> getSsl() {
return applicationConfigManager.getSsl();
}

View File

@ -0,0 +1,96 @@
/*
* 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.config.nested;
import org.apache.dubbo.config.support.Nested;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class BaggageConfig implements Serializable {
private Boolean enabled = true;
/**
* Correlation configuration.
*/
@Nested
private Correlation correlation = new Correlation();
/**
* List of fields that are referenced the same in-process as it is on the wire.
* For example, the field "x-vcap-request-id" would be set as-is including the
* prefix.
*/
private List<String> remoteFields = new ArrayList<>();
public Boolean getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public Correlation getCorrelation() {
return correlation;
}
public void setCorrelation(Correlation correlation) {
this.correlation = correlation;
}
public List<String> getRemoteFields() {
return remoteFields;
}
public void setRemoteFields(List<String> remoteFields) {
this.remoteFields = remoteFields;
}
public static class Correlation implements Serializable {
/**
* Whether to enable correlation of the baggage context with logging contexts.
*/
private boolean enabled = true;
/**
* List of fields that should be correlated with the logging context. That
* means that these fields would end up as key-value pairs in e.g. MDC.
*/
private List<String> fields = new ArrayList<>();
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public List<String> getFields() {
return this.fields;
}
public void setFields(List<String> fields) {
this.fields = fields;
}
}
}

View File

@ -0,0 +1,40 @@
/*
* 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.config.nested;
import java.io.Serializable;
public class PropagationConfig implements Serializable {
public static final String B3 = "B3";
public static final String W3C = "W3C";
/**
* Tracing context propagation type.
*/
private String type = W3C;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}

View File

@ -0,0 +1,35 @@
/*
* 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.config.nested;
import java.io.Serializable;
public class SamplingConfig implements Serializable {
/**
* Probability in the range from 0.0 to 1.0 that a trace will be sampled.
*/
private float probability = 0.10f;
public float getProbability() {
return this.probability;
}
public void setProbability(float probability) {
this.probability = probability;
}
}

View File

@ -39,6 +39,7 @@ import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.config.bootstrap.builders.ApplicationBuilder;
import org.apache.dubbo.config.bootstrap.builders.ConfigCenterBuilder;
import org.apache.dubbo.config.bootstrap.builders.ConsumerBuilder;
@ -703,6 +704,12 @@ public final class DubboBootstrap {
return this;
}
public DubboBootstrap tracing(TracingConfig tracing){
tracing.setScopeModel(applicationModel);
configManager.setTracing(tracing);
return this;
}
public DubboBootstrap ssl(SslConfig sslConfig) {
sslConfig.setScopeModel(applicationModel);
configManager.setSsl(sslConfig);

View File

@ -48,6 +48,7 @@ import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.monitor.MonitorFactory;
import org.apache.dubbo.monitor.MonitorService;
import org.apache.dubbo.registry.RegistryService;
@ -544,6 +545,12 @@ public class ConfigValidationUtils {
}
}
public static void validateTracingConfig(TracingConfig tracingConfig) {
if (tracingConfig == null) {
return;
}
}
public static void validateSslConfig(SslConfig sslConfig) {
if (sslConfig == null) {
return;

View File

@ -27,6 +27,7 @@ import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.config.context.ConfigValidator;
public class DefaultConfigValidator implements ConfigValidator {
@ -51,6 +52,8 @@ public class DefaultConfigValidator implements ConfigValidator {
ConfigValidationUtils.validateModuleConfig((ModuleConfig) config);
} else if (config instanceof MetricsConfig) {
ConfigValidationUtils.validateMetricsConfig((MetricsConfig) config);
} else if (config instanceof TracingConfig) {
ConfigValidationUtils.validateTracingConfig((TracingConfig) config);
} else if (config instanceof SslConfig) {
ConfigValidationUtils.validateSslConfig((SslConfig) config);
}

View File

@ -29,6 +29,7 @@ import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.config.context.AbstractConfigManager;
import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.config.spring.ConfigCenterBean;
@ -109,6 +110,7 @@ public class DubboConfigBeanInitializer implements BeanFactoryAware, Initializin
loadConfigBeansOfType(ConfigCenterBean.class, configManager);
loadConfigBeansOfType(MetadataReportConfig.class, configManager);
loadConfigBeansOfType(MetricsConfig.class, configManager);
loadConfigBeansOfType(TracingConfig.class, configManager);
loadConfigBeansOfType(SslConfig.class, configManager);
// load module config beans

View File

@ -27,6 +27,7 @@ import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.config.spring.ConfigCenterBean;
import com.alibaba.spring.beans.factory.annotation.EnableConfigurationBeanBinding;
@ -66,6 +67,7 @@ public class DubboConfigConfiguration {
@EnableConfigurationBeanBinding(prefix = "dubbo.config-center", type = ConfigCenterBean.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.metadata-report", type = MetadataReportConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.metrics", type = MetricsConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.tracing", type = TracingConfig.class),
@EnableConfigurationBeanBinding(prefix = "dubbo.ssl", type = SslConfig.class)
})
public static class Single {
@ -85,7 +87,8 @@ public class DubboConfigConfiguration {
@EnableConfigurationBeanBinding(prefix = "dubbo.consumers", type = ConsumerConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.config-centers", type = ConfigCenterBean.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.metadata-reports", type = MetadataReportConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.metricses", type = MetricsConfig.class, multiple = true)
@EnableConfigurationBeanBinding(prefix = "dubbo.metricses", type = MetricsConfig.class, multiple = true),
@EnableConfigurationBeanBinding(prefix = "dubbo.tracing", type = TracingConfig.class)
})
public static class Multiple {

View File

@ -27,6 +27,7 @@ import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.config.spring.ConfigCenterBean;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.config.spring.ServiceBean;
@ -60,6 +61,7 @@ public class DubboNamespaceHandler extends NamespaceHandlerSupport implements Co
registerBeanDefinitionParser("metadata-report", new DubboBeanDefinitionParser(MetadataReportConfig.class));
registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class));
registerBeanDefinitionParser("metrics", new DubboBeanDefinitionParser(MetricsConfig.class));
registerBeanDefinitionParser("tracing", new DubboBeanDefinitionParser(TracingConfig.class));
registerBeanDefinitionParser("ssl", new DubboBeanDefinitionParser(SslConfig.class));
registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class));
registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class));

View File

@ -356,7 +356,8 @@
</xsd:attribute>
<xsd:attribute name="prefer-serialization" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ The prefer serialization protocol of service, multiple serialization protocol are separated by commas, default fastjson2,hessian2. ]]></xsd:documentation>
<xsd:documentation>
<![CDATA[ The prefer serialization protocol of service, multiple serialization protocol are separated by commas, default fastjson2,hessian2. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="export-async" type="xsd:boolean">
@ -504,12 +505,14 @@
</xsd:attribute>
<xsd:attribute name="trust-serialize-class-level" type="xsd:integer">
<xsd:annotation>
<xsd:documentation><![CDATA[ The trust package level of serialize class scanning. ]]></xsd:documentation>
<xsd:documentation>
<![CDATA[ The trust package level of serialize class scanning. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="check-serializable" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation><![CDATA[ Whether restrict the serialized should implement Serializable interface. ]]></xsd:documentation>
<xsd:documentation>
<![CDATA[ Whether restrict the serialized should implement Serializable interface. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="qos-enable" type="xsd:boolean">
@ -534,12 +537,14 @@
</xsd:attribute>
<xsd:attribute name="qos-accept-foreign-ip-whitelist" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ Support specifying foreign ip in whitelist when accepting foreign ip is disabled. ]]></xsd:documentation>
<xsd:documentation>
<![CDATA[ Support specifying foreign ip in whitelist when accepting foreign ip is disabled. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="qos-anonymous-access-permission-level" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ Anonymous (any foreign ip) access level, the default is NONE, can not access any cmd. ]]></xsd:documentation>
<xsd:documentation>
<![CDATA[ Anonymous (any foreign ip) access level, the default is NONE, can not access any cmd. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
@ -1083,6 +1088,19 @@
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="tracingType">
<xsd:all>
<xsd:element ref="sampling" minOccurs="0"/>
<xsd:element ref="propagation" minOccurs="0"/>
<xsd:element ref="baggage" minOccurs="0"/>
</xsd:all>
<xsd:attribute name="enabled" type="xsd:boolean" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[ Enable tracing. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="prometheusExporterType">
<xsd:attribute name="enabled" type="xsd:boolean">
<xsd:annotation>
@ -1162,6 +1180,7 @@
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="histogramType">
<xsd:attribute name="enabled" type="xsd:boolean">
<xsd:annotation>
@ -1170,6 +1189,55 @@
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="samplingType">
<xsd:attribute name="probability" type="xsd:float">
<xsd:annotation>
<xsd:documentation>
<![CDATA[ Probability in the range from 0.0 to 1.0 that a trace will be sampled. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="propagationType">
<xsd:attribute name="type" type="xsd:string">
<xsd:annotation>
<xsd:documentation>
<![CDATA[ Tracing context propagation type, include W3C and B3. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="baggageType">
<xsd:all>
<xsd:element ref="remoteFields" minOccurs="0"/>
</xsd:all>
<xsd:attribute name="enabled" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation><![CDATA[ Enable baggage or not. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="correlationType">
<xsd:all>
<xsd:element ref="fields" minOccurs="0"/>
</xsd:all>
<xsd:attribute name="enabled" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation>
<![CDATA[ Whether to enable correlation of the baggage context with logging contexts. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="fieldsType">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="name" type="xsd:string"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="methodType">
<xsd:complexContent>
<xsd:extension base="abstractMethodType">
@ -1472,7 +1540,8 @@
</xsd:attribute>
<xsd:attribute name="prefer-serialization" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[ The prefer serialization protocol of service, multiple serialization protocol are separated by commas, default fastjson2,hessian2. ]]></xsd:documentation>
<xsd:documentation>
<![CDATA[ The prefer serialization protocol of service, multiple serialization protocol are separated by commas, default fastjson2,hessian2. ]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="keepalive" type="xsd:boolean">
@ -2043,6 +2112,17 @@
</xsd:annotation>
</xsd:element>
<xsd:element name="tracing" type="tracingType">
<xsd:annotation>
<xsd:documentation><![CDATA[ The tracing service ]]></xsd:documentation>
<xsd:appinfo>
<tool:annotation>
<tool:exports type="org.apache.dubbo.config.TracingConfig"/>
</tool:annotation>
</xsd:appinfo>
</xsd:annotation>
</xsd:element>
<xsd:element name="prometheus-exporter" type="prometheusExporterType">
<xsd:annotation>
<xsd:documentation><![CDATA[ The metrics prometheus exporter config. ]]></xsd:documentation>
@ -2066,4 +2146,45 @@
<xsd:documentation><![CDATA[ The metrics rt histogram config. ]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="sampling" type="samplingType">
<xsd:annotation>
<xsd:documentation><![CDATA[ The tracing sampling config. ]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="propagation" type="propagationType">
<xsd:annotation>
<xsd:documentation><![CDATA[ The tracing propagation config. ]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="baggage" type="baggageType">
<xsd:annotation>
<xsd:documentation><![CDATA[ The tracing baggage config. ]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="remoteFields" type="fieldsType">
<xsd:annotation>
<xsd:documentation>
<![CDATA[ The tracing baggage remoteFields config. List of fields that are referenced
the same in-process as it is on the wire. For example, the field "x-vcap-request-id" would
be set as-is including the prefix. ]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="correlation" type="correlationType">
<xsd:annotation>
<xsd:documentation><![CDATA[ The tracing baggage correlation config. ]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="fields" type="fieldsType">
<xsd:annotation>
<xsd:documentation>
<![CDATA[ List of fields that should be correlated with the logging context. That
means that these fields would end up as key-value pairs in e.g. MDC. ]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:schema>

View File

@ -37,13 +37,17 @@ import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
@Activate(group = PROVIDER, order = -1, onClass = "io.micrometer.observation.NoopObservationRegistry")
public class ObservationReceiverFilter implements Filter, BaseFilter.Listener, ScopeModelAware {
private final ObservationRegistry observationRegistry;
private ObservationRegistry observationRegistry;
private final DubboServerObservationConvention serverObservationConvention;
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

View File

@ -19,6 +19,7 @@ package org.apache.dubbo.metrics.observation;
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;
@ -63,6 +64,9 @@ abstract class AbstractObservationFilterTest extends SampleTestRunner {
invocation.addInvokedInvoker(invoker);
applicationModel.getBeanFactory().registerBean(getObservationRegistry());
TracingConfig tracingConfig = new TracingConfig();
tracingConfig.setEnabled(true);
applicationModel.getApplicationConfigManager().setTracing(tracingConfig);
filter = createFilter(applicationModel);

View File

@ -30,6 +30,7 @@ import org.apache.dubbo.config.ReferenceConfigBase;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfigBase;
import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.config.context.ModuleConfigManager;
import org.apache.dubbo.qos.api.BaseCommand;
@ -108,6 +109,9 @@ public class GetConfig implements BaseCommand {
Optional<MetricsConfig> metricsConfig = configManager.getMetrics();
metricsConfig.ifPresent(config -> appendConfig("MetricsConfig", config.getId(), config, plainOutput, applicationMap, args));
Optional<TracingConfig> tracingConfig = configManager.getTracing();
tracingConfig.ifPresent(config -> appendConfig("TracingConfig", config.getId(), config, plainOutput, applicationMap, args));
Optional<MonitorConfig> monitorConfig = configManager.getMonitor();
monitorConfig.ifPresent(config -> appendConfig("MonitorConfig", config.getId(), config, plainOutput, applicationMap, args));

View File

@ -26,6 +26,7 @@ import org.apache.dubbo.config.MonitorConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.config.context.ConfigMode;
import org.apache.dubbo.config.spring.ConfigCenterBean;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
@ -88,6 +89,9 @@ public class DubboConfigurationProperties {
@NestedConfigurationProperty
private MetricsConfig metrics = new MetricsConfig();
@NestedConfigurationProperty
private TracingConfig tracing = new TracingConfig();
// Multiple Config Bindings
private Map<String, ModuleConfig> modules = new LinkedHashMap<>();
@ -108,6 +112,8 @@ public class DubboConfigurationProperties {
private Map<String, MetricsConfig> metricses = new LinkedHashMap<>();
private Map<String, TracingConfig> tracings = new LinkedHashMap<>();
public Config getConfig() {
return config;
}
@ -204,6 +210,14 @@ public class DubboConfigurationProperties {
this.metrics = metrics;
}
public TracingConfig getTracing() {
return tracing;
}
public void setTracing(TracingConfig tracing) {
this.tracing = tracing;
}
public Map<String, ModuleConfig> getModules() {
return modules;
}
@ -276,6 +290,14 @@ public class DubboConfigurationProperties {
this.metricses = metricses;
}
public Map<String, TracingConfig> getTracings() {
return tracings;
}
public void setTracings(Map<String, TracingConfig> tracings) {
this.tracings = tracings;
}
static class Config {
/**

View File

@ -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.spring.boot.observability.autoconfigure;
import static org.apache.dubbo.spring.boot.util.DubboUtils.DUBBO_PREFIX;
import static org.apache.dubbo.spring.boot.util.DubboUtils.PROPERTY_NAME_SEPARATOR;
/**
* The utilities class for Dubbo Observability
*
* @since 3.2.0
*/
public class ObservabilityUtils {
public static final String DUBBO_TRACING_PREFIX = DUBBO_PREFIX + PROPERTY_NAME_SEPARATOR + "tracing" + PROPERTY_NAME_SEPARATOR;
public static final String DUBBO_TRACING_PROPAGATION = DUBBO_TRACING_PREFIX + "propagation";
public static final String DUBBO_TRACING_BAGGAGE = DUBBO_TRACING_PREFIX + "baggage";
public static final String DUBBO_TRACING_BAGGAGE_CORRELATION = DUBBO_TRACING_BAGGAGE + PROPERTY_NAME_SEPARATOR + "correlation";
public static final String DUBBO_TRACING_BAGGAGE_ENABLED = DUBBO_TRACING_BAGGAGE + PROPERTY_NAME_SEPARATOR + "enabled";
}

View File

@ -16,6 +16,11 @@
*/
package org.apache.dubbo.spring.boot.observability.autoconfigure.brave;
import org.apache.dubbo.spring.boot.autoconfigure.DubboConfigurationProperties;
import org.apache.dubbo.spring.boot.observability.annotation.ConditionalOnDubboTracingEnable;
import org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration;
import org.apache.dubbo.spring.boot.observability.autoconfigure.ObservabilityUtils;
import brave.CurrentSpanCustomizer;
import brave.SpanCustomizer;
import brave.Tracing;
@ -46,9 +51,6 @@ import io.micrometer.tracing.brave.bridge.W3CPropagation;
import io.micrometer.tracing.exporter.SpanExportingPredicate;
import io.micrometer.tracing.exporter.SpanFilter;
import io.micrometer.tracing.exporter.SpanReporter;
import org.apache.dubbo.spring.boot.observability.annotation.ConditionalOnDubboTracingEnable;
import org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration;
import org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@ -65,12 +67,15 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import static org.apache.dubbo.config.nested.PropagationConfig.B3;
import static org.apache.dubbo.config.nested.PropagationConfig.W3C;
/**
* provider Brave when you are using Boot <3.0 or you are not using spring-boot-starter-actuator
*/
@AutoConfiguration(before = DubboMicrometerTracingAutoConfiguration.class, afterName = "org.springframework.boot.actuate.autoconfigure.tracing.BraveAutoConfiguration")
@ConditionalOnClass({Tracer.class, BraveTracer.class})
@EnableConfigurationProperties(DubboTracingProperties.class)
@EnableConfigurationProperties(DubboConfigurationProperties.class)
@ConditionalOnDubboTracingEnable
public class BraveAutoConfiguration {
@ -87,8 +92,8 @@ public class BraveAutoConfiguration {
CompositeSpanHandler compositeSpanHandler(ObjectProvider<SpanExportingPredicate> predicates,
ObjectProvider<SpanReporter> reporters, ObjectProvider<SpanFilter> filters) {
return new CompositeSpanHandler(predicates.orderedStream().collect(Collectors.toList()),
reporters.orderedStream().collect(Collectors.toList()),
filters.orderedStream().collect(Collectors.toList()));
reporters.orderedStream().collect(Collectors.toList()),
filters.orderedStream().collect(Collectors.toList()));
}
@Bean
@ -98,8 +103,8 @@ public class BraveAutoConfiguration {
Propagation.Factory propagationFactory, Sampler sampler) {
String applicationName = environment.getProperty("spring.application.name", DEFAULT_APPLICATION_NAME);
Tracing.Builder builder = Tracing.newBuilder().currentTraceContext(currentTraceContext).traceId128Bit(true)
.supportsJoin(false).propagationFactory(propagationFactory).sampler(sampler)
.localServiceName(applicationName);
.supportsJoin(false).propagationFactory(propagationFactory).sampler(sampler)
.localServiceName(applicationName);
spanHandlers.forEach(builder::addSpanHandler);
for (TracingCustomizer tracingCustomizer : tracingCustomizers) {
tracingCustomizer.customize(builder);
@ -127,8 +132,8 @@ public class BraveAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public Sampler braveSampler(DubboTracingProperties properties) {
return Sampler.create(properties.getSampling().getProbability());
public Sampler braveSampler(DubboConfigurationProperties properties) {
return Sampler.create(properties.getTracing().getSampling().getProbability());
}
@Bean
@ -156,13 +161,13 @@ public class BraveAutoConfiguration {
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(value = "dubbo.tracing.baggage.enabled", havingValue = "false")
@ConditionalOnProperty(value = ObservabilityUtils.DUBBO_TRACING_BAGGAGE_ENABLED, havingValue = "false")
static class BraveNoBaggageConfiguration {
@Bean
@ConditionalOnMissingBean
Propagation.Factory propagationFactory(DubboTracingProperties tracing) {
DubboTracingProperties.Propagation.PropagationType type = tracing.getPropagation().getType();
Propagation.Factory propagationFactory(DubboConfigurationProperties tracing) {
String type = tracing.getTracing().getPropagation().getType();
switch (type) {
case B3:
return B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build();
@ -175,22 +180,22 @@ public class BraveAutoConfiguration {
}
@ConditionalOnProperty(value = "dubbo.tracing.baggage.enabled", matchIfMissing = true)
@ConditionalOnProperty(value = ObservabilityUtils.DUBBO_TRACING_BAGGAGE_ENABLED, matchIfMissing = true)
@Configuration(proxyBeanMethods = false)
static class BraveBaggageConfiguration {
private final DubboTracingProperties dubboTracingProperties;
private final DubboConfigurationProperties dubboConfigProperties;
public BraveBaggageConfiguration(DubboTracingProperties dubboTracingProperties) {
this.dubboTracingProperties = dubboTracingProperties;
public BraveBaggageConfiguration(DubboConfigurationProperties dubboConfigProperties) {
this.dubboConfigProperties = dubboConfigProperties;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "dubbo.tracing.propagation", value = "type", havingValue = "B3")
@ConditionalOnProperty(prefix = ObservabilityUtils.DUBBO_TRACING_PROPAGATION, value = "type", havingValue = "B3")
BaggagePropagation.FactoryBuilder b3PropagationFactoryBuilder(
ObjectProvider<BaggagePropagationCustomizer> baggagePropagationCustomizers) {
ObjectProvider<BaggagePropagationCustomizer> baggagePropagationCustomizers) {
Propagation.Factory delegate =
B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build();
B3Propagation.newFactoryBuilder().injectFormat(B3Propagation.Format.SINGLE_NO_PARENT).build();
BaggagePropagation.FactoryBuilder builder = BaggagePropagation.newFactoryBuilder(delegate);
baggagePropagationCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
@ -199,9 +204,9 @@ public class BraveAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "dubbo.tracing.propagation", value = "type", havingValue = "W3C", matchIfMissing = true)
@ConditionalOnProperty(prefix = ObservabilityUtils.DUBBO_TRACING_PROPAGATION, value = "type", havingValue = "W3C", matchIfMissing = true)
BaggagePropagation.FactoryBuilder w3cPropagationFactoryBuilder(
ObjectProvider<BaggagePropagationCustomizer> baggagePropagationCustomizers) {
ObjectProvider<BaggagePropagationCustomizer> baggagePropagationCustomizers) {
Propagation.Factory delegate = new W3CPropagation(BRAVE_BAGGAGE_MANAGER, Collections.emptyList());
BaggagePropagation.FactoryBuilder builder = BaggagePropagation.newFactoryBuilder(delegate);
@ -214,7 +219,7 @@ public class BraveAutoConfiguration {
@Order(0)
BaggagePropagationCustomizer remoteFieldsBaggagePropagationCustomizer() {
return (builder) -> {
List<String> remoteFields = dubboTracingProperties.getBaggage().getRemoteFields();
List<String> remoteFields = dubboConfigProperties.getTracing().getBaggage().getRemoteFields();
for (String fieldName : remoteFields) {
builder.add(BaggagePropagationConfig.SingleBaggageField.remote(BaggageField.create(fieldName)));
}
@ -230,7 +235,7 @@ public class BraveAutoConfiguration {
@Bean
@ConditionalOnMissingBean
CorrelationScopeDecorator.Builder mdcCorrelationScopeDecoratorBuilder(
ObjectProvider<CorrelationScopeCustomizer> correlationScopeCustomizers) {
ObjectProvider<CorrelationScopeCustomizer> correlationScopeCustomizers) {
CorrelationScopeDecorator.Builder builder = MDCScopeDecorator.newBuilder();
correlationScopeCustomizers.orderedStream().forEach((customizer) -> customizer.customize(builder));
return builder;
@ -238,14 +243,14 @@ public class BraveAutoConfiguration {
@Bean
@Order(0)
@ConditionalOnProperty(prefix = "dubbo.tracing.baggage.correlation", name = "enabled",
matchIfMissing = true)
@ConditionalOnProperty(prefix = ObservabilityUtils.DUBBO_TRACING_BAGGAGE_CORRELATION, name = "enabled",
matchIfMissing = true)
CorrelationScopeCustomizer correlationFieldsCorrelationScopeCustomizer() {
return (builder) -> {
List<String> correlationFields = this.dubboTracingProperties.getBaggage().getCorrelation().getFields();
List<String> correlationFields = this.dubboConfigProperties.getTracing().getBaggage().getCorrelation().getFields();
for (String field : correlationFields) {
builder.add(CorrelationScopeConfig.SingleCorrelationField.newBuilder(BaggageField.create(field))
.flushOnUpdate().build());
.flushOnUpdate().build());
}
};
}

View File

@ -17,9 +17,10 @@
package org.apache.dubbo.spring.boot.observability.autoconfigure.otel;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.spring.boot.autoconfigure.DubboConfigurationProperties;
import org.apache.dubbo.spring.boot.observability.annotation.ConditionalOnDubboTracingEnable;
import org.apache.dubbo.spring.boot.observability.autoconfigure.DubboMicrometerTracingAutoConfiguration;
import org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties;
import org.apache.dubbo.spring.boot.observability.autoconfigure.ObservabilityUtils;
import io.micrometer.tracing.SpanCustomizer;
import io.micrometer.tracing.exporter.SpanExportingPredicate;
@ -74,7 +75,7 @@ import java.util.stream.Collectors;
@AutoConfiguration(before = DubboMicrometerTracingAutoConfiguration.class, afterName = "org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration")
@ConditionalOnDubboTracingEnable
@ConditionalOnClass({OtelTracer.class, SdkTracerProvider.class, OpenTelemetry.class})
@EnableConfigurationProperties(DubboTracingProperties.class)
@EnableConfigurationProperties(DubboConfigurationProperties.class)
public class OpenTelemetryAutoConfiguration {
/**
@ -82,10 +83,10 @@ public class OpenTelemetryAutoConfiguration {
*/
private static final String DEFAULT_APPLICATION_NAME = "application";
private final DubboTracingProperties dubboTracingProperties;
private final DubboConfigurationProperties dubboConfigProperties;
OpenTelemetryAutoConfiguration(DubboTracingProperties dubboTracingProperties) {
this.dubboTracingProperties = dubboTracingProperties;
OpenTelemetryAutoConfiguration(DubboConfigurationProperties dubboConfigProperties) {
this.dubboConfigProperties = dubboConfigProperties;
}
@Bean
@ -115,7 +116,7 @@ public class OpenTelemetryAutoConfiguration {
@Bean
@ConditionalOnMissingBean
Sampler otelSampler() {
Sampler rootSampler = Sampler.traceIdRatioBased(this.dubboTracingProperties.getSampling().getProbability());
Sampler rootSampler = Sampler.traceIdRatioBased(this.dubboConfigProperties.getTracing().getSampling().getProbability());
return Sampler.parentBased(rootSampler);
}
@ -140,7 +141,7 @@ public class OpenTelemetryAutoConfiguration {
OtelTracer micrometerOtelTracer(Tracer tracer, OtelTracer.EventPublisher eventPublisher,
OtelCurrentTraceContext otelCurrentTraceContext) {
return new OtelTracer(tracer, otelCurrentTraceContext, eventPublisher,
new OtelBaggageManager(otelCurrentTraceContext, this.dubboTracingProperties.getBaggage().getRemoteFields(),
new OtelBaggageManager(otelCurrentTraceContext, this.dubboConfigProperties.getTracing().getBaggage().getRemoteFields(),
Collections.emptyList()));
}
@ -176,21 +177,21 @@ public class OpenTelemetryAutoConfiguration {
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "dubbo.tracing.baggage", name = "enabled", matchIfMissing = true)
@ConditionalOnProperty(prefix = ObservabilityUtils.DUBBO_TRACING_BAGGAGE, name = "enabled", matchIfMissing = true)
static class BaggageConfiguration {
private final DubboTracingProperties tracingProperties;
private final DubboConfigurationProperties dubboConfigProperties;
BaggageConfiguration(DubboTracingProperties tracingProperties) {
this.tracingProperties = tracingProperties;
BaggageConfiguration(DubboConfigurationProperties dubboConfigProperties) {
this.dubboConfigProperties = dubboConfigProperties;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "dubbo.tracing.propagation", name = "type", havingValue = "W3C",
@ConditionalOnProperty(prefix = ObservabilityUtils.DUBBO_TRACING_PROPAGATION, name = "type", havingValue = "W3C",
matchIfMissing = true)
TextMapPropagator w3cTextMapPropagatorWithBaggage(OtelCurrentTraceContext otelCurrentTraceContext) {
List<String> remoteFields = this.tracingProperties.getBaggage().getRemoteFields();
List<String> remoteFields = this.dubboConfigProperties.getTracing().getBaggage().getRemoteFields();
return TextMapPropagator.composite(W3CTraceContextPropagator.getInstance(),
W3CBaggagePropagator.getInstance(), new BaggageTextMapPropagator(remoteFields,
new OtelBaggageManager(otelCurrentTraceContext, remoteFields, Collections.emptyList())));
@ -198,9 +199,9 @@ public class OpenTelemetryAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "dubbo.tracing.propagation", name = "type", havingValue = "B3")
@ConditionalOnProperty(prefix = ObservabilityUtils.DUBBO_TRACING_PROPAGATION, name = "type", havingValue = "B3")
TextMapPropagator b3BaggageTextMapPropagator(OtelCurrentTraceContext otelCurrentTraceContext) {
List<String> remoteFields = this.tracingProperties.getBaggage().getRemoteFields();
List<String> remoteFields = this.dubboConfigProperties.getTracing().getBaggage().getRemoteFields();
return TextMapPropagator.composite(B3Propagator.injectingSingleHeader(),
new BaggageTextMapPropagator(remoteFields,
new OtelBaggageManager(otelCurrentTraceContext, remoteFields, Collections.emptyList())));
@ -208,28 +209,28 @@ public class OpenTelemetryAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "dubbo.tracing.baggage.correlation", name = "enabled",
@ConditionalOnProperty(prefix = ObservabilityUtils.DUBBO_TRACING_BAGGAGE_CORRELATION, name = "enabled",
matchIfMissing = true)
Slf4JBaggageEventListener otelSlf4JBaggageEventListener() {
return new Slf4JBaggageEventListener(this.tracingProperties.getBaggage().getCorrelation().getFields());
return new Slf4JBaggageEventListener(this.dubboConfigProperties.getTracing().getBaggage().getCorrelation().getFields());
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "dubbo.tracing.baggage", name = "enabled", havingValue = "false")
@ConditionalOnProperty(prefix = ObservabilityUtils.DUBBO_TRACING_BAGGAGE, name = "enabled", havingValue = "false")
static class NoBaggageConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "dubbo.tracing.propagation", name = "type", havingValue = "B3")
@ConditionalOnProperty(prefix = ObservabilityUtils.DUBBO_TRACING_PROPAGATION, name = "type", havingValue = "B3")
B3Propagator b3TextMapPropagator() {
return B3Propagator.injectingSingleHeader();
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "dubbo.tracing.propagation", name = "type", havingValue = "W3C",
@ConditionalOnProperty(prefix = ObservabilityUtils.DUBBO_TRACING_PROPAGATION, name = "type", havingValue = "W3C",
matchIfMissing = true)
W3CTraceContextPropagator w3cTextMapPropagatorWithoutBaggage() {
return W3CTraceContextPropagator.getInstance();

View File

@ -1,191 +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.spring.boot.observability.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.ArrayList;
import java.util.List;
@ConfigurationProperties("dubbo.tracing")
public class DubboTracingProperties {
/**
* Whether auto-configuration of tracing is enabled.
*/
private boolean enabled = true;
/**
* Sampling configuration.
*/
private final Sampling sampling = new Sampling();
/**
* Baggage configuration.
*/
private final Baggage baggage = new Baggage();
/**
* Propagation configuration.
*/
private final Propagation propagation = new Propagation();
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Sampling getSampling() {
return this.sampling;
}
public Baggage getBaggage() {
return this.baggage;
}
public Propagation getPropagation() {
return this.propagation;
}
public static class Sampling {
/**
* Probability in the range from 0.0 to 1.0 that a trace will be sampled.
*/
private float probability = 0.10f;
public float getProbability() {
return this.probability;
}
public void setProbability(float probability) {
this.probability = probability;
}
}
public static class Baggage {
/**
* Whether to enable Micrometer Tracing baggage propagation.
*/
private boolean enabled = true;
/**
* Correlation configuration.
*/
private Correlation correlation = new Correlation();
/**
* List of fields that are referenced the same in-process as it is on the wire.
* For example, the field "x-vcap-request-id" would be set as-is including the
* prefix.
*/
private List<String> remoteFields = new ArrayList<>();
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Correlation getCorrelation() {
return this.correlation;
}
public void setCorrelation(Correlation correlation) {
this.correlation = correlation;
}
public List<String> getRemoteFields() {
return this.remoteFields;
}
public void setRemoteFields(List<String> remoteFields) {
this.remoteFields = remoteFields;
}
public static class Correlation {
/**
* Whether to enable correlation of the baggage context with logging contexts.
*/
private boolean enabled = true;
/**
* List of fields that should be correlated with the logging context. That
* means that these fields would end up as key-value pairs in e.g. MDC.
*/
private List<String> fields = new ArrayList<>();
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public List<String> getFields() {
return this.fields;
}
public void setFields(List<String> fields) {
this.fields = fields;
}
}
}
public static class Propagation {
/**
* Tracing context propagation type.
*/
private PropagationType type = PropagationType.W3C;
public PropagationType getType() {
return this.type;
}
public void setType(PropagationType type) {
this.type = type;
}
public enum PropagationType {
/**
* B3 propagation type.
*/
B3,
/**
* W3C propagation type.
*/
W3C
}
}
}

View File

@ -1,82 +0,0 @@
{
"groups": [
{
"name": "dubbo.tracing",
"type": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties",
"sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties"
},
{
"name": "dubbo.tracing.baggage",
"type": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage",
"sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties",
"sourceMethod": "getBaggage()"
},
{
"name": "dubbo.tracing.baggage.correlation",
"type": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage$Correlation",
"sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage",
"sourceMethod": "getCorrelation()"
},
{
"name": "dubbo.tracing.propagation",
"type": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Propagation",
"sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties",
"sourceMethod": "getPropagation()"
},
{
"name": "dubbo.tracing.sampling",
"type": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Sampling",
"sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties",
"sourceMethod": "getSampling()"
}
],
"properties": [
{
"name": "dubbo.tracing.baggage.correlation.enabled",
"type": "java.lang.Boolean",
"description": "Whether to enable correlation of the baggage context with logging contexts.",
"sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage$Correlation",
"defaultValue": true
},
{
"name": "dubbo.tracing.baggage.correlation.fields",
"type": "java.util.List<java.lang.String>",
"description": "List of fields that should be correlated with the logging context. That means that these fields would end up as key-value pairs in e.g. MDC.",
"sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage$Correlation"
},
{
"name": "dubbo.tracing.baggage.enabled",
"type": "java.lang.Boolean",
"description": "Whether to enable Micrometer Tracing baggage propagation.",
"sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage",
"defaultValue": true
},
{
"name": "dubbo.tracing.baggage.remote-fields",
"type": "java.util.List<java.lang.String>",
"description": "List of fields that are referenced the same in-process as it is on the wire. For example, the field \"x-vcap-request-id\" would be set as-is including the prefix.",
"sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Baggage"
},
{
"name": "dubbo.tracing.enabled",
"type": "java.lang.Boolean",
"description": "Whether auto-configuration of tracing is enabled.",
"sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties",
"defaultValue": true
},
{
"name": "dubbo.tracing.propagation.type",
"type": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Propagation$PropagationType",
"description": "Tracing context propagation type.",
"sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Propagation"
},
{
"name": "dubbo.tracing.sampling.probability",
"type": "java.lang.Float",
"description": "Probability in the range from 0.0 to 1.0 that a trace will be sampled.",
"sourceType": "org.apache.dubbo.spring.boot.observability.config.DubboTracingProperties$Sampling",
"defaultValue": 0.1
}
],
"hints": []
}