From ee9005f95eef3f0af2620741fa22baeedf7141d2 Mon Sep 17 00:00:00 2001 From: Haotian Zhang Date: Tue, 3 Dec 2024 21:30:55 +0800 Subject: [PATCH] feat:upgrade trace plugin. (#1467) --- CHANGELOG.md | 3 +- pom.xml | 2 +- .../registry/PolarisServiceRegistry.java | 2 + .../tencent/cloud/common/util/OtUtils.java | 84 ++++++++++++++++ spring-cloud-tencent-dependencies/pom.xml | 4 +- .../TraceClientFinallyEnhancedPlugin.java | 51 ++++++++++ .../trace/TraceClientPreEnhancedPlugin.java | 79 +++++++++++++++ ...java => TraceServerPreEnhancedPlugin.java} | 41 +++----- .../PolarisSpanAttributesProvider.java | 99 +++++++++++++++++++ .../SpanAttributesProvider.java | 17 +++- .../tsf/TsfSpanAttributesProvider.java | 8 +- .../TraceEnhancedPluginAutoConfiguration.java | 39 +++++++- .../TsfTracePropertiesAutoConfiguration.java | 36 ------- .../main/resources/META-INF/spring.factories | 5 +- .../tsf/TsfCoreEnvironmentPostProcessor.java | 6 ++ .../PolarisServerIntrospector.java | 50 ++++++++++ .../PolarisRibbonClientConfiguration.java | 6 ++ .../plugin/EnhancedPluginContext.java | 14 +-- .../plugin/PluginOrderConstant.java | 12 ++- 19 files changed, 468 insertions(+), 90 deletions(-) create mode 100644 spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/OtUtils.java create mode 100644 spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceClientFinallyEnhancedPlugin.java create mode 100644 spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceClientPreEnhancedPlugin.java rename spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/{TraceServerMetadataEnhancedPlugin.java => TraceServerPreEnhancedPlugin.java} (57%) create mode 100644 spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/attribute/PolarisSpanAttributesProvider.java rename spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/{ => attribute}/SpanAttributesProvider.java (67%) rename spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/{ => attribute}/tsf/TsfSpanAttributesProvider.java (91%) delete mode 100644 spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/tsf/TsfTracePropertiesAutoConfiguration.java create mode 100644 spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisServerIntrospector.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 570767af89..41b284d6a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,4 +17,5 @@ - [fix:fix no registry when lossless is disabled.](https://github.com/Tencent/spring-cloud-tencent/pull/1313) - [fix: memory not released while using wildcard api call with circuitbreaker enabled](https://github.com/Tencent/spring-cloud-tencent/pull/1335) - [feat: support 2.0.0](https://github.com/Tencent/spring-cloud-tencent/pull/1458) -- [feat: support 2.0.0 config](https://github.com/Tencent/spring-cloud-tencent/pull/1463) \ No newline at end of file +- [feat: support 2.0.0 config](https://github.com/Tencent/spring-cloud-tencent/pull/1463) +- [feat:upgrade trace plugin.](https://github.com/Tencent/spring-cloud-tencent/pull/1467) \ No newline at end of file diff --git a/pom.xml b/pom.xml index 04f87adf69..070e126a85 100644 --- a/pom.xml +++ b/pom.xml @@ -90,7 +90,7 @@ - 2.0.0.0-Hoxton.SR12-RC1 + 2.0.0.0-Hoxton.SR12-SNAPSHOT 5.2.25.RELEASE diff --git a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java index 582f801988..d71810d389 100644 --- a/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java +++ b/spring-cloud-starter-tencent-polaris-discovery/src/main/java/com/tencent/cloud/polaris/registry/PolarisServiceRegistry.java @@ -26,6 +26,7 @@ import com.tencent.cloud.common.metadata.StaticMetadataManager; import com.tencent.cloud.common.util.OkHttpUtil; +import com.tencent.cloud.common.util.OtUtils; import com.tencent.cloud.polaris.PolarisDiscoveryProperties; import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.discovery.PolarisDiscoveryHandler; @@ -111,6 +112,7 @@ public void register(PolarisRegistration registration) { InstanceRegisterRequest instanceRegisterRequest = new InstanceRegisterRequest(); instanceRegisterRequest.setNamespace(polarisDiscoveryProperties.getNamespace()); instanceRegisterRequest.setService(serviceId); + OtUtils.setOtServiceNameIfNeeded(serviceId); instanceRegisterRequest.setHost(registration.getHost()); instanceRegisterRequest.setPort(registration.getPort()); instanceRegisterRequest.setWeight(polarisDiscoveryProperties.getWeight()); diff --git a/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/OtUtils.java b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/OtUtils.java new file mode 100644 index 0000000000..47c8af2ef4 --- /dev/null +++ b/spring-cloud-tencent-commons/src/main/java/com/tencent/cloud/common/util/OtUtils.java @@ -0,0 +1,84 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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 com.tencent.cloud.common.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Utils for otel. + * + * @author Haotian Zhang + */ +public final class OtUtils { + + /** + * Key of otel resource attributes. + */ + public static final String OTEL_RESOURCE_ATTRIBUTES = "otel.resource.attributes"; + + /** + * Key of lane id. + */ + public static final String OTEL_LANE_ID_KEY = "lane-id"; + + private static final Logger LOGGER = LoggerFactory.getLogger(OtUtils.class); + + private static String otServiceName = null; + + private OtUtils() { + } + + /** + * If the service name is not set, it will be set when the service is registered. + * + * @param serviceName service name + */ + public static void setOtServiceNameIfNeeded(String serviceName) { + try { + String attributes = null; + if (null != System.getenv(OTEL_RESOURCE_ATTRIBUTES)) { + attributes = System.getenv(OTEL_RESOURCE_ATTRIBUTES); + } + if (null != System.getProperty(OTEL_RESOURCE_ATTRIBUTES)) { + attributes = System.getProperty(OTEL_RESOURCE_ATTRIBUTES); + } + if (attributes == null || !attributes.contains("service.name")) { + otServiceName = serviceName; + System.setProperty(OTEL_RESOURCE_ATTRIBUTES, "service.name=" + serviceName); + LOGGER.info("update ot service name, old:{}, new:{}", + attributes, System.getProperty(OTEL_RESOURCE_ATTRIBUTES)); + } + else { + for (String attribute : attributes.split(",")) { + if (attribute.contains("service.name=")) { + otServiceName = attribute.replace("service.name=", ""); + LOGGER.info("use env ot service name:{}", otServiceName); + } + } + } + } + catch (Throwable throwable) { + LOGGER.error("set ot service name failed.", throwable); + } + } + + public static String getOtServiceName() { + return otServiceName; + } +} diff --git a/spring-cloud-tencent-dependencies/pom.xml b/spring-cloud-tencent-dependencies/pom.xml index c606bff543..578b8fe2ed 100644 --- a/spring-cloud-tencent-dependencies/pom.xml +++ b/spring-cloud-tencent-dependencies/pom.xml @@ -70,10 +70,10 @@ - 2.0.0.0-Hoxton.SR12-RC1 + 2.0.0.0-Hoxton.SR12-SNAPSHOT - 2.0.0.0-RC5 + 2.0.0.0-SNAPSHOT 32.0.1-jre 1.2.13 1.7.0 diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceClientFinallyEnhancedPlugin.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceClientFinallyEnhancedPlugin.java new file mode 100644 index 0000000000..83e640e6ba --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceClientFinallyEnhancedPlugin.java @@ -0,0 +1,51 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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 com.tencent.cloud.plugin.trace; + +import com.tencent.cloud.plugin.trace.attribute.SpanAttributesProvider; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant; +import com.tencent.polaris.api.utils.ClassUtils; +import io.opentelemetry.context.Scope; + +public class TraceClientFinallyEnhancedPlugin implements EnhancedPlugin { + + public TraceClientFinallyEnhancedPlugin() { + } + + @Override + public EnhancedPluginType getType() { + return EnhancedPluginType.Client.FINALLY; + } + + @Override + public void run(EnhancedPluginContext context) throws Throwable { + Object otScope = context.getExtraData().get(SpanAttributesProvider.OT_SCOPE_KEY); + if (ClassUtils.isClassPresent("io.opentelemetry.context.Scope") && otScope instanceof Scope) { + ((Scope) otScope).close(); + } + } + + @Override + public int getOrder() { + return PluginOrderConstant.ClientPluginOrder.TRACE_CLIENT_PLUGIN_ORDER; + } +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceClientPreEnhancedPlugin.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceClientPreEnhancedPlugin.java new file mode 100644 index 0000000000..c408c8612d --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceClientPreEnhancedPlugin.java @@ -0,0 +1,79 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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 com.tencent.cloud.plugin.trace; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.tencent.cloud.plugin.trace.attribute.SpanAttributesProvider; +import com.tencent.cloud.polaris.context.PolarisSDKContextManager; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginType; +import com.tencent.cloud.rpc.enhancement.plugin.PluginOrderConstant; +import com.tencent.polaris.api.utils.CollectionUtils; +import com.tencent.polaris.assembly.api.AssemblyAPI; +import com.tencent.polaris.assembly.api.pojo.TraceAttributes; + +public class TraceClientPreEnhancedPlugin implements EnhancedPlugin { + + private final PolarisSDKContextManager polarisSDKContextManager; + + private final List spanAttributesProviderList; + + public TraceClientPreEnhancedPlugin(PolarisSDKContextManager polarisSDKContextManager, List spanAttributesProviderList) { + this.polarisSDKContextManager = polarisSDKContextManager; + this.spanAttributesProviderList = spanAttributesProviderList; + } + + @Override + public EnhancedPluginType getType() { + return EnhancedPluginType.Client.PRE; + } + + @Override + public void run(EnhancedPluginContext context) throws Throwable { + Map attributes = new HashMap<>(); + if (CollectionUtils.isNotEmpty(spanAttributesProviderList)) { + for (SpanAttributesProvider spanAttributesProvider : spanAttributesProviderList) { + Map additionalAttributes = spanAttributesProvider.getClientBaggageAttributes(context); + if (CollectionUtils.isNotEmpty(additionalAttributes)) { + attributes.putAll(additionalAttributes); + } + } + } + + TraceAttributes traceAttributes = new TraceAttributes(); + traceAttributes.setAttributes(attributes); + traceAttributes.setAttributeLocation(TraceAttributes.AttributeLocation.BAGGAGE); + + AssemblyAPI assemblyAPI = polarisSDKContextManager.getAssemblyAPI(); + assemblyAPI.updateTraceAttributes(traceAttributes); + Object otScope = traceAttributes.getOtScope(); + if (otScope != null) { + context.getExtraData().put(SpanAttributesProvider.OT_SCOPE_KEY, otScope); + } + } + + @Override + public int getOrder() { + return PluginOrderConstant.ClientPluginOrder.TRACE_CLIENT_PLUGIN_ORDER; + } +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceServerMetadataEnhancedPlugin.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceServerPreEnhancedPlugin.java similarity index 57% rename from spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceServerMetadataEnhancedPlugin.java rename to spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceServerPreEnhancedPlugin.java index 6525ec8e45..8ae35a57b9 100644 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceServerMetadataEnhancedPlugin.java +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/TraceServerPreEnhancedPlugin.java @@ -19,10 +19,10 @@ package com.tencent.cloud.plugin.trace; import java.util.HashMap; +import java.util.List; import java.util.Map; -import com.tencent.cloud.common.metadata.MetadataContext; -import com.tencent.cloud.common.metadata.MetadataContextHolder; +import com.tencent.cloud.plugin.trace.attribute.SpanAttributesProvider; import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPlugin; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; @@ -32,15 +32,15 @@ import com.tencent.polaris.assembly.api.AssemblyAPI; import com.tencent.polaris.assembly.api.pojo.TraceAttributes; -public class TraceServerMetadataEnhancedPlugin implements EnhancedPlugin { +public class TraceServerPreEnhancedPlugin implements EnhancedPlugin { private final PolarisSDKContextManager polarisSDKContextManager; - private final SpanAttributesProvider spanAttributesProvider; + private final List spanAttributesProviderList; - public TraceServerMetadataEnhancedPlugin(PolarisSDKContextManager polarisSDKContextManager, SpanAttributesProvider spanAttributesProvider) { + public TraceServerPreEnhancedPlugin(PolarisSDKContextManager polarisSDKContextManager, List spanAttributesProviderList) { this.polarisSDKContextManager = polarisSDKContextManager; - this.spanAttributesProvider = spanAttributesProvider; + this.spanAttributesProviderList = spanAttributesProviderList; } @Override @@ -50,35 +50,26 @@ public EnhancedPluginType getType() { @Override public void run(EnhancedPluginContext context) throws Throwable { - AssemblyAPI assemblyAPI = polarisSDKContextManager.getAssemblyAPI(); Map attributes = new HashMap<>(); - if (null != spanAttributesProvider) { - Map additionalAttributes = spanAttributesProvider.getConsumerSpanAttributes(context); - if (CollectionUtils.isNotEmpty(additionalAttributes)) { - attributes.putAll(additionalAttributes); - } - } - MetadataContext metadataContext = MetadataContextHolder.get(); - Map transitiveCustomAttributes = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); - if (CollectionUtils.isNotEmpty(transitiveCustomAttributes)) { - for (Map.Entry entry : transitiveCustomAttributes.entrySet()) { - attributes.put("custom." + entry.getKey(), entry.getValue()); - } - } - Map disposableCustomAttributes = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_DISPOSABLE); - if (CollectionUtils.isNotEmpty(disposableCustomAttributes)) { - for (Map.Entry entry : disposableCustomAttributes.entrySet()) { - attributes.put("custom." + entry.getKey(), entry.getValue()); + if (CollectionUtils.isNotEmpty(spanAttributesProviderList)) { + for (SpanAttributesProvider spanAttributesProvider : spanAttributesProviderList) { + Map additionalAttributes = spanAttributesProvider.getServerSpanAttributes(context); + if (CollectionUtils.isNotEmpty(additionalAttributes)) { + attributes.putAll(additionalAttributes); + } } } + TraceAttributes traceAttributes = new TraceAttributes(); traceAttributes.setAttributes(attributes); traceAttributes.setAttributeLocation(TraceAttributes.AttributeLocation.SPAN); + + AssemblyAPI assemblyAPI = polarisSDKContextManager.getAssemblyAPI(); assemblyAPI.updateTraceAttributes(traceAttributes); } @Override public int getOrder() { - return PluginOrderConstant.ServerPluginOrder.PROVIDER_TRACE_METADATA_PLUGIN_ORDER; + return PluginOrderConstant.ServerPluginOrder.TRACE_SERVER_PRE_PLUGIN_ORDER; } } diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/attribute/PolarisSpanAttributesProvider.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/attribute/PolarisSpanAttributesProvider.java new file mode 100644 index 0000000000..b855d43f36 --- /dev/null +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/attribute/PolarisSpanAttributesProvider.java @@ -0,0 +1,99 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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 com.tencent.cloud.plugin.trace.attribute; + +import java.util.HashMap; +import java.util.Map; + +import com.tencent.cloud.common.metadata.MetadataContext; +import com.tencent.cloud.common.metadata.MetadataContextHolder; +import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; +import com.tencent.polaris.api.utils.CollectionUtils; +import com.tencent.polaris.api.utils.StringUtils; +import com.tencent.polaris.metadata.core.MessageMetadataContainer; +import com.tencent.polaris.metadata.core.MetadataType; +import com.tencent.polaris.metadata.core.constant.MetadataConstants; +import com.tencent.polaris.metadata.core.manager.CalleeMetadataContainerGroup; + +import static com.tencent.cloud.common.util.OtUtils.OTEL_LANE_ID_KEY; +import static com.tencent.polaris.plugins.router.lane.LaneRouter.TRAFFIC_STAIN_LABEL; + +/** + * Implementation of {@link SpanAttributesProvider} for polaris. + * + * @author Haotian Zhang + */ +public class PolarisSpanAttributesProvider implements SpanAttributesProvider { + @Override + public Map getServerSpanAttributes(EnhancedPluginContext context) { + Map attributes = new HashMap<>(); + MetadataContext metadataContext = MetadataContextHolder.get(); + Map transitiveCustomAttributes = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); + if (CollectionUtils.isNotEmpty(transitiveCustomAttributes)) { + for (Map.Entry entry : transitiveCustomAttributes.entrySet()) { + attributes.put("custom." + entry.getKey(), entry.getValue()); + } + } + Map disposableCustomAttributes = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_DISPOSABLE); + if (CollectionUtils.isNotEmpty(disposableCustomAttributes)) { + for (Map.Entry entry : disposableCustomAttributes.entrySet()) { + attributes.put("custom." + entry.getKey(), entry.getValue()); + } + } + Map upstreamDisposableCustomAttributes = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_UPSTREAM_DISPOSABLE); + if (CollectionUtils.isNotEmpty(upstreamDisposableCustomAttributes)) { + for (Map.Entry entry : upstreamDisposableCustomAttributes.entrySet()) { + attributes.put("custom." + entry.getKey(), entry.getValue()); + } + } + attributes.put("http.port", CalleeMetadataContainerGroup.getStaticApplicationMetadataContainer() + .getRawMetadataStringValue(MetadataConstants.LOCAL_PORT)); + return attributes; + } + + @Override + public Map getClientBaggageAttributes(EnhancedPluginContext context) { + Map attributes = new HashMap<>(); + MetadataContext metadataContext = MetadataContextHolder.get(); + Map transitiveCustomAttributes = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_TRANSITIVE); + if (CollectionUtils.isNotEmpty(transitiveCustomAttributes)) { + for (Map.Entry entry : transitiveCustomAttributes.entrySet()) { + attributes.put("custom." + entry.getKey(), entry.getValue()); + } + } + Map disposableCustomAttributes = metadataContext.getFragmentContext(MetadataContext.FRAGMENT_DISPOSABLE); + if (CollectionUtils.isNotEmpty(disposableCustomAttributes)) { + for (Map.Entry entry : disposableCustomAttributes.entrySet()) { + attributes.put("custom." + entry.getKey(), entry.getValue()); + } + } + attributes.put("http.port", CalleeMetadataContainerGroup.getStaticApplicationMetadataContainer() + .getRawMetadataStringValue(MetadataConstants.LOCAL_PORT)); + attributes.put("net.peer.service", context.getTargetServiceInstance().getServiceId()); + + String serviceLane = metadataContext.getMetadataContainer(MetadataType.MESSAGE, false) + .getRawMetadataMapValue(MessageMetadataContainer.LABEL_MAP_KEY_HEADER, TRAFFIC_STAIN_LABEL); + if (StringUtils.isNotBlank(serviceLane)) { + String[] splits = StringUtils.split(serviceLane, "/"); + if (splits.length >= 2) { + attributes.put(OTEL_LANE_ID_KEY, splits[1]); + } + } + return attributes; + } +} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/SpanAttributesProvider.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/attribute/SpanAttributesProvider.java similarity index 67% rename from spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/SpanAttributesProvider.java rename to spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/attribute/SpanAttributesProvider.java index ed7b2d4590..1dff46ea42 100644 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/SpanAttributesProvider.java +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/attribute/SpanAttributesProvider.java @@ -13,16 +13,27 @@ * 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 com.tencent.cloud.plugin.trace; +package com.tencent.cloud.plugin.trace.attribute; +import java.util.HashMap; import java.util.Map; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; public interface SpanAttributesProvider { - Map getConsumerSpanAttributes(EnhancedPluginContext context); + /** + * Key of OT scope object to save in EnhancedPluginContext. + */ + String OT_SCOPE_KEY = "OT_SCOPE_KEY"; + + default Map getServerSpanAttributes(EnhancedPluginContext context) { + return new HashMap<>(); + } + + default Map getClientBaggageAttributes(EnhancedPluginContext context) { + return new HashMap<>(); + } } diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/tsf/TsfSpanAttributesProvider.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/attribute/tsf/TsfSpanAttributesProvider.java similarity index 91% rename from spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/tsf/TsfSpanAttributesProvider.java rename to spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/attribute/tsf/TsfSpanAttributesProvider.java index 311fbc65a8..562ce2382a 100644 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/tsf/TsfSpanAttributesProvider.java +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/attribute/tsf/TsfSpanAttributesProvider.java @@ -13,15 +13,14 @@ * 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 com.tencent.cloud.plugin.trace.tsf; +package com.tencent.cloud.plugin.trace.attribute.tsf; import java.util.HashMap; import java.util.Map; -import com.tencent.cloud.plugin.trace.SpanAttributesProvider; +import com.tencent.cloud.plugin.trace.attribute.SpanAttributesProvider; import com.tencent.cloud.rpc.enhancement.plugin.EnhancedPluginContext; import com.tencent.polaris.api.utils.CollectionUtils; import com.tencent.polaris.api.utils.StringUtils; @@ -32,7 +31,7 @@ public class TsfSpanAttributesProvider implements SpanAttributesProvider { @Override - public Map getConsumerSpanAttributes(EnhancedPluginContext context) { + public Map getClientBaggageAttributes(EnhancedPluginContext context) { Map attributes = new HashMap<>(); if (null != context.getRequest().getUrl()) { attributes.put("remoteInterface", context.getRequest().getUrl().getPath()); @@ -54,5 +53,4 @@ public Map getConsumerSpanAttributes(EnhancedPluginContext conte } return attributes; } - } diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/config/TraceEnhancedPluginAutoConfiguration.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/config/TraceEnhancedPluginAutoConfiguration.java index 9eb8970a42..25ad251290 100644 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/config/TraceEnhancedPluginAutoConfiguration.java +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/config/TraceEnhancedPluginAutoConfiguration.java @@ -18,12 +18,19 @@ package com.tencent.cloud.plugin.trace.config; -import com.tencent.cloud.plugin.trace.SpanAttributesProvider; -import com.tencent.cloud.plugin.trace.TraceServerMetadataEnhancedPlugin; +import java.util.List; + +import com.tencent.cloud.plugin.trace.TraceClientFinallyEnhancedPlugin; +import com.tencent.cloud.plugin.trace.TraceClientPreEnhancedPlugin; +import com.tencent.cloud.plugin.trace.TraceServerPreEnhancedPlugin; +import com.tencent.cloud.plugin.trace.attribute.PolarisSpanAttributesProvider; +import com.tencent.cloud.plugin.trace.attribute.SpanAttributesProvider; +import com.tencent.cloud.plugin.trace.attribute.tsf.TsfSpanAttributesProvider; import com.tencent.cloud.polaris.context.ConditionalOnPolarisEnabled; import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -35,9 +42,31 @@ public class TraceEnhancedPluginAutoConfiguration { @Bean - public TraceServerMetadataEnhancedPlugin traceServerMetadataEnhancedPlugin( - PolarisSDKContextManager polarisSDKContextManager, @Autowired(required = false) SpanAttributesProvider spanAttributesProvider) { - return new TraceServerMetadataEnhancedPlugin(polarisSDKContextManager, spanAttributesProvider); + public TraceServerPreEnhancedPlugin traceServerPreEnhancedPlugin( + PolarisSDKContextManager polarisSDKContextManager, @Autowired(required = false) List spanAttributesProviderList) { + return new TraceServerPreEnhancedPlugin(polarisSDKContextManager, spanAttributesProviderList); + } + + @Bean + public TraceClientPreEnhancedPlugin traceClientPreEnhancedPlugin( + PolarisSDKContextManager polarisSDKContextManager, @Autowired(required = false) List spanAttributesProviderList) { + return new TraceClientPreEnhancedPlugin(polarisSDKContextManager, spanAttributesProviderList); + } + + @Bean + public TraceClientFinallyEnhancedPlugin traceClientFinallyEnhancedPlugin() { + return new TraceClientFinallyEnhancedPlugin(); + } + + @Bean + @ConditionalOnMissingBean + public PolarisSpanAttributesProvider polarisSpanAttributesProvider() { + return new PolarisSpanAttributesProvider(); } + @Bean + @ConditionalOnMissingBean + public TsfSpanAttributesProvider tsfClientSpanAttributesProvider() { + return new TsfSpanAttributesProvider(); + } } diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/tsf/TsfTracePropertiesAutoConfiguration.java b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/tsf/TsfTracePropertiesAutoConfiguration.java deleted file mode 100644 index 6bfed4541e..0000000000 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/java/com/tencent/cloud/plugin/trace/tsf/TsfTracePropertiesAutoConfiguration.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * 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 com.tencent.cloud.plugin.trace.tsf; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -@Configuration(proxyBeanMethods = false) -@ConditionalOnProperty(value = "spring.cloud.polaris.trace.enabled", matchIfMissing = true) -public class TsfTracePropertiesAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public TsfSpanAttributesProvider tsfClientSpanAttributesProvider() { - return new TsfSpanAttributesProvider(); - } - -} diff --git a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/resources/META-INF/spring.factories b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/resources/META-INF/spring.factories index eb958b7e9d..6042016a67 100644 --- a/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-tencent-plugin-starters/spring-cloud-starter-tencent-trace-plugin/src/main/resources/META-INF/spring.factories @@ -1,6 +1,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.tencent.cloud.plugin.trace.config.TraceConfigModifierAutoConfiguration,\ - com.tencent.cloud.plugin.trace.config.TraceEnhancedPluginAutoConfiguration,\ - com.tencent.cloud.plugin.trace.tsf.TsfTracePropertiesAutoConfiguration + com.tencent.cloud.plugin.trace.config.TraceEnhancedPluginAutoConfiguration org.springframework.cloud.bootstrap.BootstrapConfiguration=\ - com.tencent.cloud.plugin.trace.config.TraceConfigModifierBootstrapAutoConfiguration \ No newline at end of file + com.tencent.cloud.plugin.trace.config.TraceConfigModifierBootstrapAutoConfiguration diff --git a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfCoreEnvironmentPostProcessor.java b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfCoreEnvironmentPostProcessor.java index 558a9e31ea..ea382c21e5 100644 --- a/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfCoreEnvironmentPostProcessor.java +++ b/spring-cloud-tencent-polaris-context/src/main/java/com/tencent/cloud/polaris/context/config/extend/tsf/TsfCoreEnvironmentPostProcessor.java @@ -58,6 +58,12 @@ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringAp if (StringUtils.isNotBlank(tsfAppId)) { Map defaultProperties = new HashMap<>(); + // enabled + String polarisEnabled = environment.getProperty("spring.cloud.polaris.enabled"); + if (StringUtils.isBlank(polarisEnabled)) { + defaultProperties.put("spring.cloud.polaris.enabled", true); + } + // lossless String polarisAdminPort = environment.getProperty("polaris_admin_port"); if (StringUtils.isNotBlank(polarisAdminPort)) { diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisServerIntrospector.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisServerIntrospector.java new file mode 100644 index 0000000000..c4e8820f2e --- /dev/null +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/PolarisServerIntrospector.java @@ -0,0 +1,50 @@ +/* + * Tencent is pleased to support the open source community by making Spring Cloud Tencent available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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 com.tencent.cloud.polaris.loadbalancer; + +import java.util.Map; + +import com.netflix.loadbalancer.Server; +import com.tencent.cloud.common.pojo.PolarisServer; +import com.tencent.polaris.api.utils.StringUtils; + +import org.springframework.cloud.netflix.ribbon.DefaultServerIntrospector; + +/** + * Introspector for polaris server. + * + * @author Haotian Zhang + */ +public class PolarisServerIntrospector extends DefaultServerIntrospector { + + @Override + public Map getMetadata(Server server) { + if (server instanceof PolarisServer) { + return ((PolarisServer) server).getMetadata(); + } + return super.getMetadata(server); + } + + @Override + public boolean isSecure(Server server) { + if (server instanceof PolarisServer) { + return StringUtils.equalsIgnoreCase(server.getScheme(), "https"); + } + return super.isSecure(server); + } +} diff --git a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfiguration.java b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfiguration.java index bb8f021d2b..220519dc48 100644 --- a/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfiguration.java +++ b/spring-cloud-tencent-polaris-loadbalancer/src/main/java/com/tencent/cloud/polaris/loadbalancer/config/PolarisRibbonClientConfiguration.java @@ -29,6 +29,7 @@ import com.tencent.cloud.polaris.context.PolarisSDKContextManager; import com.tencent.cloud.polaris.loadbalancer.PolarisLoadBalancer; import com.tencent.cloud.polaris.loadbalancer.PolarisRingHashRule; +import com.tencent.cloud.polaris.loadbalancer.PolarisServerIntrospector; import com.tencent.cloud.polaris.loadbalancer.PolarisWeightedRandomRule; import com.tencent.cloud.polaris.loadbalancer.PolarisWeightedRoundRobinRule; import com.tencent.cloud.polaris.loadbalancer.transformer.InstanceTransformer; @@ -54,6 +55,11 @@ public ILoadBalancer polarisLoadBalancer(IClientConfig iClientConfig, IRule iRul polarisSDKContextManager.getConsumerAPI(), polarisLoadBalancerProperties, instanceTransformer); } + @Bean + public PolarisServerIntrospector polarisServerIntrospector() { + return new PolarisServerIntrospector(); + } + @Bean @ConditionalOnMissingBean @ConditionalOnProperty(value = "spring.cloud.polaris.loadbalancer.strategy", havingValue = "roundRobin") diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java index e9ef0cc67b..2711b60754 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/EnhancedPluginContext.java @@ -19,7 +19,9 @@ import java.net.URI; +import java.util.Map; import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,19 +37,13 @@ public class EnhancedPluginContext { private static final Logger LOGGER = LoggerFactory.getLogger(EnhancedPluginContext.class); - + private final Map extraData = new ConcurrentHashMap<>(); private Object originRequest; - private EnhancedRequestContext request; - private EnhancedResponseContext response; - private Throwable throwable; - private long delay; - private ServiceInstance localServiceInstance; - /** * targetServiceInstance only exist in a client runner type. */ @@ -126,6 +122,10 @@ else if (Objects.nonNull(url)) { } } + public Map getExtraData() { + return extraData; + } + @Override public String toString() { return "EnhancedPluginContext{" + diff --git a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java index f839e1dc57..5c13dfa733 100644 --- a/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java +++ b/spring-cloud-tencent-rpc-enhancement/src/main/java/com/tencent/cloud/rpc/enhancement/plugin/PluginOrderConstant.java @@ -65,15 +65,23 @@ public static class ClientPluginOrder { * {@link com.tencent.cloud.plugin.trace.TraceClientMetadataEnhancedPlugin}. */ public static final int CONSUMER_TRACE_METADATA_PLUGIN_ORDER = CONSUMER_TRANSFER_METADATA_PLUGIN_ORDER - 1; + + /** + * order for + * {@link com.tencent.cloud.plugin.trace.TraceClientPreEnhancedPlugin} + * and + * {@link com.tencent.cloud.plugin.trace.TraceClientFinallyEnhancedPlugin}. + */ + public static final int TRACE_CLIENT_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 3; } public static class ServerPluginOrder { /** * order for - * {@link com.tencent.cloud.plugin.trace.TraceServerMetadataEnhancedPlugin}. + * {@link com.tencent.cloud.plugin.trace.TraceServerPreEnhancedPlugin}. */ - public static final int PROVIDER_TRACE_METADATA_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 1; + public static final int TRACE_SERVER_PRE_PLUGIN_ORDER = Ordered.HIGHEST_PRECEDENCE + 1; } }