From 668fc24fdd9697a26b8e2a76e9d29fd62a5f04e8 Mon Sep 17 00:00:00 2001 From: yangjuanying <531948963@qq.com> Date: Thu, 27 Jul 2023 20:24:32 +0800 Subject: [PATCH] =?UTF-8?q?SCT=E6=96=B0=E5=A2=9E=E5=8A=A8=E6=80=81?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=97=A5=E5=BF=97=E7=9A=84=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PolarisConfigAutoConfiguration.java | 27 +++-- .../PolarisConfigPropertyAutoRefresher.java | 21 +++- ...arisConfigRefreshOptimizationListener.java | 32 ++++-- .../cloud/polaris/config/logger/Level.java | 29 ++++++ ...olarisConfigLoggerApplicationListener.java | 35 +++++++ .../logger/PolarisConfigLoggerContext.java | 98 +++++++++++++++++++ .../cloud/polaris/config/logger/StdLog.java | 79 +++++++++++++++ 7 files changed, 297 insertions(+), 24 deletions(-) create mode 100644 spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/Level.java create mode 100644 spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerApplicationListener.java create mode 100644 spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerContext.java create mode 100644 spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/StdLog.java diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java index be91d2287..0c0c68200 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/PolarisConfigAutoConfiguration.java @@ -18,6 +18,16 @@ package com.tencent.cloud.polaris.config; +import org.springframework.boot.autoconfigure.AutoConfigureBefore; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.SearchStrategy; +import org.springframework.cloud.context.properties.ConfigurationPropertiesBeans; +import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; +import org.springframework.cloud.context.refresh.ContextRefresher; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + import com.tencent.cloud.polaris.config.adapter.AffectedConfigurationPropertiesRebinder; import com.tencent.cloud.polaris.config.adapter.PolarisConfigPropertyRefresher; import com.tencent.cloud.polaris.config.adapter.PolarisConfigRefreshScopeAnnotationDetector; @@ -29,20 +39,11 @@ import com.tencent.cloud.polaris.config.condition.ConditionalOnReflectRefreshTyp import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; import com.tencent.cloud.polaris.config.listener.PolarisConfigChangeEventListener; import com.tencent.cloud.polaris.config.listener.PolarisConfigRefreshOptimizationListener; +import com.tencent.cloud.polaris.config.logger.PolarisConfigLoggerApplicationListener; import com.tencent.cloud.polaris.config.spring.annotation.SpringValueProcessor; import com.tencent.cloud.polaris.config.spring.property.PlaceholderHelper; import com.tencent.cloud.polaris.config.spring.property.SpringValueRegistry; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.SearchStrategy; -import org.springframework.cloud.context.properties.ConfigurationPropertiesBeans; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; -import org.springframework.cloud.context.refresh.ContextRefresher; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; - /** * polaris config module auto configuration at init application context phase. * @@ -61,6 +62,12 @@ public class PolarisConfigAutoConfiguration { public PolarisConfigChangeEventListener polarisConfigChangeEventListener() { return new PolarisConfigChangeEventListener(); } + + @Bean + public PolarisConfigLoggerApplicationListener polarisConfigLoggerApplicationListener() { + return new PolarisConfigLoggerApplicationListener(); + } + @Bean @Primary diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java index 7dead1773..e1e3aae71 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/adapter/PolarisConfigPropertyAutoRefresher.java @@ -22,17 +22,18 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; -import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeListener; -import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.ApplicationListener; import org.springframework.lang.NonNull; import org.springframework.util.CollectionUtils; +import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; +import com.tencent.cloud.polaris.config.logger.PolarisConfigLoggerContext; +import com.tencent.polaris.configuration.api.core.ConfigKVFileChangeListener; +import com.tencent.polaris.configuration.api.core.ConfigPropertyChangeInfo; + /** * 1. Listen to the Polaris server configuration publishing event 2. Write the changed * configuration content to propertySource 3. Refresh the context through contextRefresher @@ -96,6 +97,18 @@ public abstract class PolarisConfigPropertyAutoRefresher LOGGER.info("[SCT Config] changed property = {}", configPropertyChangeInfo); + // 新增动态改变日志级别的能力 + try { + if(changedKey.startsWith("logging.level") && changedKey.length() >= 14) { + String loggerName = changedKey.substring(14); + String newValue = configPropertyChangeInfo.getNewValue(); + LOGGER.info("[SCT Config] set logging.level loggerName:{}, newValue:{}", loggerName, newValue); + PolarisConfigLoggerContext.setLevel(loggerName, newValue); + } + } catch(Exception e) { + LOGGER.error("[SCT Config] set logging.level exception,", e); + } + switch (configPropertyChangeInfo.getChangeType()) { case MODIFIED: case ADDED: diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListener.java index 0c93fd8ff..bc2119adc 100644 --- a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListener.java +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/listener/PolarisConfigRefreshOptimizationListener.java @@ -18,16 +18,12 @@ package com.tencent.cloud.polaris.config.listener; +import static com.tencent.cloud.polaris.config.condition.ReflectRefreshTypeCondition.POLARIS_CONFIG_REFRESH_TYPE; + import java.util.Collections; -import com.tencent.cloud.polaris.config.adapter.PolarisConfigRefreshScopeAnnotationDetector; -import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; -import com.tencent.cloud.polaris.config.adapter.PolarisRefreshEntireContextRefresher; -import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; -import com.tencent.cloud.polaris.config.enums.RefreshType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - import org.springframework.beans.factory.config.ConstructorArgumentValues; import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; @@ -40,7 +36,11 @@ import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.MutablePropertySources; import org.springframework.lang.NonNull; -import static com.tencent.cloud.polaris.config.condition.ReflectRefreshTypeCondition.POLARIS_CONFIG_REFRESH_TYPE; +import com.tencent.cloud.polaris.config.adapter.PolarisConfigRefreshScopeAnnotationDetector; +import com.tencent.cloud.polaris.config.adapter.PolarisPropertySourceManager; +import com.tencent.cloud.polaris.config.adapter.PolarisRefreshEntireContextRefresher; +import com.tencent.cloud.polaris.config.config.PolarisConfigProperties; +import com.tencent.cloud.polaris.config.enums.RefreshType; /** * When {@link com.tencent.cloud.polaris.config.adapter.PolarisConfigRefreshScopeAnnotationDetector} detects that @@ -72,10 +72,22 @@ public class PolarisConfigRefreshOptimizationListener implements ApplicationList .getBean(PolarisConfigRefreshScopeAnnotationDetector.class); boolean isRefreshScopeAnnotationUsed = detector.isRefreshScopeAnnotationUsed(); String annotatedRefreshScopeBeanName = detector.getAnnotatedRefreshScopeBeanName(); + + // using System.setProperty to set spring.cloud.polaris.config.refresh-type + String value = System.getProperty("spring.cloud.polaris.config.refresh-type"); + boolean isSystemSetRefreshType = RefreshType.REFRESH_CONTEXT.toString().equalsIgnoreCase(value); + // a bean is using @RefreshScope, but the config refresh type is still [reflect], switch automatically - if (isRefreshScopeAnnotationUsed) { - LOGGER.warn("Detected that the bean [{}] is using @RefreshScope annotation, but the config refresh type is still [reflect]. " - + "[SCT] will automatically switch to [refresh_context].", annotatedRefreshScopeBeanName); + if (isRefreshScopeAnnotationUsed || isSystemSetRefreshType) { + if(isRefreshScopeAnnotationUsed) { + LOGGER.warn("Detected that the bean [{}] is using @RefreshScope annotation, but the config refresh type is still [reflect]. " + + "[SCT] will automatically switch to [refresh_context].", annotatedRefreshScopeBeanName); + } + + if(isSystemSetRefreshType) { + LOGGER.warn("Detected that using System.setProperty to set spring.cloud.polaris.config.refresh-type = refresh_context, but the config refresh type is still [reflect]. " + + "[SCT] will automatically switch to [refresh_context]."); + } switchConfigRefreshTypeProperty(applicationContext); modifyPolarisConfigPropertiesBean(applicationContext); // remove related bean of type [reflect] diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/Level.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/Level.java new file mode 100644 index 000000000..818219a51 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/Level.java @@ -0,0 +1,29 @@ +package com.tencent.cloud.polaris.config.logger; + +/** + * @author juanyinyang + */ +public enum Level { + + TRACE("TRACE"), DEBUG("DEBUG"), INFO("INFO"), WARN("WARN"), ERROR("ERROR"),FATAL("FATAL"),OFF("OFF"); + + private String level; + + Level(String level) { + this.level = level; + } + + public String getLevel() { + return level; + } + + + public static Level levelOf(String level) { + for (Level l : Level.values()) { + if (l.level.equalsIgnoreCase(level)) { + return l; + } + } + return null; + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerApplicationListener.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerApplicationListener.java new file mode 100644 index 000000000..b81adcd79 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerApplicationListener.java @@ -0,0 +1,35 @@ +package com.tencent.cloud.polaris.config.logger; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.context.event.ApplicationStartedEvent; +import org.springframework.boot.logging.LoggingSystem; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; + +/** + * @author juanyinyang + */ +public class PolarisConfigLoggerApplicationListener implements ApplicationListener { + + private static final Logger LOGGER = LoggerFactory.getLogger(PolarisConfigLoggerApplicationListener.class); + + /** + * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent) + */ + @Override + public void onApplicationEvent(ApplicationEvent event) { + try { + // Initialize application loggingSystem. + if (event instanceof ApplicationStartedEvent) { + ApplicationStartedEvent startedEvent = (ApplicationStartedEvent) event; + ClassLoader classLoader = startedEvent.getSpringApplication().getClassLoader(); + LoggingSystem loggingSystem = LoggingSystem.get(classLoader); + LOGGER.info("PolarisConfigLoggerApplicationListener onApplicationEvent init loggingSystem:{}", loggingSystem); + PolarisConfigLoggerContext.setLogSystem(loggingSystem); + } + } catch (Exception e) { + LOGGER.error("PolarisConfigLoggerApplicationListener onApplicationEvent exception:", e); + } + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerContext.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerContext.java new file mode 100644 index 000000000..e1c686713 --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/PolarisConfigLoggerContext.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2018 www.tencent.com. + * All Rights Reserved. + * This program is the confidential and proprietary information of + * www.tencent.com ("Confidential Information"). You shall not disclose such + * Confidential Information and shall use it only in accordance with + * the terms of the license agreement you entered into with www.tencent.com. + */ + +package com.tencent.cloud.polaris.config.logger; + +import static org.springframework.boot.logging.LoggingSystem.ROOT_LOGGER_NAME; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.logging.LogLevel; +import org.springframework.boot.logging.LoggingSystem; +import org.springframework.util.Assert; + + +/** + * @author juanyinyang + */ +public final class PolarisConfigLoggerContext { + + private static LoggingSystem loggingSystem; + + private PolarisConfigLoggerContext() { + + } + + protected static void setLogSystem(LoggingSystem logSystem) { + Assert.notNull(logSystem,"Logging System should not be null"); + PolarisConfigLoggerContext.loggingSystem = logSystem; + } + + public static void setLevel(String loggerName, String level) { + if (loggingSystem == null) { + printLog("[SCT Config] PolarisConfigLoggerContext logger: ["+loggerName+"] change to target level fail. caused by internal exception:" + level,Level.WARN); + return; + } + Level loggerLevel = Level.levelOf(level); + if (loggerLevel == null) { + printLog("[SCT Config] PolarisConfigLoggerContext logger: ["+loggerName+"] change to target level fail. caused by level is not support, level:" + level,Level.WARN); + return; + } + LogLevel logLevel = null; + switch (loggerLevel) { + case TRACE: + logLevel = LogLevel.TRACE; + break; + case DEBUG: + logLevel = LogLevel.DEBUG; + break; + case OFF: + logLevel = LogLevel.OFF; + break; + case INFO: + logLevel = LogLevel.INFO; + break; + case WARN: + logLevel = LogLevel.WARN; + break; + case ERROR: + logLevel = LogLevel.ERROR; + break; + case FATAL: + logLevel = LogLevel.FATAL; + break; + default: + printLog("[SCT Config] PolarisConfigLoggerContext logger: ["+loggerName+"] setLevel fail. caused by level is not support, level: " + level,Level.WARN); + } + loggingSystem.setLogLevel(loggerName,logLevel); + printLog("[SCT Config] PolarisConfigLoggerContext logger: ["+loggerName+"] changed to level:" + level,Level.INFO); + } + + /** + * 打印日志 + * @param message + * @param level + */ + private static void printLog(String message, Level level){ + Logger logger = LoggerFactory.getLogger(ROOT_LOGGER_NAME); + if (level.ordinal() <= Level.INFO.ordinal() ) { + if (logger != null) { + logger.info(message); + } else { + StdLog.info(message); + } + } else { + if (logger != null) { + logger.warn(message); + } else { + StdLog.warn(message); + } + } + } +} diff --git a/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/StdLog.java b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/StdLog.java new file mode 100644 index 000000000..ebaba29ca --- /dev/null +++ b/spring-cloud-starter-tencent-polaris-config/src/main/java/com/tencent/cloud/polaris/config/logger/StdLog.java @@ -0,0 +1,79 @@ +package com.tencent.cloud.polaris.config.logger; + +import java.io.PrintStream; +import java.util.Calendar; + +/** + * internal output logger + * @author juanyinyang + */ +public class StdLog { + + private static final String CLASS_INFO = StdLog.class.getName(); + + + protected static boolean debugEnabled = false; + + /** + * enable info level log + */ + protected static boolean infoEnabled = true; + + /** + * quite mode will out put nothing + */ + protected static boolean quietMode = false; + + + private static final String DEBUG_FIX = "StdLog:DEBUG: "; + + private static final String INFO_FIX = "StdLog:INFO: "; + + private static final String WARN_FIX = "StdLog:WARN: "; + + public static void setQuietMode(boolean quietMode) { + StdLog.quietMode = quietMode; + } + + public static void setInfoEnabled(boolean infoEnabled ){ + StdLog.infoEnabled = infoEnabled; + } + + public static void setDebugEnabled(boolean debugEnabled) { + StdLog.debugEnabled = debugEnabled; + } + + public static void debug(String msg) { + + if (debugEnabled && !quietMode) { + println(System.out,DEBUG_FIX + msg); + } + } + + public static void info(String msg) { + if (infoEnabled && !quietMode) { + println(System.out,INFO_FIX + msg); + } + } + + public static void warn(String msg) { + if (infoEnabled && !quietMode) { + println(System.err,WARN_FIX + msg); + } + } + + public static void warn(String msg, Throwable t) { + if (quietMode) { + return; + } + println(System.err,WARN_FIX + msg); + if (t != null) { + t.printStackTrace(); + } + } + + private static void println(PrintStream out, String msg) { + out.println(Calendar.getInstance().getTime().toString() + " " + CLASS_INFO + " " + msg); + } + +}