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
+}