From 86c66aab6d80c7843ef4dc6422b4f51fa0124e59 Mon Sep 17 00:00:00 2001 From: Redkale Date: Sun, 11 Dec 2022 10:45:47 +0800 Subject: [PATCH] =?UTF-8?q?=E9=85=8D=E7=BD=AE=E4=B8=AD=E5=BF=83=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=8A=A8=E6=80=81=E6=9B=B4=E6=94=B9=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/org/redkale/boot/Application.java | 72 ++++++++++++++++--- .../org/redkale/boot/LoggingBaseHandler.java | 3 - .../redkale/boot/LoggingSearchHandler.java | 8 ++- .../org/redkale/boot/PropertiesAgent.java | 17 ++--- 4 files changed, 72 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/redkale/boot/Application.java b/src/main/java/org/redkale/boot/Application.java index f0f778c3c..cd5b5452d 100644 --- a/src/main/java/org/redkale/boot/Application.java +++ b/src/main/java/org/redkale/boot/Application.java @@ -128,9 +128,6 @@ public final class Application { private static final int UDP_CAPACITY = 1024; - //仅仅用于传递给LoggingSearchHandler使用 - static Application currentApplication; - //本进程节点ID final int nodeid; @@ -144,6 +141,9 @@ public final class Application { //@since 2.3.0 final ExecutorService workExecutor; + //日志配置资源 + final Properties loggingProperties = new Properties(); + //Source 原始的配置资源, 只会存在redkale.datasource(.|[) redkale.cachesource(.|[)开头的配置项 final Properties sourceProperties = new Properties(); @@ -582,6 +582,7 @@ public final class Application { private void loadResourceProperties() throws IOException { final Properties dyncProps = new Properties(); final AtomicInteger propertyIndex = new AtomicInteger(); + Properties logProps = null; //新的日志配置项 //------------------------------------ 读取本地DataSource、CacheSource配置 ------------------------------------ if ("file".equals(this.confPath.getScheme())) { File sourceFile = new File(new File(confPath), "source.properties"); @@ -689,9 +690,19 @@ public final class Application { if (compileMode) { this.propertiesAgent.compile(propertiesConf); } else { - Properties props = this.propertiesAgent.init(this, propertiesConf); - if (props != null) { - agentEnvs.putAll(props); + Map propMap = this.propertiesAgent.init(this, propertiesConf); + if (propMap != null) { + for (Map.Entry en : propMap.entrySet()) { + if (en.getKey().startsWith("logging")) { + if (logProps != null) { + logger.log(Level.WARNING, "skip repeat logging config properties(" + en.getKey() + ")"); + } else { + logProps = en.getValue(); + } + } else { + agentEnvs.putAll(en.getValue()); + } + } } } logger.info("PropertiesAgent (type = " + this.propertiesAgent.getClass().getSimpleName() + ") init in " + (System.currentTimeMillis() - s) + " ms"); @@ -798,6 +809,10 @@ public final class Application { } } } + //重置日志配置 + if (logProps != null && !logProps.isEmpty()) { + reconfigLogging(logProps); + } } void reconfigLogging(Properties properties0) { @@ -887,8 +902,19 @@ public final class Application { final PrintStream ps = new PrintStream(out); properties.forEach((x, y) -> ps.println(x + "=" + y)); try { - LogManager.getLogManager().readConfiguration(new ByteArrayInputStream(out.toByteArray())); - } catch (IOException e) { + LogManager manager = LogManager.getLogManager(); + manager.readConfiguration(new ByteArrayInputStream(out.toByteArray())); + loggingProperties.clear(); + loggingProperties.putAll(properties); + Enumeration en = manager.getLoggerNames(); + while (en.hasMoreElements()) { + for (Handler handler : manager.getLogger(en.nextElement()).getHandlers()) { + if (handler instanceof LoggingSearchHandler) { + ((LoggingSearchHandler) handler).application = this; + } + } + } + } catch (IOException e) { //不会发生 } } @@ -1775,7 +1801,6 @@ public final class Application { //PrepareCompiler.main(args); //测试代码 final Application application = Application.create(false); - currentApplication = application; application.init(); application.startSelfServer(); try { @@ -1794,7 +1819,7 @@ public final class Application { return value == null ? value : value.replace("${APP_HOME}", homePath).replace("${APP_NAME}", name); } - void updateEnvironmentProperties(List events) { + void updateEnvironmentProperties(String namespace, List events) { if (events == null || events.isEmpty()) return; synchronized (envProperties) { Properties envRegisterProps = new Properties(); @@ -1803,11 +1828,16 @@ public final class Application { Set sourceRemovedKeys = new HashSet<>(); Properties sourceChangedProps = new Properties(); + Properties loggingChangedProps = new Properties(); for (ResourceEvent event : events) { + if (namespace != null && namespace.startsWith("logging")) { + loggingChangedProps.put(event.name(), event.newValue()); + continue; + } if (event.name().startsWith("redkale.datasource.") || event.name().startsWith("redkale.datasource[") || event.name().startsWith("redkale.cachesource.") || event.name().startsWith("redkale.cachesource[")) { if (event.name().endsWith(".name")) { - logger.log(Level.WARNING, "skip illegal key " + event.name() + " in source config, key cannot endsWith '.name'"); + logger.log(Level.WARNING, "skip illegal key " + event.name() + " in source config " + (namespace == null ? "" : namespace) + ", key cannot endsWith '.name'"); } else { if (!Objects.equals(event.newValue(), sourceProperties.getProperty(event.name()))) { if (event.newValue() == null) { @@ -1864,6 +1894,26 @@ public final class Application { envRemovedKeys.forEach(k -> envProperties.remove(k)); resourceFactory.register(envRegisterProps, "", Environment.class); } + //日志配置项的变更 + if (!loggingChangedProps.isEmpty()) { + //只是简单变更日志级别则直接操作,无需重新配置日志 + if (loggingChangedProps.size() == 1 && loggingChangedProps.containsKey(".level")) { + try { + Level logLevel = Level.parse(loggingChangedProps.getProperty(".level")); + Logger.getGlobal().setLevel(logLevel); + loggingProperties.putAll(loggingChangedProps); + logger.log(Level.INFO, "reconfig logging level to " + logLevel); + } catch (Exception e) { + logger.log(Level.WARNING, "reconfig logging level error, new level is " + loggingChangedProps.getProperty(".level")); + } + } else { + Properties newLogProps = new Properties(); + newLogProps.putAll(this.loggingProperties); + newLogProps.putAll(loggingChangedProps); + reconfigLogging(newLogProps); + logger.log(Level.INFO, "reconfig logging finished "); + } + } //数据源配置项的变更 if (!sourceChangedProps.isEmpty() || !sourceRemovedKeys.isEmpty()) { Set cacheSourceNames = new LinkedHashSet<>(); diff --git a/src/main/java/org/redkale/boot/LoggingBaseHandler.java b/src/main/java/org/redkale/boot/LoggingBaseHandler.java index 0c87b04cc..c2ccb093a 100644 --- a/src/main/java/org/redkale/boot/LoggingBaseHandler.java +++ b/src/main/java/org/redkale/boot/LoggingBaseHandler.java @@ -14,7 +14,4 @@ import java.util.logging.Handler; */ public abstract class LoggingBaseHandler extends Handler { - protected Application currentApplication() { - return Application.currentApplication; //不能直接暴露外界访问 - } } diff --git a/src/main/java/org/redkale/boot/LoggingSearchHandler.java b/src/main/java/org/redkale/boot/LoggingSearchHandler.java index 98c1329f6..1704aed6d 100644 --- a/src/main/java/org/redkale/boot/LoggingSearchHandler.java +++ b/src/main/java/org/redkale/boot/LoggingSearchHandler.java @@ -43,6 +43,9 @@ public class LoggingSearchHandler extends LoggingBaseHandler { protected SearchSource source; + //在LogManager.getLogManager().readConfiguration执行完后,通过反射注入Application + protected Application application; + public LoggingSearchHandler() { configure(); open(); @@ -95,7 +98,10 @@ public class LoggingSearchHandler extends LoggingBaseHandler { if (retryCount.get() < 1) return; try { Utility.sleep(3000); //如果SearchSource自身在打印日志,需要停顿一点时间让SearchSource初始化完成 - Application application = currentApplication(); + if (application == null) { + Utility.sleep(3000); + } + if (application == null) return; this.source = (SearchSource) application.loadDataSource(sourceResourceName, false); if (retryCount.get() == 1 && this.source == null) System.err.println("ERROR: not load logging.source(" + sourceResourceName + ")"); } catch (Exception t) { diff --git a/src/main/java/org/redkale/boot/PropertiesAgent.java b/src/main/java/org/redkale/boot/PropertiesAgent.java index e42957e3c..66a1a13a5 100644 --- a/src/main/java/org/redkale/boot/PropertiesAgent.java +++ b/src/main/java/org/redkale/boot/PropertiesAgent.java @@ -45,9 +45,9 @@ public abstract class PropertiesAgent { * @param application Application * @param conf 节点配置 * - * @return 加载的配置项 + * @return 加载的配置项, key:namespace */ - public abstract Properties init(Application application, AnyValue conf); + public abstract Map init(Application application, AnyValue conf); /** * 销毁动作 @@ -56,18 +56,9 @@ public abstract class PropertiesAgent { */ public abstract void destroy(AnyValue conf); - protected void updateEnvironmentProperties(Application application, List events) { + protected void updateEnvironmentProperties(Application application, String namespace, List events) { if (events == null || events.isEmpty()) return; - application.updateEnvironmentProperties(events); -// Properties envChangeCache = new Properties(); -// Properties sourceChangeCache = new Properties(); -// //props.forEach((k, v) -> application.updateEnvironmentProperty(k.toString(), v.toString().trim(), envChangeCache, sourceChangeCache)); -// if (!envChangeCache.isEmpty()) { -// application.resourceFactory.register(envChangeCache, "", Environment.class); -// } -// if (!sourceChangeCache.isEmpty()) { -// application.updateSourceProperties(sourceChangeCache); -// } + application.updateEnvironmentProperties(namespace, events); } protected void reconfigLogging(Application application, Properties loggingProperties) {