This is an automated email from the ASF dual-hosted git repository.

mattsicker pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git


The following commit(s) were added to refs/heads/master by this push:
     new 2d533123d6 Clean up static config in SimpleLogger/StatusLogger
     new 612c7f0caa Merge pull request #1139 from jvz/simple-logger
2d533123d6 is described below

commit 2d533123d65cc66332c41d6b0d51f85db6d3856e
Author: Matt Sicker <[email protected]>
AuthorDate: Sat Nov 12 22:54:06 2022 -0600

    Clean up static config in SimpleLogger/StatusLogger
    
    Signed-off-by: Matt Sicker <[email protected]>
---
 .../test/junit/LoggerContextFactoryExtension.java  |  1 -
 .../log4j/status/StatusConsoleListenerTest.java    |  5 +-
 .../apache/logging/log4j/simple/SimpleLogger.java  | 60 ++++++++--------
 .../log4j/simple/SimpleLoggerConfiguration.java    | 80 ++++++++++++++++++++++
 .../logging/log4j/simple/SimpleLoggerContext.java  | 44 ++----------
 .../org/apache/logging/log4j/spi/Provider.java     |  2 +-
 .../logging/log4j/status/SimpleLoggerFactory.java  | 59 ----------------
 .../log4j/status/StatusConsoleListener.java        | 14 +---
 .../apache/logging/log4j/status/StatusLogger.java  | 70 ++++---------------
 .../log4j/status/StatusLoggerConfiguration.java    | 56 +++++++++++++++
 .../logging/log4j/status/StatusLoggerFactory.java  | 50 ++++++++++++++
 .../log4j/core/test/junit/LoggerContextRule.java   | 10 +--
 log4j-to-jul/src/main/java/module-info.java        |  2 +-
 13 files changed, 247 insertions(+), 206 deletions(-)

diff --git 
a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/LoggerContextFactoryExtension.java
 
b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/LoggerContextFactoryExtension.java
index 0b63e3ab5e..89d412eb39 100644
--- 
a/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/LoggerContextFactoryExtension.java
+++ 
b/log4j-api-test/src/main/java/org/apache/logging/log4j/test/junit/LoggerContextFactoryExtension.java
@@ -14,7 +14,6 @@
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
-
 package org.apache.logging.log4j.test.junit;
 
 import org.apache.logging.log4j.LogManager;
diff --git 
a/log4j-api-test/src/test/java/org/apache/logging/log4j/status/StatusConsoleListenerTest.java
 
b/log4j-api-test/src/test/java/org/apache/logging/log4j/status/StatusConsoleListenerTest.java
index ba5d634841..9d761a1ce7 100644
--- 
a/log4j-api-test/src/test/java/org/apache/logging/log4j/status/StatusConsoleListenerTest.java
+++ 
b/log4j-api-test/src/test/java/org/apache/logging/log4j/status/StatusConsoleListenerTest.java
@@ -42,10 +42,9 @@ public class StatusConsoleListenerTest {
         Mockito.when(logger.atLevel(Mockito.any())).thenReturn(logBuilder);
         
Mockito.when(logBuilder.withThrowable(Mockito.any())).thenReturn(logBuilder);
         
Mockito.when(logBuilder.withLocation(Mockito.any())).thenReturn(logBuilder);
-        final SimpleLoggerFactory loggerFactory = 
Mockito.mock(SimpleLoggerFactory.class);
+        final StatusLoggerFactory loggerFactory = 
Mockito.mock(StatusLoggerFactory.class);
         Mockito
                 .when(loggerFactory.createSimpleLogger(
-                        Mockito.any(),
                         Mockito.any(),
                         Mockito.any(),
                         Mockito.any()))
@@ -74,7 +73,6 @@ public class StatusConsoleListenerTest {
                 .createSimpleLogger(
                         Mockito.eq("StatusConsoleListener"),
                         Mockito.same(level),
-                        Mockito.any(),
                         Mockito.same(stream));
         Mockito.verify(logger).atLevel(Mockito.same(level));
         Mockito.verify(logBuilder).withThrowable(Mockito.same(throwable));
@@ -125,6 +123,7 @@ public class StatusConsoleListenerTest {
         // Verify the output.
         Assertions
                 .assertThat(output)
+                .isNotBlank()
                 .contains(expectedThrowable.getMessage())
                 .contains(expectedMessage.getFormattedMessage())
                 .doesNotContain(discardedThrowable.getMessage())
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java
index 85bb91a15e..0045e6dc79 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLogger.java
@@ -18,7 +18,6 @@ package org.apache.logging.log4j.simple;
 
 import java.io.PrintStream;
 import java.text.DateFormat;
-import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.Map;
 
@@ -28,7 +27,7 @@ import org.apache.logging.log4j.ThreadContext;
 import org.apache.logging.log4j.message.Message;
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.spi.AbstractLogger;
-import org.apache.logging.log4j.util.PropertyEnvironment;
+import org.apache.logging.log4j.util.InternalApi;
 import org.apache.logging.log4j.util.Strings;
 
 /**
@@ -58,41 +57,36 @@ public class SimpleLogger extends AbstractLogger {
 
     private final String logName;
 
-    public SimpleLogger(final String name, final Level defaultLevel, final 
boolean showLogName,
-            final boolean showShortLogName, final boolean showDateTime, final 
boolean showContextMap,
-            final String dateTimeFormat, final MessageFactory messageFactory, 
final PropertyEnvironment props,
-            final PrintStream stream) {
+    public SimpleLogger(final String name, final MessageFactory 
messageFactory, final PrintStream stream,
+                        final SimpleLoggerConfiguration configuration) {
         super(name, messageFactory);
-        final String lvl = 
props.getStringProperty(SimpleLoggerContext.SYSTEM_PREFIX + name + ".level");
-        this.level = Level.toLevel(lvl, defaultLevel);
-        if (showShortLogName) {
+        level = configuration.getLoggerLevel(name);
+        if (configuration.isShortNameShown()) {
             final int index = name.lastIndexOf(".");
-            if (index > 0 && index < name.length()) {
-                this.logName = name.substring(index + 1);
-            } else {
-                this.logName = name;
-            }
-        } else if (showLogName) {
-            this.logName = name;
+            logName = index > 0 ? name.substring(index + 1) : name;
+        } else if (configuration.isLogNameShown()) {
+            logName = name;
         } else {
-            this.logName = null;
+            logName = null;
         }
-        this.showDateTime = showDateTime;
-        this.showContextMap = showContextMap;
+        showDateTime = configuration.isDateTimeShown();
+        showContextMap = configuration.isContextMapShown();
         this.stream = stream;
+        dateFormatter = showDateTime ? configuration.getDateTimeFormat() : 
null;
+    }
 
-        if (showDateTime) {
-            DateFormat format;
-            try {
-                format = new SimpleDateFormat(dateTimeFormat);
-            } catch (final IllegalArgumentException e) {
-                // If the format pattern is invalid - use the default format
-                format = new 
SimpleDateFormat(SimpleLoggerContext.DEFAULT_DATE_TIME_FORMAT);
-            }
-            this.dateFormatter = format;
-        } else {
-            this.dateFormatter = null;
-        }
+    // exposed for use in StatusLoggerFactory
+    @InternalApi
+    public SimpleLogger(final String name, final MessageFactory 
messageFactory, final PrintStream stream,
+                        final Level level, final DateFormat dateFormatter, 
final boolean showDateTime) {
+        super(name, messageFactory);
+        this.stream = stream;
+        this.level = level;
+        this.dateFormatter = dateFormatter;
+        this.showDateTime = showDateTime;
+        this.showContextMap = false;
+        final int index = name.lastIndexOf(".");
+        logName = index > 0 ? name.substring(index + 1) : name;
     }
 
     @Override
@@ -224,7 +218,7 @@ public class SimpleLogger extends AbstractLogger {
             final Map<String, String> mdc = 
ThreadContext.getImmutableContext();
             if (mdc.size() > 0) {
                 sb.append(SPACE);
-                sb.append(mdc.toString());
+                sb.append(mdc);
                 sb.append(SPACE);
             }
         }
@@ -236,7 +230,7 @@ public class SimpleLogger extends AbstractLogger {
         } else {
             t = throwable;
         }
-        stream.println(sb.toString());
+        stream.println(sb);
         if (t != null) {
             stream.print(SPACE);
             t.printStackTrace(stream);
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerConfiguration.java
 
b/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerConfiguration.java
new file mode 100644
index 0000000000..9e06cd0fce
--- /dev/null
+++ 
b/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerConfiguration.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.simple;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.util.PropertyEnvironment;
+
+import static 
org.apache.logging.log4j.simple.SimpleLoggerContext.DEFAULT_DATE_TIME_FORMAT;
+import static 
org.apache.logging.log4j.simple.SimpleLoggerContext.SYSTEM_PREFIX;
+
+public class SimpleLoggerConfiguration {
+
+    protected final PropertyEnvironment environment;
+
+    public SimpleLoggerConfiguration(final PropertyEnvironment environment) {
+        this.environment = environment;
+    }
+
+    /** Include the ThreadContextMap in the log message */
+    public boolean isContextMapShown() {
+        return environment.getBooleanProperty(SYSTEM_PREFIX + 
"showContextMap", false);
+    }
+
+    /** Include the instance name in the log message? */
+    public boolean isLogNameShown() {
+        return environment.getBooleanProperty(SYSTEM_PREFIX + "showlogname", 
false);
+    }
+
+    /**
+     * Include the short name (last component) of the logger in the log 
message. Defaults to true - otherwise we'll be
+     * lost in a flood of messages without knowing who sends them.
+     */
+    public boolean isShortNameShown() {
+        return environment.getBooleanProperty(SYSTEM_PREFIX + 
"showShortLogname", true);
+    }
+
+    /** Include the current time in the log message */
+    public boolean isDateTimeShown() {
+        return environment.getBooleanProperty(SYSTEM_PREFIX + "showdatetime", 
false);
+    }
+
+    public Level getDefaultLevel() {
+        final String level = environment.getStringProperty(SYSTEM_PREFIX + 
"level");
+        return Level.toLevel(level, Level.ERROR);
+    }
+
+    public Level getLoggerLevel(final String loggerName) {
+        final String level = environment.getStringProperty(SYSTEM_PREFIX + 
loggerName + ".level");
+        return Level.toLevel(level, getDefaultLevel());
+    }
+
+    public DateFormat getDateTimeFormat() {
+        try {
+            return new 
SimpleDateFormat(environment.getStringProperty(SYSTEM_PREFIX + 
"dateTimeFormat", DEFAULT_DATE_TIME_FORMAT));
+        } catch (final IllegalArgumentException e) {
+            return new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT);
+        }
+    }
+
+    public String getLogFileName() {
+        return environment.getStringProperty(SYSTEM_PREFIX + "logFile", 
"system.err");
+    }
+}
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java
 
b/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java
index 8c788069d2..6e72aa9fab 100644
--- 
a/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java
+++ 
b/log4j-api/src/main/java/org/apache/logging/log4j/simple/SimpleLoggerContext.java
@@ -20,14 +20,12 @@ import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.PrintStream;
 
-import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.spi.ExtendedLogger;
 import org.apache.logging.log4j.spi.LoggerContext;
 import org.apache.logging.log4j.spi.LoggerRegistry;
 import org.apache.logging.log4j.util.PropertiesUtil;
-import org.apache.logging.log4j.util.PropertyEnvironment;
 
 /**
  * A simple {@link LoggerContext} implementation.
@@ -47,27 +45,7 @@ public class SimpleLoggerContext implements LoggerContext {
     /** All system properties used by <code>SimpleLog</code> start with this */
     protected static final String SYSTEM_PREFIX = 
"org.apache.logging.log4j.simplelog.";
 
-    private final PropertyEnvironment props;
-
-    /** Include the instance name in the log message? */
-    private final boolean showLogName;
-
-    /**
-     * Include the short name (last component) of the logger in the log 
message. Defaults to true - otherwise we'll be
-     * lost in a flood of messages without knowing who sends them.
-     */
-    private final boolean showShortName;
-
-    /** Include the current time in the log message */
-    private final boolean showDateTime;
-
-    /** Include the ThreadContextMap in the log message */
-    private final boolean showContextMap;
-
-    /** The date and time format to use in the log message */
-    private final String dateTimeFormat;
-
-    private final Level defaultLevel;
+    private final SimpleLoggerConfiguration configuration;
 
     private final PrintStream stream;
 
@@ -77,19 +55,12 @@ public class SimpleLoggerContext implements LoggerContext {
      * Constructs a new initialized instance.
      */
     public SimpleLoggerContext() {
-        props = PropertiesUtil.getProperties("simplelog");
-
-        showContextMap = props.getBooleanProperty(SYSTEM_PREFIX + 
"showContextMap", false);
-        showLogName = props.getBooleanProperty(SYSTEM_PREFIX + "showlogname", 
false);
-        showShortName = props.getBooleanProperty(SYSTEM_PREFIX + 
"showShortLogname", true);
-        showDateTime = props.getBooleanProperty(SYSTEM_PREFIX + 
"showdatetime", false);
-        final String lvl = props.getStringProperty(SYSTEM_PREFIX + "level");
-        defaultLevel = Level.toLevel(lvl, Level.ERROR);
-
-        dateTimeFormat = showDateTime ? 
props.getStringProperty(SimpleLoggerContext.SYSTEM_PREFIX + "dateTimeFormat",
-                DEFAULT_DATE_TIME_FORMAT) : null;
+        this(new 
SimpleLoggerConfiguration(PropertiesUtil.getProperties("simplelog")));
+    }
 
-        final String fileName = props.getStringProperty(SYSTEM_PREFIX + 
"logFile", SYSTEM_ERR);
+    public SimpleLoggerContext(final SimpleLoggerConfiguration configuration) {
+        this.configuration = configuration;
+        final String fileName = configuration.getLogFileName();
         PrintStream ps;
         if (SYSTEM_ERR.equalsIgnoreCase(fileName)) {
             ps = System.err;
@@ -123,8 +94,7 @@ public class SimpleLoggerContext implements LoggerContext {
             AbstractLogger.checkMessageFactory(extendedLogger, messageFactory);
             return extendedLogger;
         }
-        final SimpleLogger simpleLogger = new SimpleLogger(name, defaultLevel, 
showLogName, showShortName, showDateTime,
-                showContextMap, dateTimeFormat, messageFactory, props, stream);
+        final SimpleLogger simpleLogger = new SimpleLogger(name, 
messageFactory, stream, configuration);
         loggerRegistry.putIfAbsent(name, messageFactory, simpleLogger);
         return loggerRegistry.getLogger(name, messageFactory);
     }
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/Provider.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/spi/Provider.java
index 591c4c27a0..833b2d1318 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/Provider.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/Provider.java
@@ -189,7 +189,7 @@ public class Provider {
     public URL getUrl() {
         return url;
     }
-    
+
     @Override
     public String toString() {
         final StringBuilder result = new StringBuilder("Provider[");
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/status/SimpleLoggerFactory.java
 
b/log4j-api/src/main/java/org/apache/logging/log4j/status/SimpleLoggerFactory.java
deleted file mode 100644
index a28da9e5de..0000000000
--- 
a/log4j-api/src/main/java/org/apache/logging/log4j/status/SimpleLoggerFactory.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.status;
-
-import java.io.PrintStream;
-
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.message.MessageFactory;
-import org.apache.logging.log4j.simple.SimpleLogger;
-import org.apache.logging.log4j.util.Strings;
-
-/**
- * {@link org.apache.logging.log4j.simple.SimpleLogger} factory to be used by 
{@link StatusLogger} and {@link StatusConsoleListener}.
- */
-class SimpleLoggerFactory {
-
-    private static final SimpleLoggerFactory INSTANCE = new 
SimpleLoggerFactory();
-
-    private SimpleLoggerFactory() {}
-
-    static SimpleLoggerFactory getInstance() {
-        return INSTANCE;
-    }
-
-    SimpleLogger createSimpleLogger(
-            final String name,
-            final Level level,
-            final MessageFactory messageFactory,
-            final PrintStream stream) {
-        final String dateFormat = 
StatusLogger.PROPS.getStringProperty(StatusLogger.STATUS_DATE_FORMAT);
-        final boolean dateFormatProvided = Strings.isNotBlank(dateFormat);
-        return new SimpleLogger(
-                name,
-                level,
-                false,
-                true,
-                dateFormatProvided,
-                false,
-                dateFormat,
-                messageFactory,
-                StatusLogger.PROPS,
-                stream);
-    }
-
-}
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusConsoleListener.java
 
b/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusConsoleListener.java
index f18134e34c..99275b98ff 100644
--- 
a/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusConsoleListener.java
+++ 
b/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusConsoleListener.java
@@ -22,7 +22,6 @@ import java.util.Objects;
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.message.ParameterizedNoReferenceMessageFactory;
 
 /**
  * {@link StatusListener} that writes to the console.
@@ -59,22 +58,15 @@ public class StatusConsoleListener implements 
StatusListener {
      * @throws NullPointerException on null {@code level} or {@code stream}
      */
     public StatusConsoleListener(final Level level, final PrintStream stream) {
-        this(level, stream, SimpleLoggerFactory.getInstance());
+        this(level, stream, StatusLoggerFactory.getInstance());
     }
 
-    StatusConsoleListener(
-            final Level level,
-            final PrintStream stream,
-            final SimpleLoggerFactory loggerFactory) {
+    StatusConsoleListener(final Level level, final PrintStream stream, final 
StatusLoggerFactory loggerFactory) {
         this.level = Objects.requireNonNull(level, "level");
         this.stream = Objects.requireNonNull(stream, "stream");
         this.logger = Objects
                 .requireNonNull(loggerFactory, "loggerFactory")
-                .createSimpleLogger(
-                        "StatusConsoleListener",
-                        level,
-                        ParameterizedNoReferenceMessageFactory.INSTANCE,
-                        stream);
+                .createSimpleLogger("StatusConsoleListener", level, stream);
     }
 
     /**
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java 
b/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java
index f3b894f65b..09828929dd 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java
@@ -32,65 +32,29 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Marker;
 import org.apache.logging.log4j.message.Message;
-import org.apache.logging.log4j.message.MessageFactory;
 import org.apache.logging.log4j.message.ParameterizedNoReferenceMessageFactory;
 import org.apache.logging.log4j.simple.SimpleLogger;
 import org.apache.logging.log4j.simple.SimpleLoggerContext;
 import org.apache.logging.log4j.spi.AbstractLogger;
 import org.apache.logging.log4j.spi.LoggingSystemProperties;
 import org.apache.logging.log4j.util.LowLevelLogUtil;
-import org.apache.logging.log4j.util.PropertiesUtil;
-import org.apache.logging.log4j.util.PropertyEnvironment;
 
 /**
  * Records events that occur in the logging system. By default, only error 
messages are logged to {@link System#err}.
  * Normally, the Log4j StatusLogger is configured via the root {@code 
<Configuration status="LEVEL"/>} node in a Log4j
  * configuration file. However, this can be overridden via a system property 
named
- * {@value #DEFAULT_STATUS_LISTENER_LEVEL} and will work with any Log4j 
provider.
+ * {@value LoggingSystemProperties#STATUS_DEFAULT_LISTENER_LEVEL} and will 
work with any Log4j provider.
  *
  * @see SimpleLogger
  * @see SimpleLoggerContext
  */
 public final class StatusLogger extends AbstractLogger {
 
-    /**
-     * System property that can be configured with the number of entries in 
the queue. Once the limit is reached older
-     * entries will be removed as new entries are added.
-     */
-    public static final String MAX_STATUS_ENTRIES = 
LoggingSystemProperties.STATUS_MAX_ENTRIES;
-
-    /**
-     * System property that can be configured with the {@link Level} name to 
use as the default level for
-     * {@link StatusListener}s.
-     */
-    public static final String DEFAULT_STATUS_LISTENER_LEVEL = 
LoggingSystemProperties.STATUS_DEFAULT_LISTENER_LEVEL;
-
-    /**
-     * System property that can be configured with a date-time format string 
to use as the format for timestamps
-     * in the status logger output. See {@link java.text.SimpleDateFormat} for 
supported formats.
-     * @since 2.11.0
-     */
-    public static final String STATUS_DATE_FORMAT = 
LoggingSystemProperties.STATUS_DATE_FORMAT;
-
     private static final long serialVersionUID = 2L;
 
     private static final String NOT_AVAIL = "?";
 
-    static final PropertyEnvironment PROPS = 
PropertiesUtil.getProperties("StatusLogger");
-
-    private static final int MAX_ENTRIES = 
PROPS.getIntegerProperty(MAX_STATUS_ENTRIES, 200);
-
-    private static final String DEFAULT_STATUS_LEVEL = 
PROPS.getStringProperty(DEFAULT_STATUS_LISTENER_LEVEL);
-
-    static final boolean DEBUG_ENABLED = PropertiesUtil
-            .getProperties()
-            .getBooleanProperty(LoggingSystemProperties.SYSTEM_DEBUG, false, 
true);
-
-    // LOG4J2-1176: normal parameterized message remembers param object, 
causing memory leaks.
-    private static final StatusLogger STATUS_LOGGER = new StatusLogger(
-            StatusLogger.class.getName(),
-            ParameterizedNoReferenceMessageFactory.INSTANCE,
-            SimpleLoggerFactory.getInstance());
+    private static final StatusLogger STATUS_LOGGER = 
StatusLoggerFactory.getInstance().createStatusLogger();
 
     static {
         // now safe to use StatusLogger in LowLevelLogUtil
@@ -98,6 +62,7 @@ public final class StatusLogger extends AbstractLogger {
     }
 
     private final SimpleLogger logger;
+    private final StatusLoggerConfiguration configuration;
 
     private final Collection<StatusListener> listeners = new 
CopyOnWriteArrayList<>();
 
@@ -105,7 +70,7 @@ public final class StatusLogger extends AbstractLogger {
     // ReentrantReadWriteLock is Serializable
     private final ReadWriteLock listenersLock = new ReentrantReadWriteLock();
 
-    private final Queue<StatusData> messages = new BoundedQueue<>(MAX_ENTRIES);
+    private final Queue<StatusData> messages;
 
     @SuppressWarnings("NonSerializableFieldInSerializableClass")
     // ReentrantLock is Serializable
@@ -126,29 +91,24 @@ public final class StatusLogger extends AbstractLogger {
      * This is now the listener level is set:
      * </p>
      * <ol>
-     * <li>If the property {@value #DEFAULT_STATUS_LISTENER_LEVEL} is set, 
then use <em>it</em>, otherwise,</li>
+     * <li>If the property {@value 
LoggingSystemProperties#STATUS_DEFAULT_LISTENER_LEVEL} is set, then use 
<em>it</em>, otherwise,</li>
      * <li>Use {@link Level#WARN}</li>
      * </ol>
      * <p>
      * See:
      * <ol>
      * <li>LOG4J2-1813 Provide shorter and more intuitive way to switch on 
Log4j internal debug logging. If system property
-     * "log4j2.debug" is defined, print all status logging.</li>
+     * {@value LoggingSystemProperties#SYSTEM_DEBUG} is defined, print all 
status logging.</li>
      * <li>LOG4J2-3340 StatusLogger's log Level cannot be changed as 
advertised.</li>
      * </ol>
      * </p>
-     *
-     * @param name The logger name.
-     * @param messageFactory The message factory.
      */
-    private StatusLogger(
-            final String name,
-            final MessageFactory messageFactory,
-            final SimpleLoggerFactory loggerFactory) {
-        super(name, messageFactory);
-        final Level loggerLevel = DEBUG_ENABLED ? Level.TRACE : Level.ERROR;
-        this.logger = loggerFactory.createSimpleLogger("StatusLogger", 
loggerLevel, messageFactory, System.err);
-        this.listenersLevel = Level.toLevel(DEFAULT_STATUS_LEVEL, 
Level.WARN).intLevel();
+    StatusLogger(final SimpleLogger logger, final StatusLoggerConfiguration 
configuration) {
+        super(StatusLogger.class.getName(), 
ParameterizedNoReferenceMessageFactory.INSTANCE);
+        this.logger = logger;
+        this.configuration = configuration;
+        this.listenersLevel = configuration.getDefaultLevel().intLevel();
+        messages = new BoundedQueue<>(configuration.getMaxEntries());
     }
 
     /**
@@ -192,7 +152,7 @@ public final class StatusLogger extends AbstractLogger {
         listenersLock.writeLock().lock();
         try {
             listeners.remove(listener);
-            int lowest = Level.toLevel(DEFAULT_STATUS_LEVEL, 
Level.WARN).intLevel();
+            int lowest = configuration.getDefaultLevel().intLevel();
             for (final StatusListener statusListener : listeners) {
                 final int level = statusListener.getStatusLevel().intLevel();
                 if (lowest < level) {
@@ -300,7 +260,7 @@ public final class StatusLogger extends AbstractLogger {
             msgLock.unlock();
         }
         // LOG4J2-1813 if system property "log4j2.debug" is defined, all 
status logging is enabled
-        if (DEBUG_ENABLED || (listeners.size() <= 0)) {
+        if (configuration.isDebugEnabled() || listeners.isEmpty()) {
             logger.logMessage(fqcn, level, marker, msg, t);
         } else {
             for (final StatusListener listener : listeners) {
@@ -430,7 +390,7 @@ public final class StatusLogger extends AbstractLogger {
 
     @Override
     public boolean isEnabled(final Level level, final Marker marker) {
-        if (DEBUG_ENABLED) {
+        if (configuration.isDebugEnabled()) {
             return true;
         }
         if (listeners.size() > 0) {
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLoggerConfiguration.java
 
b/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLoggerConfiguration.java
new file mode 100644
index 0000000000..47039d3869
--- /dev/null
+++ 
b/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLoggerConfiguration.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.status;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.util.PropertyEnvironment;
+
+import static org.apache.logging.log4j.spi.LoggingSystemProperties.*;
+
+public class StatusLoggerConfiguration {
+    private final PropertyEnvironment environment;
+
+    public StatusLoggerConfiguration(final PropertyEnvironment environment) {
+        this.environment = environment;
+    }
+
+    public int getMaxEntries() {
+        return environment.getIntegerProperty(STATUS_MAX_ENTRIES, 200);
+    }
+
+    public Level getDefaultLevel() {
+        return 
Level.toLevel(environment.getStringProperty(STATUS_DEFAULT_LISTENER_LEVEL), 
Level.WARN);
+    }
+
+    public boolean isDebugEnabled() {
+        return environment.getBooleanProperty(SYSTEM_DEBUG, false, true);
+    }
+
+    public DateFormat getDateTimeFormat() {
+        final String format = 
environment.getStringProperty(STATUS_DATE_FORMAT);
+        if (format != null) {
+            try {
+                return new SimpleDateFormat(format);
+            } catch (final IllegalArgumentException ignored) {
+            }
+        }
+        return null;
+    }
+}
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLoggerFactory.java
 
b/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLoggerFactory.java
new file mode 100644
index 0000000000..d7cd8eb0cf
--- /dev/null
+++ 
b/log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLoggerFactory.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.status;
+
+import java.io.PrintStream;
+import java.text.DateFormat;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.message.ParameterizedNoReferenceMessageFactory;
+import org.apache.logging.log4j.simple.SimpleLogger;
+import org.apache.logging.log4j.util.PropertiesUtil;
+
+class StatusLoggerFactory {
+    private static final String STATUS_LOGGER = "StatusLogger";
+    private final StatusLoggerConfiguration configuration;
+
+    StatusLoggerFactory(final StatusLoggerConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    SimpleLogger createSimpleLogger(final String name, final Level 
loggerLevel, final PrintStream stream) {
+        final DateFormat dateFormat = configuration.getDateTimeFormat();
+        return new SimpleLogger(name, 
ParameterizedNoReferenceMessageFactory.INSTANCE, stream,
+                loggerLevel, dateFormat, dateFormat != null);
+    }
+
+    StatusLogger createStatusLogger() {
+        final Level loggerLevel = configuration.isDebugEnabled() ? Level.TRACE 
: Level.ERROR;
+        final SimpleLogger logger = createSimpleLogger(STATUS_LOGGER, 
loggerLevel, System.err);
+        return new StatusLogger(logger, configuration);
+    }
+
+    static StatusLoggerFactory getInstance() {
+        return new StatusLoggerFactory(new 
StatusLoggerConfiguration(PropertiesUtil.getProperties(STATUS_LOGGER)));
+    }
+}
diff --git 
a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/LoggerContextRule.java
 
b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/LoggerContextRule.java
index 9bcb833c3b..118f71b245 100644
--- 
a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/LoggerContextRule.java
+++ 
b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/junit/LoggerContextRule.java
@@ -16,6 +16,8 @@
  */
 package org.apache.logging.log4j.core.test.junit;
 
+import java.util.concurrent.TimeUnit;
+
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.core.AbstractLifeCycle;
@@ -40,8 +42,6 @@ import org.junit.rules.TestRule;
 import org.junit.runner.Description;
 import org.junit.runners.model.Statement;
 
-import java.util.concurrent.TimeUnit;
-
 import static org.junit.Assert.assertNotNull;
 
 /**
@@ -58,7 +58,7 @@ public class LoggerContextRule implements TestRule, 
LoggerContextAccessor {
     public static LoggerContextRule 
createShutdownTimeoutLoggerContextRule(final String config) {
         return new LoggerContextRule(config, 10, TimeUnit.SECONDS);
     }
-    
+
     private static final String SYS_PROP_KEY_CLASS_NAME = 
"org.apache.logging.log4j.junit.LoggerContextRule#ClassName";
     private static final String SYS_PROP_KEY_DISPLAY_NAME = 
"org.apache.logging.log4j.junit.LoggerContextRule#DisplayName";
     private final String configurationLocation;
@@ -199,7 +199,7 @@ public class LoggerContextRule implements TestRule, 
LoggerContextAccessor {
 
     /**
      * Gets the configuration location.
-     * 
+     *
      * @return the configuration location.
      */
     public String getConfigurationLocation() {
@@ -310,7 +310,7 @@ public class LoggerContextRule implements TestRule, 
LoggerContextAccessor {
     public void reconfigure() {
         loggerContext.reconfigure();
     }
-    
+
     @Override
     public String toString() {
         final StringBuilder builder = new StringBuilder();
diff --git a/log4j-to-jul/src/main/java/module-info.java 
b/log4j-to-jul/src/main/java/module-info.java
index 6ad9397a86..481d142ce7 100644
--- a/log4j-to-jul/src/main/java/module-info.java
+++ b/log4j-to-jul/src/main/java/module-info.java
@@ -21,4 +21,4 @@ module org.apache.logging.log4j.tojul {
     requires java.logging;
 
     provides org.apache.logging.log4j.spi.Provider with 
org.apache.logging.log4j.tojul.JULProvider;
-}
\ No newline at end of file
+}


Reply via email to