From f0497a2d11854f8bdb8dae9ef11d9d900789ebf0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 21 May 2026 10:50:43 +0000 Subject: [PATCH] docs: add JavaDoc with example usage to all main source classes and non-private methods Agent-Logs-Url: https://github.com/microsphere-projects/microsphere-logging/sessions/e3fe6db3-b002-49d5-9298-701ad373b159 Co-authored-by: mercyblitz <533114+mercyblitz@users.noreply.github.com> --- .../microsphere/logging/jdk/JavaLogging.java | 76 ++++++++ .../logging/log4j/Log4jLogger.java | 164 ++++++++++++++++++ .../logging/log4j/Log4jLoggerFactory.java | 29 ++++ .../logging/log4j/Log4jLogging.java | 65 +++++++ .../logging/log4j2/Log4j2Logger.java | 164 ++++++++++++++++++ .../logging/log4j2/Log4j2LoggerFactory.java | 29 ++++ .../logging/log4j2/Log4j2Logging.java | 68 ++++++++ .../logging/log4j2/LogEventComparator.java | 17 ++ .../log4j2/appender/InMemoryAppender.java | 125 +++++++++++++ .../log4j2/layout/DelegatingLayout.java | 106 +++++++++++ .../layout/SmartFileAppenderLayout.java | 75 ++++++++ .../logging/log4j2/util/Log4j2Utils.java | 57 +++++- .../logging/logback/LogbackLogging.java | 66 +++++++ .../logging/jmx/LoggingMXBeanAdapter.java | 94 ++++++++++ .../test/junit4/LoggingLevelsRule.java | 21 +++ .../test/junit4/LoggingLevelsStatement.java | 23 +++ .../logging/LoggingLevelCallback.java | 36 ++++ .../LoggingLevelParameterResolver.java | 29 ++++ ...LoggingLevelTemplateInvocationContext.java | 45 +++++ .../logging/LoggingLevelsExtension.java | 86 +++++++++ 20 files changed, 1373 insertions(+), 2 deletions(-) diff --git a/microsphere-java-logging/src/main/java/io/microsphere/logging/jdk/JavaLogging.java b/microsphere-java-logging/src/main/java/io/microsphere/logging/jdk/JavaLogging.java index 059b439..b14a925 100644 --- a/microsphere-java-logging/src/main/java/io/microsphere/logging/jdk/JavaLogging.java +++ b/microsphere-java-logging/src/main/java/io/microsphere/logging/jdk/JavaLogging.java @@ -55,41 +55,117 @@ public class JavaLogging implements Logging { static final LoggingMXBean loggingMXBean = getLoggingMXBean(); + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   JavaLogging logging = new JavaLogging();
+     *   String rootName = logging.getRootLoggerName();
+     *   // returns "" (empty string for the JDK root logger)
+     * }
+ */ @Override public String getRootLoggerName() { return ROOT_LOGGER_NAME; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   JavaLogging logging = new JavaLogging();
+     *   List names = logging.getLoggerNames();
+     * }
+ */ @Override public List getLoggerNames() { return loggingMXBean.getLoggerNames(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   JavaLogging logging = new JavaLogging();
+     *   Set levels = logging.getSupportedLoggingLevels();
+     *   // e.g. ["OFF", "SEVERE", "WARNING", "INFO", "CONFIG", "FINE", "FINER", "FINEST", "ALL"]
+     * }
+ */ @Override public Set getSupportedLoggingLevels() { return ALL_LEVELS; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   JavaLogging logging = new JavaLogging();
+     *   String level = logging.getLoggerLevel("io.microsphere"); // e.g. "INFO"
+     * }
+ */ @Override public String getLoggerLevel(String loggerName) { return loggingMXBean.getLoggerLevel(loggerName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   JavaLogging logging = new JavaLogging();
+     *   logging.setLoggerLevel("io.microsphere", "FINE");
+     * }
+ */ @Override public void setLoggerLevel(String loggerName, String levelName) { loggingMXBean.setLoggerLevel(loggerName, levelName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   JavaLogging logging = new JavaLogging();
+     *   String parentName = logging.getParentLoggerName("io.microsphere.logging");
+     *   // returns "io.microsphere"
+     * }
+ */ @Override public String getParentLoggerName(String loggerName) { return loggingMXBean.getParentLoggerName(loggerName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   JavaLogging logging = new JavaLogging();
+     *   String name = logging.getName(); // "Java Logging"
+     * }
+ */ @Override public String getName() { return "Java Logging"; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   JavaLogging logging = new JavaLogging();
+     *   int priority = logging.getPriority();
+     *   // returns JavaLogging.PRIORITY
+     * }
+ */ @Override public int getPriority() { return PRIORITY; diff --git a/microsphere-log4j/src/main/java/io/microsphere/logging/log4j/Log4jLogger.java b/microsphere-log4j/src/main/java/io/microsphere/logging/log4j/Log4jLogger.java index f205a5c..8641040 100644 --- a/microsphere-log4j/src/main/java/io/microsphere/logging/log4j/Log4jLogger.java +++ b/microsphere-log4j/src/main/java/io/microsphere/logging/log4j/Log4jLogger.java @@ -37,87 +37,251 @@ class Log4jLogger extends AbstractLogger implements DelegatingWrapper { private final Logger logger; + /** + * Creates a new {@link Log4jLogger} for the given logger name. + * + * @param loggerName the name of the logger + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     * }
+ */ public Log4jLogger(String loggerName) { super(loggerName); this.logger = getLogger(loggerName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   if (logger.isTraceEnabled()) {
+     *     logger.trace("trace message");
+     *   }
+     * }
+ */ @Override public boolean isTraceEnabled() { return this.logger.isTraceEnabled(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   logger.trace("entering method foo");
+     * }
+ */ @Override public void trace(String message) { this.logger.trace(message); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   logger.trace("trace with exception", new RuntimeException("cause"));
+     * }
+ */ @Override public void trace(String message, Throwable t) { this.logger.trace(message, t); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   if (logger.isDebugEnabled()) {
+     *     logger.debug("debug message");
+     *   }
+     * }
+ */ @Override public boolean isDebugEnabled() { return this.logger.isDebugEnabled(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   logger.debug("processing item");
+     * }
+ */ @Override public void debug(String message) { this.logger.debug(message); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   logger.debug("debug with exception", new RuntimeException("cause"));
+     * }
+ */ @Override public void debug(String message, Throwable t) { this.logger.debug(message, t); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   if (logger.isInfoEnabled()) {
+     *     logger.info("application started");
+     *   }
+     * }
+ */ @Override public boolean isInfoEnabled() { return this.logger.isInfoEnabled(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   logger.info("application started");
+     * }
+ */ @Override public void info(String message) { this.logger.info(message); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   logger.info("info with exception", new RuntimeException("cause"));
+     * }
+ */ @Override public void info(String message, Throwable t) { this.logger.info(message, t); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   if (logger.isWarnEnabled()) {
+     *     logger.warn("low memory");
+     *   }
+     * }
+ */ @Override public boolean isWarnEnabled() { return this.logger.isEnabledFor(WARN); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   logger.warn("unexpected configuration value");
+     * }
+ */ @Override public void warn(String message) { this.logger.warn(message); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   logger.warn("warn with exception", new RuntimeException("cause"));
+     * }
+ */ @Override public void warn(String message, Throwable t) { this.logger.warn(message, t); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   if (logger.isErrorEnabled()) {
+     *     logger.error("operation failed");
+     *   }
+     * }
+ */ @Override public boolean isErrorEnabled() { return this.logger.isEnabledFor(ERROR); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   logger.error("operation failed");
+     * }
+ */ @Override public void error(String message) { this.logger.error(message); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   logger.error("error with exception", new RuntimeException("cause"));
+     * }
+ */ @Override public void error(String message, Throwable t) { this.logger.error(message, t); } + /** + * Returns the underlying Log4j {@link Logger} delegate. + * + *

Example Usage

+ *
{@code
+     *   Log4jLogger logger = new Log4jLogger("io.microsphere");
+     *   org.apache.log4j.Logger delegate = (org.apache.log4j.Logger) logger.getDelegate();
+     * }
+ */ @Override public Object getDelegate() { return this.logger; diff --git a/microsphere-log4j/src/main/java/io/microsphere/logging/log4j/Log4jLoggerFactory.java b/microsphere-log4j/src/main/java/io/microsphere/logging/log4j/Log4jLoggerFactory.java index 57eb108..73ef20e 100644 --- a/microsphere-log4j/src/main/java/io/microsphere/logging/log4j/Log4jLoggerFactory.java +++ b/microsphere-log4j/src/main/java/io/microsphere/logging/log4j/Log4jLoggerFactory.java @@ -33,16 +33,45 @@ public class Log4jLoggerFactory extends LoggerFactory { public static final String LOG4J_LOGGER_CLASS_NAME = "org.apache.log4j.Logger"; + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLoggerFactory factory = new Log4jLoggerFactory();
+     *   String className = factory.getDelegateLoggerClassName();
+     *   // returns "org.apache.log4j.Logger"
+     * }
+ */ @Override protected String getDelegateLoggerClassName() { return LOG4J_LOGGER_CLASS_NAME; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLoggerFactory factory = new Log4jLoggerFactory();
+     *   Logger logger = factory.createLogger("io.microsphere");
+     * }
+ */ @Override public Logger createLogger(String name) { return new Log4jLogger(name); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLoggerFactory factory = new Log4jLoggerFactory();
+     *   int priority = factory.getPriority();
+     *   // returns Log4jLogging.PRIORITY
+     * }
+ */ @Override public int getPriority() { return PRIORITY; diff --git a/microsphere-log4j/src/main/java/io/microsphere/logging/log4j/Log4jLogging.java b/microsphere-log4j/src/main/java/io/microsphere/logging/log4j/Log4jLogging.java index fb5ce2b..d0721bb 100644 --- a/microsphere-log4j/src/main/java/io/microsphere/logging/log4j/Log4jLogging.java +++ b/microsphere-log4j/src/main/java/io/microsphere/logging/log4j/Log4jLogging.java @@ -56,11 +56,29 @@ public class Log4jLogging implements Logging { */ public static final Set ALL_LEVELS = INSTANCE.resolve(Level.class); + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogging logging = new Log4jLogging();
+     *   String rootName = logging.getRootLoggerName(); // "root"
+     * }
+ */ @Override public String getRootLoggerName() { return ROOT_LOGGER_NAME; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogging logging = new Log4jLogging();
+     *   List names = logging.getLoggerNames();
+     * }
+ */ @Override public List getLoggerNames() { LoggerRepository loggerRepository = getLoggerRepository(); @@ -71,26 +89,73 @@ public List getLoggerNames() { .collect(toList()); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogging logging = new Log4jLogging();
+     *   Set levels = logging.getSupportedLoggingLevels();
+     *   // e.g. ["OFF", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "ALL"]
+     * }
+ */ @Override public Set getSupportedLoggingLevels() { return ALL_LEVELS; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogging logging = new Log4jLogging();
+     *   String level = logging.getLoggerLevel("io.microsphere"); // e.g. "INFO"
+     * }
+ */ @Override public String getLoggerLevel(String loggerName) { return getLevelString(loggerName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogging logging = new Log4jLogging();
+     *   logging.setLoggerLevel("io.microsphere", "DEBUG");
+     * }
+ */ @Override public void setLoggerLevel(String loggerName, String levelName) { Log4jUtils.setLoggerLevel(loggerName, levelName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogging logging = new Log4jLogging();
+     *   String name = logging.getName(); // "Log4j"
+     * }
+ */ @Override public String getName() { return "Log4j"; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4jLogging logging = new Log4jLogging();
+     *   int priority = logging.getPriority();
+     *   // returns Log4jLogging.PRIORITY
+     * }
+ */ @Override public int getPriority() { return PRIORITY; diff --git a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/Log4j2Logger.java b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/Log4j2Logger.java index 8bd13f6..4a6dafc 100644 --- a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/Log4j2Logger.java +++ b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/Log4j2Logger.java @@ -35,87 +35,251 @@ class Log4j2Logger extends AbstractLogger implements DelegatingWrapper { private final Logger logger; + /** + * Creates a new {@link Log4j2Logger} for the given logger name. + * + * @param loggerName the name of the logger + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     * }
+ */ public Log4j2Logger(String loggerName) { super(loggerName); this.logger = getLogger(loggerName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   if (logger.isTraceEnabled()) {
+     *     logger.trace("trace message");
+     *   }
+     * }
+ */ @Override public boolean isTraceEnabled() { return this.logger.isTraceEnabled(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   logger.trace("entering method foo");
+     * }
+ */ @Override public void trace(String message) { this.logger.trace(message); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   logger.trace("trace with exception", new RuntimeException("cause"));
+     * }
+ */ @Override public void trace(String message, Throwable t) { this.logger.trace(message, t); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   if (logger.isDebugEnabled()) {
+     *     logger.debug("debug message");
+     *   }
+     * }
+ */ @Override public boolean isDebugEnabled() { return this.logger.isDebugEnabled(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   logger.debug("processing item: {}", item);
+     * }
+ */ @Override public void debug(String message) { this.logger.debug(message); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   logger.debug("debug with exception", new RuntimeException("cause"));
+     * }
+ */ @Override public void debug(String message, Throwable t) { this.logger.debug(message, t); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   if (logger.isInfoEnabled()) {
+     *     logger.info("application started");
+     *   }
+     * }
+ */ @Override public boolean isInfoEnabled() { return this.logger.isInfoEnabled(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   logger.info("application started");
+     * }
+ */ @Override public void info(String message) { this.logger.info(message); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   logger.info("info with exception", new RuntimeException("cause"));
+     * }
+ */ @Override public void info(String message, Throwable t) { this.logger.info(message, t); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   if (logger.isWarnEnabled()) {
+     *     logger.warn("low memory");
+     *   }
+     * }
+ */ @Override public boolean isWarnEnabled() { return this.logger.isWarnEnabled(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   logger.warn("unexpected configuration value");
+     * }
+ */ @Override public void warn(String message) { this.logger.warn(message); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   logger.warn("warn with exception", new RuntimeException("cause"));
+     * }
+ */ @Override public void warn(String message, Throwable t) { this.logger.warn(message, t); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   if (logger.isErrorEnabled()) {
+     *     logger.error("operation failed");
+     *   }
+     * }
+ */ @Override public boolean isErrorEnabled() { return this.logger.isErrorEnabled(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   logger.error("operation failed");
+     * }
+ */ @Override public void error(String message) { this.logger.error(message); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   logger.error("error with exception", new RuntimeException("cause"));
+     * }
+ */ @Override public void error(String message, Throwable t) { this.logger.error(message, t); } + /** + * Returns the underlying Log4j2 {@link Logger} delegate. + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logger logger = new Log4j2Logger("io.microsphere");
+     *   org.apache.logging.log4j.Logger delegate = (org.apache.logging.log4j.Logger) logger.getDelegate();
+     * }
+ */ @Override public Object getDelegate() { return this.logger; diff --git a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/Log4j2LoggerFactory.java b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/Log4j2LoggerFactory.java index 1acfcfa..8d75601 100644 --- a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/Log4j2LoggerFactory.java +++ b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/Log4j2LoggerFactory.java @@ -33,16 +33,45 @@ public class Log4j2LoggerFactory extends LoggerFactory { public static final String LOG4J2_LOGGER_CLASS_NAME = "org.apache.logging.log4j.Logger"; + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2LoggerFactory factory = new Log4j2LoggerFactory();
+     *   String className = factory.getDelegateLoggerClassName();
+     *   // returns "org.apache.logging.log4j.Logger"
+     * }
+ */ @Override protected String getDelegateLoggerClassName() { return LOG4J2_LOGGER_CLASS_NAME; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2LoggerFactory factory = new Log4j2LoggerFactory();
+     *   Logger logger = factory.createLogger("io.microsphere");
+     * }
+ */ @Override public Logger createLogger(String name) { return new Log4j2Logger(name); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2LoggerFactory factory = new Log4j2LoggerFactory();
+     *   int priority = factory.getPriority();
+     *   // returns Log4j2Logging.PRIORITY
+     * }
+ */ @Override public int getPriority() { return PRIORITY; diff --git a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/Log4j2Logging.java b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/Log4j2Logging.java index 723fa8f..3f5dc4c 100644 --- a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/Log4j2Logging.java +++ b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/Log4j2Logging.java @@ -52,11 +52,30 @@ public class Log4j2Logging implements Logging { */ public static final Set ALL_LEVELS = INSTANCE.resolve(Level.class); + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logging logging = new Log4j2Logging();
+     *   String rootName = logging.getRootLoggerName();
+     *   // returns ""
+     * }
+ */ @Override public String getRootLoggerName() { return ROOT_LOGGER_NAME; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logging logging = new Log4j2Logging();
+     *   List names = logging.getLoggerNames();
+     * }
+ */ @Override public List getLoggerNames() { return getLoggers() @@ -65,26 +84,75 @@ public List getLoggerNames() { .collect(toList()); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logging logging = new Log4j2Logging();
+     *   Set levels = logging.getSupportedLoggingLevels();
+     *   // e.g. ["OFF", "FATAL", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "ALL"]
+     * }
+ */ @Override public Set getSupportedLoggingLevels() { return ALL_LEVELS; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logging logging = new Log4j2Logging();
+     *   String level = logging.getLoggerLevel("io.microsphere");
+     *   // e.g. "INFO"
+     * }
+ */ @Override public String getLoggerLevel(String loggerName) { return getLevelString(loggerName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logging logging = new Log4j2Logging();
+     *   logging.setLoggerLevel("io.microsphere", "DEBUG");
+     * }
+ */ @Override public void setLoggerLevel(String loggerName, String levelName) { Log4j2Utils.setLoggerLevel(loggerName, levelName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logging logging = new Log4j2Logging();
+     *   String name = logging.getName();
+     *   // returns "Log4j2"
+     * }
+ */ @Override public String getName() { return "Log4j2"; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Log4j2Logging logging = new Log4j2Logging();
+     *   int priority = logging.getPriority();
+     *   // returns Log4j2Logging.PRIORITY
+     * }
+ */ @Override public int getPriority() { return PRIORITY; diff --git a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/LogEventComparator.java b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/LogEventComparator.java index 95111aa..4a2abd4 100644 --- a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/LogEventComparator.java +++ b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/LogEventComparator.java @@ -38,6 +38,23 @@ public class LogEventComparator implements Comparator { private LogEventComparator() { } + /** + * Compares two {@link LogEvent} instances by their logging timestamp. + * Returns a negative integer, zero, or a positive integer if the first event's time + * is earlier than, equal to, or later than the second. + * + * @param o1 the first {@link LogEvent} + * @param o2 the second {@link LogEvent} + * @return a negative integer, zero, or positive integer + * + *

Example Usage

+ *
{@code
+     *   LogEvent event1 = ...; // earlier event
+     *   LogEvent event2 = ...; // later event
+     *   int result = LogEventComparator.INSTANCE.compare(event1, event2);
+     *   // result < 0 means event1 occurred before event2
+     * }
+ */ @Override public int compare(LogEvent o1, LogEvent o2) { return Long.compare(getTime(o1), getTime(o2)); diff --git a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/appender/InMemoryAppender.java b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/appender/InMemoryAppender.java index d61b33e..3dd2a5c 100644 --- a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/appender/InMemoryAppender.java +++ b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/appender/InMemoryAppender.java @@ -46,45 +46,147 @@ public class InMemoryAppender extends AbstractLifeCycle implements Appender { private final Set logEvents = new ConcurrentSkipListSet<>(INSTANCE); + /** + * Appends the given {@link LogEvent} to the in-memory collection. + * + * @param event the {@link LogEvent} to record + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = new InMemoryAppender();
+     *   appender.start();
+     *   LogEvent event = Log4jLogEvent.newBuilder()
+     *       .setLoggerName("test.logger")
+     *       .setLevel(Level.INFO)
+     *       .setMessage(new SimpleMessage("hello"))
+     *       .build();
+     *   appender.append(event);
+     * }
+ */ @Override public void append(LogEvent event) { logEvents.add(event); } + /** + * Returns the name of this appender, which is {@value #NAME}. + * + * @return the constant name {@value #NAME} + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = new InMemoryAppender();
+     *   String name = appender.getName(); // "InMemory"
+     * }
+ */ @Override public String getName() { return NAME; } + /** + * Returns {@code null} because this appender does not use a {@link Layout}. + * + * @return always {@code null} + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = new InMemoryAppender();
+     *   Layout layout = appender.getLayout(); // null
+     * }
+ */ @Override public Layout getLayout() { return null; } + /** + * Returns {@code false} because this appender does not silently ignore exceptions. + * + * @return always {@code false} + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = new InMemoryAppender();
+     *   boolean ignore = appender.ignoreExceptions(); // false
+     * }
+ */ @Override public boolean ignoreExceptions() { return false; } + /** + * Returns {@code null} because this appender does not use an {@link ErrorHandler}. + * + * @return always {@code null} + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = new InMemoryAppender();
+     *   ErrorHandler handler = appender.getHandler(); // null
+     * }
+ */ @Override public ErrorHandler getHandler() { return null; } + /** + * No-op: this appender does not support setting an {@link ErrorHandler}. + * + * @param handler ignored + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = new InMemoryAppender();
+     *   appender.setHandler(null); // no-op
+     * }
+ */ @Override public void setHandler(ErrorHandler handler) { } + /** + * Initializes the appender lifecycle. + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = new InMemoryAppender();
+     *   appender.initialize();
+     * }
+ */ @Override public void initialize() { super.initialize(); } + /** + * Starts the appender lifecycle. + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = new InMemoryAppender();
+     *   appender.start();
+     *   // appender is now ready to record events
+     * }
+ */ @Override public void start() { super.start(); } + /** + * Stops the appender lifecycle and clears all recorded {@link LogEvent} instances. + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = new InMemoryAppender();
+     *   appender.start();
+     *   appender.append(event);
+     *   appender.stop(); // clears buffered events
+     * }
+ */ @Override public void stop() { super.stop(); @@ -95,6 +197,15 @@ public void stop() { * Transfer all log events to another {@link Appender} * * @param appender another {@link Appender} + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender source = new InMemoryAppender();
+     *   source.start();
+     *   source.append(event);
+     *   FileAppender target = ...;
+     *   source.transfer(target);
+     * }
*/ public void transfer(Appender appender) { Iterator iterator = logEvents.iterator(); @@ -105,6 +216,20 @@ public void transfer(Appender appender) { } } + /** + * Finds and returns the {@link InMemoryAppender} registered in the current Log4j2 configuration, + * or {@code null} if none is registered. + * + * @return the registered {@link InMemoryAppender}, or {@code null} if not found + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = InMemoryAppender.findInMemoryAppender();
+     *   if (appender != null) {
+     *     appender.transfer(anotherAppender);
+     *   }
+     * }
+ */ public static InMemoryAppender findInMemoryAppender() { return findAppender(NAME); } diff --git a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/layout/DelegatingLayout.java b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/layout/DelegatingLayout.java index 7607832..cec05d1 100644 --- a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/layout/DelegatingLayout.java +++ b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/layout/DelegatingLayout.java @@ -34,52 +34,158 @@ public class DelegatingLayout implements Layout { private Layout delegate; + /** + * Creates a new {@link DelegatingLayout} wrapping the given delegate {@link Layout}. + * + * @param delegate the {@link Layout} to delegate to + * + *

Example Usage

+ *
{@code
+     *   Layout patternLayout = PatternLayout.newBuilder().withPattern("%m").build();
+     *   DelegatingLayout layout = new DelegatingLayout<>(patternLayout);
+     * }
+ */ public DelegatingLayout(Layout delegate) { this.delegate = delegate; } + /** + * Creates a new {@link DelegatingLayout} with no delegate set. The delegate must be + * provided via {@link #setDelegate(Layout)} before use. + * + *

Example Usage

+ *
{@code
+     *   DelegatingLayout layout = new DelegatingLayout<>();
+     *   layout.setDelegate(PatternLayout.newBuilder().withPattern("%m").build());
+     * }
+ */ public DelegatingLayout() { } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   DelegatingLayout layout = new DelegatingLayout<>(delegate);
+     *   byte[] footer = layout.getFooter();
+     * }
+ */ @Override public byte[] getFooter() { return delegate.getFooter(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   DelegatingLayout layout = new DelegatingLayout<>(delegate);
+     *   byte[] header = layout.getHeader();
+     * }
+ */ @Override public byte[] getHeader() { return delegate.getHeader(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   DelegatingLayout layout = new DelegatingLayout<>(delegate);
+     *   byte[] bytes = layout.toByteArray(logEvent);
+     * }
+ */ @Override public byte[] toByteArray(LogEvent event) { return delegate.toByteArray(event); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   DelegatingLayout layout = new DelegatingLayout<>(delegate);
+     *   Object serialized = layout.toSerializable(logEvent);
+     * }
+ */ @Override public T toSerializable(LogEvent event) { return delegate.toSerializable(event); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   DelegatingLayout layout = new DelegatingLayout<>(delegate);
+     *   String contentType = layout.getContentType();
+     * }
+ */ @Override public String getContentType() { return delegate.getContentType(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   DelegatingLayout layout = new DelegatingLayout<>(delegate);
+     *   Map format = layout.getContentFormat();
+     * }
+ */ @Override public Map getContentFormat() { return delegate.getContentFormat(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   DelegatingLayout layout = new DelegatingLayout<>(delegate);
+     *   layout.encode(logEvent, destination);
+     * }
+ */ @Override public void encode(LogEvent source, ByteBufferDestination destination) { delegate.encode(source, destination); } + /** + * Returns the underlying delegate {@link Layout}. + * + * @return the delegate {@link Layout} + * + *

Example Usage

+ *
{@code
+     *   DelegatingLayout layout = new DelegatingLayout<>(patternLayout);
+     *   Layout delegate = layout.getDelegate();
+     * }
+ */ public Layout getDelegate() { return delegate; } + /** + * Sets a new delegate {@link Layout}. + * + * @param delegate the new delegate {@link Layout} + * + *

Example Usage

+ *
{@code
+     *   DelegatingLayout layout = new DelegatingLayout<>();
+     *   layout.setDelegate(PatternLayout.newBuilder().withPattern("%d %m").build());
+     * }
+ */ public void setDelegate(Layout delegate) { this.delegate = delegate; } diff --git a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/layout/SmartFileAppenderLayout.java b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/layout/SmartFileAppenderLayout.java index ed9e3d2..28031ea 100644 --- a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/layout/SmartFileAppenderLayout.java +++ b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/layout/SmartFileAppenderLayout.java @@ -49,6 +49,18 @@ public class SmartFileAppenderLayout implements Layout delegatingLayouts; + /** + * Creates a new {@link SmartFileAppenderLayout} that inspects the given {@link LoggerContext} + * to select the appropriate delegating {@link Layout} per logger name. + * + * @param context the {@link LoggerContext} used to discover file appenders + * + *

Example Usage

+ *
{@code
+     *   LoggerContext context = (LoggerContext) LogManager.getContext(false);
+     *   SmartFileAppenderLayout layout = new SmartFileAppenderLayout<>(context);
+     * }
+ */ public SmartFileAppenderLayout(LoggerContext context) { this.delegatingLayouts = initDelegatingLayouts(context); } @@ -100,38 +112,101 @@ private Appender selectAppender(Logger logger, Class appende } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   SmartFileAppenderLayout layout = new SmartFileAppenderLayout<>(context);
+     *   byte[] footer = layout.getFooter();
+     * }
+ */ @Override public byte[] getFooter() { return DEFAULT_LAYOUT.getFooter(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   SmartFileAppenderLayout layout = new SmartFileAppenderLayout<>(context);
+     *   byte[] header = layout.getHeader();
+     * }
+ */ @Override public byte[] getHeader() { return DEFAULT_LAYOUT.getHeader(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   SmartFileAppenderLayout layout = new SmartFileAppenderLayout<>(context);
+     *   byte[] bytes = layout.toByteArray(logEvent);
+     * }
+ */ @Override public byte[] toByteArray(LogEvent event) { Layout delegate = getDelegate(event); return delegate.toByteArray(event); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   SmartFileAppenderLayout layout = new SmartFileAppenderLayout<>(context);
+     *   Object serialized = layout.toSerializable(logEvent);
+     * }
+ */ @Override public T toSerializable(LogEvent event) { Layout delegate = getDelegate(event); return (T) delegate.toSerializable(event); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   SmartFileAppenderLayout layout = new SmartFileAppenderLayout<>(context);
+     *   String contentType = layout.getContentType();
+     * }
+ */ @Override public String getContentType() { return DEFAULT_LAYOUT.getContentType(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   SmartFileAppenderLayout layout = new SmartFileAppenderLayout<>(context);
+     *   Map format = layout.getContentFormat();
+     * }
+ */ @Override public Map getContentFormat() { return DEFAULT_LAYOUT.getContentFormat(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   SmartFileAppenderLayout layout = new SmartFileAppenderLayout<>(context);
+     *   layout.encode(logEvent, destination);
+     * }
+ */ @Override public void encode(LogEvent source, ByteBufferDestination destination) { Layout delegate = getDelegate(source); diff --git a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/util/Log4j2Utils.java b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/util/Log4j2Utils.java index c2dbc36..c3e95e2 100644 --- a/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/util/Log4j2Utils.java +++ b/microsphere-log4j2/src/main/java/io/microsphere/logging/log4j2/util/Log4j2Utils.java @@ -190,30 +190,83 @@ public static Collection getLoggers() { return getLoggerContext().getLoggers(); } + /** + * Apply the given {@link Consumer} to each {@link Logger} in the current {@link LoggerContext}. + * + * @param loggerConsumer the consumer to apply + * + *

Example Usage

+ *
{@code
+     *   Log4j2Utils.doInLogger(logger -> logger.setLevel(Level.DEBUG));
+     * }
+ */ public static void doInLogger(Consumer loggerConsumer) { getLoggers().forEach(loggerConsumer); } /** + * Add the given {@link Appender} to the specified {@link Logger} instances. + * + * @param appender the {@link Appender} to add + * @param loggers the {@link Logger} instances to which the appender is added * - * @param appender - * @param loggers + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = new InMemoryAppender();
+     *   Collection loggers = Log4j2Utils.getLoggers();
+     *   Log4j2Utils.addAppender(appender, loggers);
+     * }
*/ public static void addAppender(Appender appender, Iterable loggers) { LoggerContext loggerContext = getLoggerContext(); addAppender(loggerContext, appender, loggers); } + /** + * Add the given {@link Appender} to all {@link Logger} instances in the current {@link LoggerContext}. + * + * @param appender the {@link Appender} to add to all loggers + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = new InMemoryAppender();
+     *   Log4j2Utils.addAppenderForAllLoggers(appender);
+     * }
+ */ public static void addAppenderForAllLoggers(Appender appender) { LoggerContext loggerContext = getLoggerContext(); addAppender(loggerContext, appender, loggerContext.getLoggers()); } + /** + * Remove the given {@link Appender} from the specified {@link Logger} instances. + * + * @param appender the {@link Appender} to remove + * @param loggers the {@link Logger} instances from which the appender is removed + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = new InMemoryAppender();
+     *   Collection loggers = Log4j2Utils.getLoggers();
+     *   Log4j2Utils.removeAppender(appender, loggers);
+     * }
+ */ public static void removeAppender(Appender appender, Iterable loggers) { LoggerContext loggerContext = getLoggerContext(); removeAppender(loggerContext, appender, loggers); } + /** + * Remove the given {@link Appender} from all {@link Logger} instances in the current {@link LoggerContext}. + * + * @param appender the {@link Appender} to remove from all loggers + * + *

Example Usage

+ *
{@code
+     *   InMemoryAppender appender = Log4j2Utils.findAppender(InMemoryAppender.NAME);
+     *   Log4j2Utils.removeAppenderForAllLoggers(appender);
+     * }
+ */ public static void removeAppenderForAllLoggers(Appender appender) { LoggerContext loggerContext = getLoggerContext(); removeAppender(loggerContext, appender, loggerContext.getLoggers()); diff --git a/microsphere-logback/src/main/java/io/microsphere/logging/logback/LogbackLogging.java b/microsphere-logback/src/main/java/io/microsphere/logging/logback/LogbackLogging.java index f8f941e..b95f29e 100644 --- a/microsphere-logback/src/main/java/io/microsphere/logging/logback/LogbackLogging.java +++ b/microsphere-logback/src/main/java/io/microsphere/logging/logback/LogbackLogging.java @@ -52,11 +52,30 @@ public class LogbackLogging implements Logging { */ public static final Set ALL_LEVELS = INSTANCE.resolve(Level.class); + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   LogbackLogging logging = new LogbackLogging();
+     *   String rootName = logging.getRootLoggerName();
+     *   // returns org.slf4j.Logger.ROOT_LOGGER_NAME ("ROOT")
+     * }
+ */ @Override public String getRootLoggerName() { return ROOT_LOGGER_NAME; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   LogbackLogging logging = new LogbackLogging();
+     *   List names = logging.getLoggerNames();
+     * }
+ */ @Override public List getLoggerNames() { return getLoggerContext() @@ -65,26 +84,73 @@ public List getLoggerNames() { .collect(toList()); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   LogbackLogging logging = new LogbackLogging();
+     *   Set levels = logging.getSupportedLoggingLevels();
+     *   // e.g. ["OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "ALL"]
+     * }
+ */ @Override public Set getSupportedLoggingLevels() { return ALL_LEVELS; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   LogbackLogging logging = new LogbackLogging();
+     *   String level = logging.getLoggerLevel("io.microsphere"); // e.g. "INFO"
+     * }
+ */ @Override public String getLoggerLevel(String loggerName) { return getLevelString(loggerName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   LogbackLogging logging = new LogbackLogging();
+     *   logging.setLoggerLevel("io.microsphere", "DEBUG");
+     * }
+ */ @Override public void setLoggerLevel(String loggerName, String levelName) { LogbackUtils.setLoggerLevel(loggerName, levelName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   LogbackLogging logging = new LogbackLogging();
+     *   String name = logging.getName(); // "Logback"
+     * }
+ */ @Override public String getName() { return "Logback"; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   LogbackLogging logging = new LogbackLogging();
+     *   int priority = logging.getPriority();
+     *   // returns LogbackLogging.PRIORITY
+     * }
+ */ @Override public int getPriority() { return PRIORITY; diff --git a/microsphere-logging-commons/src/main/java/io/microsphere/logging/jmx/LoggingMXBeanAdapter.java b/microsphere-logging-commons/src/main/java/io/microsphere/logging/jmx/LoggingMXBeanAdapter.java index bb3fdf6..04e70e9 100644 --- a/microsphere-logging-commons/src/main/java/io/microsphere/logging/jmx/LoggingMXBeanAdapter.java +++ b/microsphere-logging-commons/src/main/java/io/microsphere/logging/jmx/LoggingMXBeanAdapter.java @@ -35,45 +35,139 @@ public class LoggingMXBeanAdapter implements LoggingMXBean, DelegatingWrapper { private final Logging logging; + /** + * Creates a new {@link LoggingMXBeanAdapter} wrapping the given {@link Logging} instance. + * + * @param logging the {@link Logging} delegate; must not be {@code null} + * + *

Example Usage

+ *
{@code
+     *   Logging logging = LoggingUtils.load();
+     *   LoggingMXBeanAdapter adapter = new LoggingMXBeanAdapter(logging);
+     * }
+ */ public LoggingMXBeanAdapter(Logging logging) { this.logging = logging; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Logging logging = LoggingUtils.load();
+     *   LoggingMXBeanAdapter adapter = new LoggingMXBeanAdapter(logging);
+     *   List names = adapter.getLoggerNames();
+     * }
+ */ @Override public List getLoggerNames() { return this.logging.getLoggerNames(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Logging logging = LoggingUtils.load();
+     *   LoggingMXBeanAdapter adapter = new LoggingMXBeanAdapter(logging);
+     *   String level = adapter.getLoggerLevel("io.microsphere");
+     * }
+ */ @Override public String getLoggerLevel(String loggerName) { return this.logging.getLoggerLevel(loggerName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Logging logging = LoggingUtils.load();
+     *   LoggingMXBeanAdapter adapter = new LoggingMXBeanAdapter(logging);
+     *   adapter.setLoggerLevel("io.microsphere", "DEBUG");
+     * }
+ */ @Override public void setLoggerLevel(String loggerName, String levelName) { this.logging.setLoggerLevel(loggerName, levelName); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Logging logging = LoggingUtils.load();
+     *   LoggingMXBeanAdapter adapter = new LoggingMXBeanAdapter(logging);
+     *   String parentName = adapter.getParentLoggerName("io.microsphere.logging");
+     *   // returns "io.microsphere"
+     * }
+ */ @Override public String getParentLoggerName(String loggerName) { return this.logging.getParentLoggerName(loggerName); } + /** + * Returns the underlying {@link Logging} delegate. + * + *

Example Usage

+ *
{@code
+     *   Logging logging = LoggingUtils.load();
+     *   LoggingMXBeanAdapter adapter = new LoggingMXBeanAdapter(logging);
+     *   Logging delegate = (Logging) adapter.getDelegate();
+     * }
+ */ @Override public Object getDelegate() { return this.logging; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Logging logging = LoggingUtils.load();
+     *   LoggingMXBeanAdapter adapter = new LoggingMXBeanAdapter(logging);
+     *   int hash = adapter.hashCode();
+     * }
+ */ @Override public int hashCode() { return this.logging.hashCode(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Logging logging = LoggingUtils.load();
+     *   LoggingMXBeanAdapter adapter1 = new LoggingMXBeanAdapter(logging);
+     *   LoggingMXBeanAdapter adapter2 = new LoggingMXBeanAdapter(logging);
+     *   boolean equal = adapter1.equals(adapter2);
+     * }
+ */ @Override public boolean equals(Object obj) { return this.logging.equals(obj); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   Logging logging = LoggingUtils.load();
+     *   LoggingMXBeanAdapter adapter = new LoggingMXBeanAdapter(logging);
+     *   String str = adapter.toString();
+     *   // e.g. "LoggingMXBeanAdapter[Log4j2]"
+     * }
+ */ @Override public String toString() { return "LoggingMXBeanAdapter[" + logging + "]"; diff --git a/microsphere-logging-test/src/main/java/io/microsphere/logging/test/junit4/LoggingLevelsRule.java b/microsphere-logging-test/src/main/java/io/microsphere/logging/test/junit4/LoggingLevelsRule.java index 07ee373..aebda96 100644 --- a/microsphere-logging-test/src/main/java/io/microsphere/logging/test/junit4/LoggingLevelsRule.java +++ b/microsphere-logging-test/src/main/java/io/microsphere/logging/test/junit4/LoggingLevelsRule.java @@ -38,11 +38,32 @@ protected LoggingLevelsRule(String... levels) { this.levels = levels; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   LoggingLevelsRule rule = LoggingLevelsRule.levels("TRACE", "DEBUG", "INFO");
+     *   // JUnit 4 applies the rule, iterating through each logging level
+     * }
+ */ @Override public Statement apply(Statement base, Description description) { return new LoggingLevelsStatement(base, description, levels); } + /** + * Creates a new {@link LoggingLevelsRule} for the given logging levels. + * + * @param levels the logging levels to iterate through (e.g. "TRACE", "DEBUG", "INFO") + * @return a new {@link LoggingLevelsRule} + * + *

Example Usage

+ *
{@code
+     *   @ClassRule
+     *   public static final LoggingLevelsRule loggingLevelsRule = LoggingLevelsRule.levels("TRACE", "DEBUG", "INFO");
+     * }
+ */ public static LoggingLevelsRule levels(String... levels) { return new LoggingLevelsRule(levels); } diff --git a/microsphere-logging-test/src/main/java/io/microsphere/logging/test/junit4/LoggingLevelsStatement.java b/microsphere-logging-test/src/main/java/io/microsphere/logging/test/junit4/LoggingLevelsStatement.java index 02e73e9..eef5a27 100644 --- a/microsphere-logging-test/src/main/java/io/microsphere/logging/test/junit4/LoggingLevelsStatement.java +++ b/microsphere-logging-test/src/main/java/io/microsphere/logging/test/junit4/LoggingLevelsStatement.java @@ -46,6 +46,18 @@ public class LoggingLevelsStatement extends Statement { protected final Set levels; + /** + * Creates a new {@link LoggingLevelsStatement} with the specified statement, description, and logging levels. + * + * @param next the original JUnit {@link Statement} to wrap + * @param description the test {@link Description} + * @param levels the logging level names to iterate + * + *

Example Usage

+ *
{@code
+     *   LoggingLevelsStatement statement = new LoggingLevelsStatement(base, description, "TRACE", "DEBUG", "INFO");
+     * }
+ */ protected LoggingLevelsStatement(Statement next, Description description, String... levels) { this.next = next; this.description = description; @@ -53,6 +65,17 @@ protected LoggingLevelsStatement(Statement next, Description description, String this.levels = ofSet(levels); } + /** + * Evaluates the wrapped statement once per logging level, changing the logger level before each iteration + * and restoring the original level afterwards. + * + *

Example Usage

+ *
{@code
+     *   // Used internally by LoggingLevelsRule; each test method is executed with TRACE, DEBUG and INFO level
+     *   @ClassRule
+     *   public static final LoggingLevelsRule rule = LoggingLevelsRule.levels("TRACE", "DEBUG", "INFO");
+     * }
+ */ @Override public void evaluate() throws Throwable { Class testClass = this.testClass; diff --git a/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelCallback.java b/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelCallback.java index e3a6679..f00fa7a 100644 --- a/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelCallback.java +++ b/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelCallback.java @@ -49,6 +49,19 @@ class LoggingLevelCallback implements BeforeEachCallback, AfterEachCallback { private Map loggingsWithoriginalLevels; + /** + * Creates a new {@link LoggingLevelCallback}. + * + * @param loggings the list of {@link Logging} instances to configure + * @param loggerNames the logger names to set the level on + * @param level the logging level string to apply (e.g. "DEBUG", "INFO") + * + *

Example Usage

+ *
{@code
+     *   List loggings = LoggingUtils.loadAll();
+     *   LoggingLevelCallback callback = new LoggingLevelCallback(loggings, new String[]{"io.microsphere"}, "DEBUG");
+     * }
+ */ LoggingLevelCallback(List loggings, String[] loggerNames, String level) { this.loggings = loggings; this.loggerNames = loggerNames; @@ -56,6 +69,18 @@ class LoggingLevelCallback implements BeforeEachCallback, AfterEachCallback { this.loggingsWithoriginalLevels = newHashMap(loggings.size()); } + /** + * Sets the logging level for each logger name before each test method executes, + * storing the original levels for later restoration. + * + * @param context the current {@link ExtensionContext} + * + *

Example Usage

+ *
{@code
+     *   // Called automatically by JUnit 5 before each test method in a @LoggingLevelsTest template
+     *   callback.beforeEach(extensionContext);
+     * }
+ */ @Override public void beforeEach(ExtensionContext context) { int length = loggerNames.length; @@ -70,6 +95,17 @@ public void beforeEach(ExtensionContext context) { } } + /** + * Restores the original logging levels for each logger name after each test method completes. + * + * @param context the current {@link ExtensionContext} + * + *

Example Usage

+ *
{@code
+     *   // Called automatically by JUnit 5 after each test method in a @LoggingLevelsTest template
+     *   callback.afterEach(extensionContext);
+     * }
+ */ @Override public void afterEach(ExtensionContext context) { int length = loggerNames.length; diff --git a/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelParameterResolver.java b/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelParameterResolver.java index 6aaec5e..f9a58be 100644 --- a/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelParameterResolver.java +++ b/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelParameterResolver.java @@ -38,11 +38,31 @@ class LoggingLevelParameterResolver implements ParameterResolver { private final int index; + /** + * Creates a new {@link LoggingLevelParameterResolver} with the given level and index. + * + * @param level the logging level string (e.g. "DEBUG", "INFO") + * @param index the zero-based index of the level in the levels array + * + *

Example Usage

+ *
{@code
+     *   LoggingLevelParameterResolver resolver = new LoggingLevelParameterResolver("DEBUG", 0);
+     * }
+ */ LoggingLevelParameterResolver(String level, int index) { this.level = level; this.index = index; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   // Returns true if the parameter type is String (for level) or int (for index)
+     *   boolean supported = resolver.supportsParameter(parameterContext, extensionContext);
+     * }
+ */ @Override public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { Parameter parameter = parameterContext.getParameter(); @@ -50,6 +70,15 @@ public boolean supportsParameter(ParameterContext parameterContext, ExtensionCon return String.class.equals(parameterType) || int.class.equals(parameterType); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   // Returns the level string for String parameters, or the index for int parameters
+     *   Object value = resolver.resolveParameter(parameterContext, extensionContext);
+     * }
+ */ @Override public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) throws ParameterResolutionException { Parameter parameter = parameterContext.getParameter(); diff --git a/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelTemplateInvocationContext.java b/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelTemplateInvocationContext.java index e67ef99..fae2d5e 100644 --- a/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelTemplateInvocationContext.java +++ b/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelTemplateInvocationContext.java @@ -47,6 +47,22 @@ class LoggingLevelTemplateInvocationContext implements ClassTemplateInvocationCo private final boolean isClassTemplate; + /** + * Creates a new {@link LoggingLevelTemplateInvocationContext}. + * + * @param loggings the list of {@link Logging} instances to configure + * @param loggerName the logger names to apply the level to + * @param level the logging level string (e.g. "DEBUG", "INFO") + * @param index the zero-based index of this level in the levels array + * @param isClassTemplate {@code true} if this is a class template context + * + *

Example Usage

+ *
{@code
+     *   List loggings = LoggingUtils.loadAll();
+     *   LoggingLevelTemplateInvocationContext ctx =
+     *       new LoggingLevelTemplateInvocationContext(loggings, new String[]{"io.microsphere"}, "DEBUG", 0, false);
+     * }
+ */ LoggingLevelTemplateInvocationContext(List loggings, String[] loggerName, String level, int index, boolean isClassTemplate) { this.loggins = loggings; this.loggerName = loggerName; @@ -55,11 +71,29 @@ class LoggingLevelTemplateInvocationContext implements ClassTemplateInvocationCo this.isClassTemplate = isClassTemplate; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   LoggingLevelTemplateInvocationContext ctx = ...;
+     *   String displayName = ctx.getDisplayName(1); // e.g. "[DEBUG]"
+     * }
+ */ @Override public String getDisplayName(int invocationIndex) { return "[" + this.level + "]"; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   LoggingLevelTemplateInvocationContext ctx = ...;
+     *   List extensions = ctx.getAdditionalExtensions();
+     * }
+ */ @Override public List getAdditionalExtensions() { List extensions = new ArrayList<>(this.isClassTemplate ? 2 : 1); @@ -70,6 +104,17 @@ public List getAdditionalExtensions() { return extensions; } + /** + * Prepares the invocation context before each test execution. + * + * @param context the current {@link ExtensionContext} + * + *

Example Usage

+ *
{@code
+     *   LoggingLevelTemplateInvocationContext ctx = ...;
+     *   ctx.prepareInvocation(extensionContext);
+     * }
+ */ public void prepareInvocation(ExtensionContext context) { } } \ No newline at end of file diff --git a/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelsExtension.java b/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelsExtension.java index 94773d3..ee25c0a 100644 --- a/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelsExtension.java +++ b/microsphere-logging-test/src/main/java/io/microsphere/logging/test/jupiter/extension/logging/LoggingLevelsExtension.java @@ -58,6 +58,15 @@ public abstract class LoggingLevelsExtension implements Cl private final Class annotationType; + /** + * Creates a new {@link LoggingLevelsExtension} resolving the annotation type from the generic type parameter. + * + *

Example Usage

+ *
{@code
+     *   // Typically extended by concrete subclasses:
+     *   public class LoggingLevelsTestExtension extends LoggingLevelsExtension {}
+     * }
+ */ public LoggingLevelsExtension() { this.annotationType = resolveAnnotationType(); } @@ -69,21 +78,62 @@ private Class
resolveAnnotationType() { .toClass(); } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   // Always returns true so this extension supports any class template context
+     *   boolean supported = extension.supportsClassTemplate(context);
+     * }
+ */ @Override public boolean supportsClassTemplate(ExtensionContext context) { return true; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   // Always returns true so this extension supports any test template context
+     *   boolean supported = extension.supportsTestTemplate(context);
+     * }
+ */ @Override public boolean supportsTestTemplate(ExtensionContext context) { return true; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   // Provides one invocation context per logging level declared in @LoggingLevelsTest
+     *   Stream contexts =
+     *       extension.provideTestTemplateInvocationContexts(extensionContext);
+     * }
+ */ @Override public Stream provideTestTemplateInvocationContexts(ExtensionContext context) { return (Stream) provideInvocationContexts(context, false); } + /** + * Resolves the {@link LoggingLevelsAttributes} from the annotation on the test class or method. + * + * @param context the current {@link ExtensionContext} + * @param isClassTemplate {@code true} if resolving from a class template; {@code false} for a test template + * @return the resolved {@link LoggingLevelsAttributes} + * + *

Example Usage

+ *
{@code
+     *   LoggingLevelsAttributes attrs = extension.getLoggingLevelsAttributes(context, false);
+     *   String[] levels = attrs.levels; // e.g. ["TRACE", "DEBUG", "INFO"]
+     * }
+ */ protected LoggingLevelsAttributes getLoggingLevelsAttributes(ExtensionContext context, boolean isClassTemplate) { AnnotatedElement annotatedElement = isClassTemplate ? context.getRequiredTestClass() : context.getRequiredTestMethod(); A annotation = annotatedElement.getAnnotation(annotationType); @@ -97,11 +147,34 @@ protected LoggingLevelsAttributes getLoggingLevelsAttributes(ExtensionContext co return attributes; } + /** + * {@inheritDoc} + * + *

Example Usage

+ *
{@code
+     *   // Provides one ClassTemplateInvocationContext per logging level declared in @LoggingLevelsClass
+     *   Stream contexts =
+     *       extension.provideClassTemplateInvocationContexts(extensionContext);
+     * }
+ */ @Override public Stream provideClassTemplateInvocationContexts(ExtensionContext context) { return provideInvocationContexts(context, true); } + /** + * Builds the stream of {@link LoggingLevelTemplateInvocationContext} instances for the given levels. + * + * @param context the current {@link ExtensionContext} + * @param isClassTemplate {@code true} for class templates; {@code false} for test templates + * @return a {@link Stream} of invocation contexts, one per logging level + * + *

Example Usage

+ *
{@code
+     *   Stream stream =
+     *       extension.provideInvocationContexts(context, false);
+     * }
+ */ protected Stream provideInvocationContexts(ExtensionContext context, boolean isClassTemplate) { ClassLoader classLoader = getClassLoader(getClass()); List loggins = loadAll(classLoader); @@ -121,6 +194,19 @@ protected Stream provideInvocationContext return contexts.stream(); } + /** + * Resolves the logger names from the annotation attributes or falls back to the test class package name. + * + * @param context the current {@link ExtensionContext} + * @param attributes the resolved {@link LoggingLevelsAttributes} + * @return an array of logger names + * + *

Example Usage

+ *
{@code
+     *   String[] loggerNames = extension.getLoggerNames(context, attributes);
+     *   // If loggingClasses is empty, returns [testClass.getPackage().getName()]
+     * }
+ */ protected String[] getLoggerNames(ExtensionContext context, LoggingLevelsAttributes attributes) { Class[] loggingClasses = attributes.loggingClasses; if (isEmpty(loggingClasses)) {