SCT新增动态修改日志的能力

pull/1095/head
yangjuanying 2 years ago
parent 6a53cfdd7d
commit 668fc24fdd

@ -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

@ -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:

@ -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]

@ -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;
}
}

@ -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<ApplicationEvent> {
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);
}
}
}

@ -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);
}
}
}
}

@ -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);
}
}
Loading…
Cancel
Save