From 68234c49f35c0369841b20bbee529f3325238d47 Mon Sep 17 00:00:00 2001 From: Yuriy Movchan Date: Thu, 23 Jan 2025 22:14:06 +0300 Subject: [PATCH 1/5] feat(oxCore): add json loggin layout support Signed-off-by: Yuriy Movchan --- .../gluu/service/logger/LoggerService.java | 277 ++++++++++-------- 1 file changed, 162 insertions(+), 115 deletions(-) diff --git a/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java b/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java index b02d04be..478ba3a8 100644 --- a/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java +++ b/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java @@ -1,6 +1,7 @@ package org.gluu.service.logger; import java.io.File; +import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.LogManager; @@ -11,7 +12,15 @@ import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.core.Appender; +import org.apache.logging.log4j.core.Layout; import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.appender.ConsoleAppender; +import org.apache.logging.log4j.core.appender.RollingFileAppender; +import org.apache.logging.log4j.core.config.AbstractConfiguration; +import org.apache.logging.log4j.core.config.LoggerConfig; +import org.apache.logging.log4j.core.layout.JsonLayout; +import org.apache.logging.log4j.core.layout.PatternLayout; import org.gluu.model.types.LoggingLayoutType; import org.gluu.service.cdi.async.Asynchronous; import org.gluu.service.cdi.event.ConfigurationUpdate; @@ -29,7 +38,11 @@ */ public abstract class LoggerService { - private final static int DEFAULT_INTERVAL = 15; // 15 seconds + private static final JsonLayout DEFAULT_JSON_PATTERN_LAYOUT = JsonLayout.createDefaultLayout(); + + private static final PatternLayout DEFAULT_TEXT_PATTERN_LAYOUT = PatternLayout.newBuilder().withPattern("%d %-5p [%t] [%C{6}] (%F:%L) - %m%n").build(); + + private final static int DEFAULT_INTERVAL = 15; // 15 seconds @Inject private Logger log; @@ -38,6 +51,7 @@ public abstract class LoggerService { private Event timerEvent; private Level prevLogLevel; + private LoggingLayoutType prevLogLoggingLayout; private AtomicBoolean isActive; @@ -80,6 +94,7 @@ public void updateLoggerTimerEvent(@Observes @Scheduled LoggerUpdateEvent logger try { updateLoggerConfiguration(); this.prevLogLevel = getCurrentLogLevel(); + this.prevLogLoggingLayout = getCurrentLoggingLayout(); } catch (Throwable ex) { log.error("Exception happened while updating newly added logger configuration", ex); } finally { @@ -90,15 +105,14 @@ public void updateLoggerTimerEvent(@Observes @Scheduled LoggerUpdateEvent logger private void updateLoggerConfiguration() { // Do periodic update to apply changes to new loggers as well String loggingLevel = getLoggingLevel(); - if (StringHelper.isEmpty(loggingLevel) || StringUtils.isEmpty(this.getLoggingLayout()) - || StringHelper.equalsIgnoreCase("DEFAULT", loggingLevel)) { + if (isWrongLoggingConfig(loggingLevel)) { return; } - Level level = Level.toLevel(loggingLevel, Level.INFO); - LoggingLayoutType loggingLayout = LoggingLayoutType.getByValue(this.getLoggingLayout().toUpperCase()); + Level level = getCurrentLogLevel(); + LoggingLayoutType loggingLayout = getCurrentLoggingLayout(); - updateAppendersAndLogLevel(loggingLayout, prevLogLevel, level); + updateAppendersAndLogLevel(prevLogLoggingLayout, loggingLayout, prevLogLevel, level); } public void updateLoggerSeverity(@Observes @ConfigurationUpdate Object appConfiguration) { @@ -134,24 +148,23 @@ private void updateLoggerSeverityImpl() { resetLoggerConfigLocation(); String loggingLevel = getLoggingLevel(); - if (StringHelper.isEmpty(loggingLevel) || StringUtils.isEmpty(this.getLoggingLayout()) - || StringHelper.equalsIgnoreCase("DEFAULT", loggingLevel)) { + if (isWrongLoggingConfig(loggingLevel)) { return; } - Level level = Level.toLevel(loggingLevel, Level.INFO); - LoggingLayoutType loggingLayout = LoggingLayoutType.getByValue(this.getLoggingLayout().toUpperCase()); + Level level = getCurrentLogLevel(); + LoggingLayoutType loggingLayout = getCurrentLoggingLayout(); log.info("Setting layout and loggers level to '{}`, `{}' after configuration update", loggingLayout, loggingLevel); - updateAppendersAndLogLevel(loggingLayout, prevLogLevel, level); + updateAppendersAndLogLevel(prevLogLoggingLayout, loggingLayout, prevLogLevel, level); } private void setDisableJdkLogger() { if (isDisableJdkLogger()) { - LogManager.getLogManager().reset(); java.util.logging.Logger globalLogger = java.util.logging.Logger.getLogger(java.util.logging.Logger.GLOBAL_LOGGER_NAME); - if (globalLogger != null) { + if ((globalLogger != null) && (globalLogger.getLevel() != java.util.logging.Level.OFF)) { + LogManager.getLogManager().reset(); globalLogger.setLevel(java.util.logging.Level.OFF); } } @@ -171,8 +184,11 @@ private boolean setExternalLoggerConfig() { } LoggerContext loggerContext = LoggerContext.getContext(false); - loggerContext.setConfigLocation(log4jFile.toURI()); - loggerContext.reconfigure(); + if (loggerContext.getConfigLocation() != log4jFile.toURI()) { + log.info("Starting logger context reconfigure after setting path to external configuration: '{}'", log4jFile.toURI()); + loggerContext.setConfigLocation(log4jFile.toURI()); + loggerContext.reconfigure(); + } return true; } @@ -187,111 +203,128 @@ public void resetLoggerConfigLocation() { loggerContext.reconfigure(); } - private void updateAppendersAndLogLevel(LoggingLayoutType loggingLayout, Level prevLevel, Level newLevel) { - if (loggingLayout == LoggingLayoutType.TEXT) { - if (newLevel != prevLevel) { - final LoggerContext ctx = LoggerContext.getContext(false); - ctx.getConfiguration().getRootLogger().setLevel(newLevel); - ctx.reconfigure(); - } - - LoggerContext loggerContext = LoggerContext.getContext(false); - - int count = 0; - for (org.apache.logging.log4j.core.Logger logger : loggerContext.getLoggers()) { - String loggerName = logger.getName(); - if (loggerName.startsWith("org.gluu")) { - if (logger.getLevel() != newLevel) { - count++; - logger.setLevel(newLevel); - } - } - } - - if (count > 0) { - log.info("Updated log level of '{}' loggers to {}", count, newLevel.toString()); - } + private void updateAppendersAndLogLevel(LoggingLayoutType prevLoggingLayout, LoggingLayoutType loggingLayout, Level prevLevel, Level newLevel) { + final LoggerContext ctx = LoggerContext.getContext(false); + + // Update logging layout if needed + if (prevLoggingLayout == loggingLayout) { + log.info("Updating logging layout configuration from '{}' to '{}'", prevLoggingLayout, loggingLayout); + updateLoggerLayout(loggingLayout, newLevel, ctx); } -// boolean runLoggersUpdate = false; -// int loggerConfigUpdates = 0; -// int appenderConfigUpdates = 0; -// LoggerContext ctx = LoggerContext.getContext(false); -// -// AbstractConfiguration config = (AbstractConfiguration) ctx.getConfiguration(); -// for (Entry loggerConfigEntry : config.getLoggers().entrySet()) { -// LoggerConfig loggerConfig = loggerConfigEntry.getValue(); -// log.trace("Updating log configuration '{}'", loggerConfig.getName()); -// -// if (!loggerConfig.getLevel().equals(level)) { -// loggerConfig.setLevel(level); -// log.trace("Updating log level in configuration '{}' to '{}'", loggerConfig.getName(), level); -// runLoggersUpdate = true; -// loggerConfigUpdates++; -// } -// -// for (Map.Entry appenderEntry : loggerConfig.getAppenders().entrySet()) { -// Appender appender = appenderEntry.getValue(); -// log.trace("Updating appender '{}'", appender.getName()); -// -// Layout layout = appender.getLayout(); -// if (loggingLayout == LoggingLayoutType.TEXT) { -// layout = PatternLayout.newBuilder().withPattern("%d %-5p [%t] [%C{6}] (%F:%L) - %m%n").build(); -// } else if (loggingLayout == LoggingLayoutType.JSON) { -// layout = JsonLayout.createDefaultLayout(); -// } -// -// if (appender instanceof RollingFileAppender) { -// RollingFileAppender rollingFile = (RollingFileAppender) appender; -// if (rollingFile.getLayout().getClass().isAssignableFrom(layout.getClass())) { -// continue; -// } -// RollingFileAppender newFileAppender = RollingFileAppender.newBuilder() -// .setLayout(layout) -// .withStrategy(rollingFile.getManager().getRolloverStrategy()) -// .withPolicy(rollingFile.getTriggeringPolicy()) -// .withFileName(rollingFile.getFileName()) -// .withFilePattern(rollingFile.getFilePattern()) -// .setName(rollingFile.getName()) -// .build(); -// newFileAppender.start(); -// appender.stop(); -// loggerConfig.removeAppender(appenderEntry.getKey()); -// loggerConfig.addAppender(newFileAppender, null, null); -// -// runLoggersUpdate = true; -// appenderConfigUpdates++; -// } else if (appender instanceof ConsoleAppender) { -// ConsoleAppender consoleAppender = (ConsoleAppender) appender; -// if (consoleAppender.getLayout().getClass().isAssignableFrom(layout.getClass())) { -// continue; -// } -// -// ConsoleAppender newConsoleAppender = ConsoleAppender.newBuilder() -// .setLayout(layout) -// .setTarget(consoleAppender.getTarget()) -// .setName(consoleAppender.getName()) -// .build(); -// newConsoleAppender.start(); -// appender.stop(); -// loggerConfig.removeAppender(appenderEntry.getKey()); -// loggerConfig.addAppender(newConsoleAppender, null, null); -// -// runLoggersUpdate = true; -// appenderConfigUpdates++; -// } -// } -// } -// -// if (runLoggersUpdate) { -// log.trace("Trigger loggers update after '{}' updates", loggerConfigUpdates + appenderConfigUpdates); -// ctx.updateLoggers(); -// } + + // Update root level if needed + Level rootLevel = ctx.getConfiguration().getRootLogger().getLevel(); + if ((newLevel != prevLevel) && (newLevel != rootLevel)) { + log.info("Updating root level to '{}'", newLevel); + ctx.getConfiguration().getRootLogger().setLevel(newLevel); + ctx.reconfigure(); + } + + // Update active loggers + updateActiveLoggers(newLevel, ctx); } + private void updateActiveLoggers(Level newLevel, final LoggerContext ctx) { + int count = 0; + for (org.apache.logging.log4j.core.Logger logger : ctx.getLoggers()) { + String loggerName = logger.getName(); + if (loggerName.startsWith("org.gluu")) { + if (logger.getLevel() != newLevel) { + count++; + logger.setLevel(newLevel); + } + } + } + + if (count > 0) { + log.info("Updated log level of '{}' loggers to '{}'", count, newLevel.toString()); + } + } + + // We need to call this method only on loggingLayout update + private void updateLoggerLayout(LoggingLayoutType loggingLayout, Level newLevel, final LoggerContext ctx) { + int loggerConfigUpdates = 0; + int appenderConfigUpdates = 0; + + AbstractConfiguration config = (AbstractConfiguration) ctx.getConfiguration(); + for (Map.Entry loggerConfigEntry : config.getLoggers().entrySet()) { + LoggerConfig loggerConfig = loggerConfigEntry.getValue(); + log.debug("Updating log configuration '{}'", loggerConfig.getName()); + + if (!loggerConfig.getLevel().equals(newLevel)) { + loggerConfig.setLevel(newLevel); + log.debug("Updating log level in configuration '{}' to '{}'", loggerConfig.getName(), newLevel); + loggerConfigUpdates++; + } + + for (Map.Entry appenderEntry : loggerConfig.getAppenders().entrySet()) { + Appender appender = appenderEntry.getValue(); + log.debug("Updating appender '{}'", appender.getName()); + + Layout layout = appender.getLayout(); + if (loggingLayout == LoggingLayoutType.TEXT) { + layout = DEFAULT_TEXT_PATTERN_LAYOUT; + } else if (loggingLayout == LoggingLayoutType.JSON) { + layout = DEFAULT_JSON_PATTERN_LAYOUT; + } + + if (appender instanceof RollingFileAppender) { + RollingFileAppender rollingFile = (RollingFileAppender) appender; + if (rollingFile.getLayout().getClass().isAssignableFrom(layout.getClass())) { + // Skip logger which have required logger type + continue; + } + + RollingFileAppender newFileAppender = RollingFileAppender.newBuilder() + .setLayout(layout) + .withStrategy(rollingFile.getManager().getRolloverStrategy()) + .withPolicy(rollingFile.getTriggeringPolicy()) + .withFileName(rollingFile.getFileName()) + .withFilePattern(rollingFile.getFilePattern()) + .setName(rollingFile.getName()) + .build(); + newFileAppender.start(); + appender.stop(); + loggerConfig.removeAppender(appenderEntry.getKey()); + loggerConfig.addAppender(newFileAppender, newLevel, null); + + appenderConfigUpdates++; + } else if (appender instanceof ConsoleAppender) { + ConsoleAppender consoleAppender = (ConsoleAppender) appender; + if (consoleAppender.getLayout().getClass().isAssignableFrom(layout.getClass())) { + // Skip logger which have required logger type + continue; + } + + ConsoleAppender newConsoleAppender = ConsoleAppender.newBuilder() + .setLayout(layout) + .setTarget(consoleAppender.getTarget()) + .setName(consoleAppender.getName()) + .build(); + newConsoleAppender.start(); + appender.stop(); + loggerConfig.removeAppender(appenderEntry.getKey()); + loggerConfig.addAppender(newConsoleAppender, newLevel, null); + + appenderConfigUpdates++; + } + } + } + + if ((loggerConfigUpdates > 0) || (appenderConfigUpdates > 0)) { + log.trace("Trigger loggers update after '{}' updates", loggerConfigUpdates + appenderConfigUpdates); + ctx.updateLoggers(); + } + } + + private boolean isWrongLoggingConfig(String loggingLevel) { + return StringHelper.isEmpty(loggingLevel) || StringUtils.isEmpty(this.getLoggingLayout()) + || StringHelper.equalsIgnoreCase("DEFAULT", loggingLevel); + } + private Level getCurrentLogLevel() { String loggingLevel = getLoggingLevel(); - if (StringHelper.isEmpty(loggingLevel) || StringUtils.isEmpty(this.getLoggingLayout()) - || StringHelper.equalsIgnoreCase("DEFAULT", loggingLevel)) { + if (isWrongLoggingConfig(loggingLevel)) { return Level.INFO; } @@ -300,6 +333,20 @@ private Level getCurrentLogLevel() { return level; } + private LoggingLayoutType getCurrentLoggingLayout() { + String loggingLayout = getLoggingLayout(); + if (isWrongLoggingConfig(loggingLayout)) { + return LoggingLayoutType.TEXT; + } + + LoggingLayoutType loggingLayoutType = LoggingLayoutType.getByValue(loggingLayout.toUpperCase()); + if (loggingLayoutType == null) { + return LoggingLayoutType.TEXT; + } + + return loggingLayoutType; + } + public abstract boolean isDisableJdkLogger(); public abstract String getLoggingLevel(); From 30391b27998fd127003b62dac4b413b2ce703f09 Mon Sep 17 00:00:00 2001 From: Yuriy Movchan Date: Fri, 24 Jan 2025 09:00:03 +0300 Subject: [PATCH 2/5] feat(oxCore): add json loggin layout support Signed-off-by: Yuriy Movchan --- .../gluu/service/logger/LoggerService.java | 45 +++++++++++-------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java b/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java index 478ba3a8..965f16f7 100644 --- a/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java +++ b/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java @@ -71,6 +71,7 @@ public void initTimer(boolean updateNow) { final int interval = DEFAULT_INTERVAL; this.prevLogLevel = getCurrentLogLevel(); + this.prevLogLoggingLayout = getCurrentLoggingLayout(); timerEvent.fire(new TimerEvent(new TimerSchedule(delay, interval), new LoggerUpdateEvent(), Scheduled.Literal.INSTANCE)); @@ -102,19 +103,7 @@ public void updateLoggerTimerEvent(@Observes @Scheduled LoggerUpdateEvent logger } } - private void updateLoggerConfiguration() { - // Do periodic update to apply changes to new loggers as well - String loggingLevel = getLoggingLevel(); - if (isWrongLoggingConfig(loggingLevel)) { - return; - } - - Level level = getCurrentLogLevel(); - LoggingLayoutType loggingLayout = getCurrentLoggingLayout(); - - updateAppendersAndLogLevel(prevLogLoggingLayout, loggingLayout, prevLogLevel, level); - } - + @Asynchronous public void updateLoggerSeverity(@Observes @ConfigurationUpdate Object appConfiguration) { if (this.isActive.get()) { return; @@ -139,31 +128,41 @@ public void updateLoggerSeverity() { } private void updateLoggerSeverityImpl() { + log.info("Starting logging configuration update after configuration change"); + + //resetLoggerConfigLocation(); + setDisableJdkLogger(); if (setExternalLoggerConfig()) { return; } + + updateLoggerConfiguration(); + } - resetLoggerConfigLocation(); - + private void updateLoggerConfiguration() { + // Do periodic update to apply changes to new loggers as well String loggingLevel = getLoggingLevel(); if (isWrongLoggingConfig(loggingLevel)) { + log.warn("Log level is invalid in logging configuration"); return; } Level level = getCurrentLogLevel(); LoggingLayoutType loggingLayout = getCurrentLoggingLayout(); - log.info("Setting layout and loggers level to '{}`, `{}' after configuration update", loggingLayout, loggingLevel); + log.info("Setting layout and loggers level to '{}`, `{}' after logging configuration update", loggingLayout, loggingLevel); updateAppendersAndLogLevel(prevLogLoggingLayout, loggingLayout, prevLogLevel, level); } private void setDisableJdkLogger() { if (isDisableJdkLogger()) { + log.info("Starting JDK loggers update"); java.util.logging.Logger globalLogger = java.util.logging.Logger.getLogger(java.util.logging.Logger.GLOBAL_LOGGER_NAME); if ((globalLogger != null) && (globalLogger.getLevel() != java.util.logging.Level.OFF)) { + log.info("Disabling JDK loggers"); LogManager.getLogManager().reset(); globalLogger.setLevel(java.util.logging.Level.OFF); } @@ -188,6 +187,8 @@ private boolean setExternalLoggerConfig() { log.info("Starting logger context reconfigure after setting path to external configuration: '{}'", log4jFile.toURI()); loggerContext.setConfigLocation(log4jFile.toURI()); loggerContext.reconfigure(); + } else { + log.debug("Logger context reconfigure is not required. Logconfiguration path is the same"); } return true; @@ -237,7 +238,7 @@ private void updateActiveLoggers(Level newLevel, final LoggerContext ctx) { } if (count > 0) { - log.info("Updated log level of '{}' loggers to '{}'", count, newLevel.toString()); + log.info("Updated '{}' loggers to level '{}'", count, newLevel.toString()); } } @@ -249,7 +250,7 @@ private void updateLoggerLayout(LoggingLayoutType loggingLayout, Level newLevel, AbstractConfiguration config = (AbstractConfiguration) ctx.getConfiguration(); for (Map.Entry loggerConfigEntry : config.getLoggers().entrySet()) { LoggerConfig loggerConfig = loggerConfigEntry.getValue(); - log.debug("Updating log configuration '{}'", loggerConfig.getName()); + log.debug("Analyzing log configuration '{}'", loggerConfig.getName()); if (!loggerConfig.getLevel().equals(newLevel)) { loggerConfig.setLevel(newLevel); @@ -259,7 +260,7 @@ private void updateLoggerLayout(LoggingLayoutType loggingLayout, Level newLevel, for (Map.Entry appenderEntry : loggerConfig.getAppenders().entrySet()) { Appender appender = appenderEntry.getValue(); - log.debug("Updating appender '{}'", appender.getName()); + log.debug("Analyzing appender '{}'", appender.getName()); Layout layout = appender.getLayout(); if (loggingLayout == LoggingLayoutType.TEXT) { @@ -271,10 +272,13 @@ private void updateLoggerLayout(LoggingLayoutType loggingLayout, Level newLevel, if (appender instanceof RollingFileAppender) { RollingFileAppender rollingFile = (RollingFileAppender) appender; if (rollingFile.getLayout().getClass().isAssignableFrom(layout.getClass())) { + log.debug("Skippig appender update '{}'", appender.getName()); // Skip logger which have required logger type continue; } + log.debug("Updating appender '{}'", appender.getName()); + RollingFileAppender newFileAppender = RollingFileAppender.newBuilder() .setLayout(layout) .withStrategy(rollingFile.getManager().getRolloverStrategy()) @@ -292,10 +296,13 @@ private void updateLoggerLayout(LoggingLayoutType loggingLayout, Level newLevel, } else if (appender instanceof ConsoleAppender) { ConsoleAppender consoleAppender = (ConsoleAppender) appender; if (consoleAppender.getLayout().getClass().isAssignableFrom(layout.getClass())) { + log.debug("Skippig appender update '{}'", appender.getName()); // Skip logger which have required logger type continue; } + log.debug("Updating appender '{}'", appender.getName()); + ConsoleAppender newConsoleAppender = ConsoleAppender.newBuilder() .setLayout(layout) .setTarget(consoleAppender.getTarget()) From 35630ac70268a479770bce00137b1cbfe665b949 Mon Sep 17 00:00:00 2001 From: Yuriy Movchan Date: Fri, 24 Jan 2025 16:39:48 +0300 Subject: [PATCH 3/5] feat(oxCore): add json loggin layout support Signed-off-by: Yuriy Movchan --- .../gluu/service/logger/LoggerService.java | 95 +++++++++++-------- 1 file changed, 57 insertions(+), 38 deletions(-) diff --git a/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java b/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java index 965f16f7..df3c08f0 100644 --- a/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java +++ b/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java @@ -54,6 +54,8 @@ public abstract class LoggerService { private LoggingLayoutType prevLogLoggingLayout; private AtomicBoolean isActive; + + private boolean useExternalConfiguration = false; @PostConstruct public void create() { @@ -93,7 +95,7 @@ public void updateLoggerTimerEvent(@Observes @Scheduled LoggerUpdateEvent logger } try { - updateLoggerConfiguration(); + updateLoggerConfiguration(true); this.prevLogLevel = getCurrentLogLevel(); this.prevLogLoggingLayout = getCurrentLoggingLayout(); } catch (Throwable ex) { @@ -114,7 +116,9 @@ public void updateLoggerSeverity(@Observes @ConfigurationUpdate Object appConfig } try { - updateLoggerSeverityImpl(); + updateApplicationConfiguration(); + this.prevLogLevel = getCurrentLogLevel(); + this.prevLogLoggingLayout = getCurrentLoggingLayout(); } catch (Throwable ex) { log.error("Exception happened while updating logger configuration after base configuration update", ex); } finally { @@ -122,29 +126,38 @@ public void updateLoggerSeverity(@Observes @ConfigurationUpdate Object appConfig } } - public void updateLoggerSeverity() { - // Full log4j2 configuration reload - updateLoggerSeverityImpl(); - } - - private void updateLoggerSeverityImpl() { + private void updateApplicationConfiguration() { log.info("Starting logging configuration update after configuration change"); - //resetLoggerConfigLocation(); - + // Disable JDK loggers setDisableJdkLogger(); - if (setExternalLoggerConfig()) { + boolean prevUseExternalConfiguration = this.useExternalConfiguration; + this.useExternalConfiguration = setExternalLoggerConfig(); + if (this.useExternalConfiguration) { + // Use external logging configuration + this.useExternalConfiguration = true; + log.info("Using ewxternal logging configuration. Layout type and log level update were disabled"); return; } - updateLoggerConfiguration(); + // Reset to default logging configuration + if (prevUseExternalConfiguration) { + log.info("Replacing logging configuration with default one. Layout type and log level update were enabled"); + resetLoggerConfigLocation(); + } + + // Call periodic logging configuration update + updateLoggerConfiguration(false); } - private void updateLoggerConfiguration() { + private void updateLoggerConfiguration(boolean isLoggerUpdateEvent) { + if (this.useExternalConfiguration) { + log.trace("Usign external logging configuration"); + } + // Do periodic update to apply changes to new loggers as well - String loggingLevel = getLoggingLevel(); - if (isWrongLoggingConfig(loggingLevel)) { + if (checkLoggingConfig()) { log.warn("Log level is invalid in logging configuration"); return; } @@ -152,7 +165,9 @@ private void updateLoggerConfiguration() { Level level = getCurrentLogLevel(); LoggingLayoutType loggingLayout = getCurrentLoggingLayout(); - log.info("Setting layout and loggers level to '{}`, `{}' after logging configuration update", loggingLayout, loggingLevel); + String msgPattern = isLoggerUpdateEvent ? "Starting layout and loggers level periodic update. Layout: '{}`, level: `{}' " : + "Starting layout and loggers level after configuration update. Layout: '{}`, level: `{}' "; + log.info(msgPattern, loggingLayout, level); updateAppendersAndLogLevel(prevLogLoggingLayout, loggingLayout, prevLogLevel, level); } @@ -171,14 +186,15 @@ private void setDisableJdkLogger() { private boolean setExternalLoggerConfig() { String externalLoggerConfiguration = getExternalLoggerConfiguration(); - log.info("External log configuration: {}", externalLoggerConfiguration); if (StringUtils.isEmpty(externalLoggerConfiguration)) { + log.trace("External log configuration is not provided"); return false; } + log.info("External log configuration: {}", externalLoggerConfiguration); File log4jFile = new File(externalLoggerConfiguration); if (!log4jFile.exists()) { - log.info("External log configuration does not exist."); + log.info("External log configuration file '{}' does not exist.", log4jFile.getAbsolutePath()); return false; } @@ -200,26 +216,30 @@ public void resetLoggerConfigLocation() { LoggerContext loggerContext = LoggerContext.getContext(false); if (loggerContext.getConfigLocation() != null) { loggerContext.setConfigLocation(null); + loggerContext.reconfigure(); } - loggerContext.reconfigure(); } - private void updateAppendersAndLogLevel(LoggingLayoutType prevLoggingLayout, LoggingLayoutType loggingLayout, Level prevLevel, Level newLevel) { + private void updateAppendersAndLogLevel(LoggingLayoutType prevLoggingLayout, LoggingLayoutType newLoggingLayout, Level prevLevel, Level newLevel) { final LoggerContext ctx = LoggerContext.getContext(false); - // Update logging layout if needed - if (prevLoggingLayout == loggingLayout) { - log.info("Updating logging layout configuration from '{}' to '{}'", prevLoggingLayout, loggingLayout); - updateLoggerLayout(loggingLayout, newLevel, ctx); - } - // Update root level if needed Level rootLevel = ctx.getConfiguration().getRootLogger().getLevel(); if ((newLevel != prevLevel) && (newLevel != rootLevel)) { log.info("Updating root level to '{}'", newLevel); ctx.getConfiguration().getRootLogger().setLevel(newLevel); - ctx.reconfigure(); + ctx.updateLoggers(); } + + // Update logger configurations and appenders on layout or level change + if ((prevLoggingLayout != newLoggingLayout) || (prevLevel != newLevel)) { + if (prevLoggingLayout == null) { + log.info("Setting logging layout to specified in configuration '{}'", newLoggingLayout); + } else { + log.info("Updating logging layout configuration from '{}' to '{}' and loggin level from '{}' to '{}'", prevLoggingLayout, newLoggingLayout, prevLevel, newLevel); + } + updateLoggerConfig(newLoggingLayout, newLevel, ctx); + } // Update active loggers updateActiveLoggers(newLevel, ctx); @@ -242,8 +262,7 @@ private void updateActiveLoggers(Level newLevel, final LoggerContext ctx) { } } - // We need to call this method only on loggingLayout update - private void updateLoggerLayout(LoggingLayoutType loggingLayout, Level newLevel, final LoggerContext ctx) { + private void updateLoggerConfig(LoggingLayoutType loggingLayout, Level newLevel, final LoggerContext ctx) { int loggerConfigUpdates = 0; int appenderConfigUpdates = 0; @@ -324,28 +343,28 @@ private void updateLoggerLayout(LoggingLayoutType loggingLayout, Level newLevel, } } - private boolean isWrongLoggingConfig(String loggingLevel) { - return StringHelper.isEmpty(loggingLevel) || StringUtils.isEmpty(this.getLoggingLayout()) - || StringHelper.equalsIgnoreCase("DEFAULT", loggingLevel); + private boolean checkLoggingConfig() { + return StringHelper.isEmpty(getLoggingLevel()) || StringUtils.isEmpty(this.getLoggingLayout()) + || StringHelper.equalsIgnoreCase("DEFAULT", getLoggingLevel()); } private Level getCurrentLogLevel() { - String loggingLevel = getLoggingLevel(); - if (isWrongLoggingConfig(loggingLevel)) { + if (checkLoggingConfig()) { return Level.INFO; } + String loggingLevel = getLoggingLevel(); Level level = Level.toLevel(loggingLevel, Level.INFO); return level; } private LoggingLayoutType getCurrentLoggingLayout() { - String loggingLayout = getLoggingLayout(); - if (isWrongLoggingConfig(loggingLayout)) { + if (checkLoggingConfig()) { return LoggingLayoutType.TEXT; } + String loggingLayout = getLoggingLayout(); LoggingLayoutType loggingLayoutType = LoggingLayoutType.getByValue(loggingLayout.toUpperCase()); if (loggingLayoutType == null) { return LoggingLayoutType.TEXT; @@ -357,9 +376,9 @@ private LoggingLayoutType getCurrentLoggingLayout() { public abstract boolean isDisableJdkLogger(); public abstract String getLoggingLevel(); - - public abstract String getExternalLoggerConfiguration(); public abstract String getLoggingLayout(); + + public abstract String getExternalLoggerConfiguration(); } From c0b68d86812357e95e9acf6da276828d444dff26 Mon Sep 17 00:00:00 2001 From: Yuriy Movchan Date: Fri, 24 Jan 2025 21:18:59 +0300 Subject: [PATCH 4/5] feat(oxCore): add json loggin layout support Signed-off-by: Yuriy Movchan --- .../gluu/service/logger/LoggerService.java | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java b/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java index df3c08f0..1881da80 100644 --- a/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java +++ b/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java @@ -1,6 +1,8 @@ package org.gluu.service.logger; import java.io.File; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.LogManager; @@ -266,6 +268,7 @@ private void updateLoggerConfig(LoggingLayoutType loggingLayout, Level newLevel, int loggerConfigUpdates = 0; int appenderConfigUpdates = 0; + List removeAppenders = new ArrayList<>(); AbstractConfiguration config = (AbstractConfiguration) ctx.getConfiguration(); for (Map.Entry loggerConfigEntry : config.getLoggers().entrySet()) { LoggerConfig loggerConfig = loggerConfigEntry.getValue(); @@ -291,7 +294,7 @@ private void updateLoggerConfig(LoggingLayoutType loggingLayout, Level newLevel, if (appender instanceof RollingFileAppender) { RollingFileAppender rollingFile = (RollingFileAppender) appender; if (rollingFile.getLayout().getClass().isAssignableFrom(layout.getClass())) { - log.debug("Skippig appender update '{}'", appender.getName()); + log.debug("Skipping appender update '{}'", appender.getName()); // Skip logger which have required logger type continue; } @@ -307,7 +310,7 @@ private void updateLoggerConfig(LoggingLayoutType loggingLayout, Level newLevel, .setName(rollingFile.getName()) .build(); newFileAppender.start(); - appender.stop(); + removeAppenders.add(appender); loggerConfig.removeAppender(appenderEntry.getKey()); loggerConfig.addAppender(newFileAppender, newLevel, null); @@ -315,7 +318,7 @@ private void updateLoggerConfig(LoggingLayoutType loggingLayout, Level newLevel, } else if (appender instanceof ConsoleAppender) { ConsoleAppender consoleAppender = (ConsoleAppender) appender; if (consoleAppender.getLayout().getClass().isAssignableFrom(layout.getClass())) { - log.debug("Skippig appender update '{}'", appender.getName()); + log.debug("Skipping appender update '{}'", appender.getName()); // Skip logger which have required logger type continue; } @@ -328,7 +331,7 @@ private void updateLoggerConfig(LoggingLayoutType loggingLayout, Level newLevel, .setName(consoleAppender.getName()) .build(); newConsoleAppender.start(); - appender.stop(); + removeAppenders.add(appender); loggerConfig.removeAppender(appenderEntry.getKey()); loggerConfig.addAppender(newConsoleAppender, newLevel, null); @@ -339,7 +342,14 @@ private void updateLoggerConfig(LoggingLayoutType loggingLayout, Level newLevel, if ((loggerConfigUpdates > 0) || (appenderConfigUpdates > 0)) { log.trace("Trigger loggers update after '{}' updates", loggerConfigUpdates + appenderConfigUpdates); - ctx.updateLoggers(); + + // Stop old appenders after adding new appenders to avoid lose messages + log.trace("Removind old '{}' appenders", removeAppenders.size()); + for (Appender appendr : removeAppenders) { + appendr.stop(); + } + + ctx.updateLoggers(config); } } From 7f046a3eb48f0c3311bd522c76d4e396b725b470 Mon Sep 17 00:00:00 2001 From: Yuriy Movchan Date: Fri, 24 Jan 2025 22:07:28 +0300 Subject: [PATCH 5/5] feat(oxCore): add json loggin layout support Signed-off-by: Yuriy Movchan --- .../main/java/org/gluu/service/logger/LoggerService.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java b/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java index 1881da80..0bec35d1 100644 --- a/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java +++ b/oxCore/oxService/src/main/java/org/gluu/service/logger/LoggerService.java @@ -138,8 +138,7 @@ private void updateApplicationConfiguration() { this.useExternalConfiguration = setExternalLoggerConfig(); if (this.useExternalConfiguration) { // Use external logging configuration - this.useExternalConfiguration = true; - log.info("Using ewxternal logging configuration. Layout type and log level update were disabled"); + log.info("Using external logging configuration. Layout type and log level update were disabled"); return; } @@ -311,8 +310,8 @@ private void updateLoggerConfig(LoggingLayoutType loggingLayout, Level newLevel, .build(); newFileAppender.start(); removeAppenders.add(appender); - loggerConfig.removeAppender(appenderEntry.getKey()); loggerConfig.addAppender(newFileAppender, newLevel, null); + loggerConfig.removeAppender(appenderEntry.getKey()); appenderConfigUpdates++; } else if (appender instanceof ConsoleAppender) { @@ -332,8 +331,8 @@ private void updateLoggerConfig(LoggingLayoutType loggingLayout, Level newLevel, .build(); newConsoleAppender.start(); removeAppenders.add(appender); - loggerConfig.removeAppender(appenderEntry.getKey()); loggerConfig.addAppender(newConsoleAppender, newLevel, null); + loggerConfig.removeAppender(appenderEntry.getKey()); appenderConfigUpdates++; }