diff --git a/trpc-core/src/main/java/com/tencent/trpc/core/common/Constants.java b/trpc-core/src/main/java/com/tencent/trpc/core/common/Constants.java index 632f88a330..c034bb302d 100644 --- a/trpc-core/src/main/java/com/tencent/trpc/core/common/Constants.java +++ b/trpc-core/src/main/java/com/tencent/trpc/core/common/Constants.java @@ -195,6 +195,11 @@ public class Constants { */ public static final String CONTAINER_NAME = "container_name"; + /** + * Enable trpcmdcadapter + */ + public static final String ENABLE_TRPCMDCADAPTER = "enable_trpcmdcadapter"; + /** * Environment name registered to Polaris */ diff --git a/trpc-core/src/main/java/com/tencent/trpc/core/utils/ConfigUtils.java b/trpc-core/src/main/java/com/tencent/trpc/core/utils/ConfigUtils.java new file mode 100644 index 0000000000..e59bebc32e --- /dev/null +++ b/trpc-core/src/main/java/com/tencent/trpc/core/utils/ConfigUtils.java @@ -0,0 +1,56 @@ +package com.tencent.trpc.core.utils; + +import com.tencent.trpc.core.common.TRpcSystemProperties; +import com.tencent.trpc.core.common.config.GlobalConfig; +import com.tencent.trpc.core.common.config.constant.ConfigConstants; +import com.tencent.trpc.core.logger.Logger; +import com.tencent.trpc.core.logger.LoggerFactory; +import org.apache.commons.collections4.MapUtils; +import org.apache.commons.lang3.ObjectUtils; + +import java.io.FileInputStream; +import java.util.Map; + + +/** + * @author jiaxxzhang + * @project trpc-java + * @description 静态加载配置工具类 + * @date 2024/4/3 14:20:14 + */ +public class ConfigUtils { + + private static final Logger logger = LoggerFactory.getLogger(ConfigUtils.class); + + public static final String DEFAULT_YAML_CONFIG_FILE_NAME = "trpc_java.yaml"; + + /** + * 静态加载全局配置 + * + * @return + */ + public static GlobalConfig loadGlobalConfig() { + String confPath = TRpcSystemProperties.getProperties(TRpcSystemProperties.CONFIG_PATH); + Map config = null; + try { + if (StringUtils.isEmpty(confPath)) { + logger.warn("warning!!, not set properties [" + TRpcSystemProperties.CONFIG_PATH + + "], we will use classpath:" + DEFAULT_YAML_CONFIG_FILE_NAME + ""); + if (ObjectUtils.isNotEmpty(YamlParser.class.getClassLoader().getResourceAsStream(DEFAULT_YAML_CONFIG_FILE_NAME))){ + config = (Map) YamlParser.parseAsFromClassPath(DEFAULT_YAML_CONFIG_FILE_NAME, Map.class).get(ConfigConstants.GLOBAL); + } + } else { + config = (Map) YamlParser.parseAs(new FileInputStream(confPath), Map.class).get(ConfigConstants.GLOBAL); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + GlobalConfig globalConfig = new GlobalConfig(); + if(MapUtils.isNotEmpty(config)){ + BinderUtils.bind(globalConfig, config); + BinderUtils.bind(BinderUtils.UNDERSCORES_TO_UPPERCASE, globalConfig, config, + ConfigConstants.ENABLE_SET, o -> "Y".equalsIgnoreCase(String.valueOf(o))); + } + return globalConfig; + } +} diff --git a/trpc-core/src/main/java/org/slf4j/TrpcMDCAdapter.java b/trpc-core/src/main/java/org/slf4j/TrpcMDCAdapter.java index a93137b7ef..fd0ecb7ab2 100644 --- a/trpc-core/src/main/java/org/slf4j/TrpcMDCAdapter.java +++ b/trpc-core/src/main/java/org/slf4j/TrpcMDCAdapter.java @@ -12,13 +12,20 @@ package org.slf4j; import com.alibaba.ttl.TransmittableThreadLocal; +import com.tencent.trpc.core.common.config.GlobalConfig; +import com.tencent.trpc.core.logger.Logger; +import com.tencent.trpc.core.logger.LoggerFactory; +import com.tencent.trpc.core.utils.ConfigUtils; import com.tencent.trpc.core.utils.StringUtils; +import org.slf4j.spi.MDCAdapter; + import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; -import org.slf4j.spi.MDCAdapter; + +import static com.tencent.trpc.core.common.Constants.ENABLE_TRPCMDCADAPTER; /** * TrpcMDCAdapter @@ -32,11 +39,13 @@ */ public class TrpcMDCAdapter implements MDCAdapter { + private static final Logger logger = LoggerFactory.getLogger(TrpcMDCAdapter.class); + private static final int WRITE_OPERATION = 1; private static final int READ_OPERATION = 2; - private static final TrpcMDCAdapter mtcMDCAdapter; + private static final TrpcMDCAdapter mtcMDCAdapter = new TrpcMDCAdapter(); private final ThreadLocal> copyOnInheritThreadLocal = new TransmittableThreadLocal<>(); @@ -46,8 +55,12 @@ public class TrpcMDCAdapter implements MDCAdapter { private final ThreadLocal lastOperation = new ThreadLocal<>(); static { - mtcMDCAdapter = new TrpcMDCAdapter(); - MDC.mdcAdapter = mtcMDCAdapter; + GlobalConfig globalConfig = ConfigUtils.loadGlobalConfig(); + if (Boolean.parseBoolean(globalConfig.getExt() + .getOrDefault(ENABLE_TRPCMDCADAPTER, Boolean.TRUE).toString())) { + MDC.mdcAdapter = mtcMDCAdapter; + logger.info("enable TrpcMDCAdapter"); + } } public static MDCAdapter init() { diff --git a/trpc-core/src/test/resources/trpc_java.yaml b/trpc-core/src/test/resources/trpc_java.yaml new file mode 100644 index 0000000000..95ef90a115 --- /dev/null +++ b/trpc-core/src/test/resources/trpc_java.yaml @@ -0,0 +1,8 @@ +global: #全局配置 + namespace: test_namespace #环境类型,分正式环境和非正式环境两种类型 + env_name: test_env_name #环境名称,非正式环境下多环境的名称 + container_name: test_container_name #节点容器名 + enable_set: Y + full_set_name: a.b.c #set分组信息 + ext: + enable_trpcmdcadapter: true #是否启用trpcmdcadapter \ No newline at end of file diff --git a/trpc-test/trpc-test-integration/src/integration-test/java/com/tencent/trpc/integration/test/transport/slf4j/TrpcMDCAdapterTest.java b/trpc-test/trpc-test-integration/src/integration-test/java/com/tencent/trpc/integration/test/transport/slf4j/TrpcMDCAdapterTest.java new file mode 100644 index 0000000000..45d10b2ce5 --- /dev/null +++ b/trpc-test/trpc-test-integration/src/integration-test/java/com/tencent/trpc/integration/test/transport/slf4j/TrpcMDCAdapterTest.java @@ -0,0 +1,60 @@ +/* + * Tencent is pleased to support the open source community by making tRPC available. + * + * Copyright (C) 2023 THL A29 Limited, a Tencent company. + * All rights reserved. + * + * If you have downloaded a copy of the tRPC source code from Tencent, + * please note that tRPC source code is licensed under the Apache 2.0 License, + * A copy of the Apache 2.0 License can be found in the LICENSE file. + */ + +package com.tencent.trpc.integration.test.transport.slf4j; + +import com.tencent.trpc.core.rpc.RpcClientContext; +import com.tencent.trpc.integration.test.TrpcServerApplication; +import com.tencent.trpc.integration.test.stub.EchoAPI; +import com.tencent.trpc.integration.test.stub.EchoService; +import com.tencent.trpc.spring.annotation.TRpcClient; +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.slf4j.TrpcMDCAdapter; +import org.slf4j.spi.MDCAdapter; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import java.util.HashMap; +import java.util.Map; + +import static org.junit.Assert.assertEquals; + +@RunWith(SpringRunner.class) +@SpringBootTest(classes = TrpcServerApplication.class) +@ActiveProfiles("transport") +public class TrpcMDCAdapterTest { + + @TRpcClient(id = "http-client-7072") + private EchoAPI http7072EchoAPI; + + @TRpcClient(id = "http-client-7073") + private EchoAPI http7073EchoAPI; + + /** + * Test for testTrpcMDCAdapter + */ + @Test + public void testTrpcMDCAdapter() { + + String message = "http-hello"; + EchoService.EchoResponse response = http7072EchoAPI.echo(new RpcClientContext(), EchoService.EchoRequest.newBuilder() + .setMessage(message) + .build()); + assertEquals(message, response.getMessage()); + response = http7073EchoAPI.echo(new RpcClientContext(), EchoService.EchoRequest.newBuilder() + .setMessage(message) + .build()); + assertEquals(message, response.getMessage()); + } +} diff --git a/trpc-test/trpc-test-integration/src/integration-test/resources/application-transport.yml b/trpc-test/trpc-test-integration/src/integration-test/resources/application-transport.yml index 04d63a6766..840be9c5a7 100644 --- a/trpc-test/trpc-test-integration/src/integration-test/resources/application-transport.yml +++ b/trpc-test/trpc-test-integration/src/integration-test/resources/application-transport.yml @@ -3,6 +3,15 @@ spring: web-application-type: none trpc: + global: #全局配置 + namespace: test_namespace #环境类型,分正式环境和非正式环境两种类型 + env_name: test_env_name #环境名称,非正式环境下多环境的名称 + container_name: test_container_name #节点容器名 + enable_set: Y + full_set_name: a.b.c #set分组信息 + ext: + enable_trpcmdcadapter: true #是否启用trpcmdcadapter + server: app: integration-test server: integration-test-server