-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Labels
apiAffects the public APIAffects the public APIbugIncorrect, unexpected, or unintended behavior of existing codeIncorrect, unexpected, or unintended behavior of existing code
Description
Description
StatusLogger messages used to be written to stderr by default. Since 2.23.0, they are writing to stdout. This is a significant regression. As a rule, stderr is for humans, and stdout is for programs. The pipe operator redirects stdout by default, and a CLI utility can have its output corrupted because Log4j2 emitted a status message to stdout. For example, consider a program that emits JSON and has its output piped to jq
: after upgrading to Log4j 2.23.0 or later, this program will cease to work correctly unless the StatusLogger is reconfigured to not emit anything, or is explicitly configured to write to stderr.
This regression can be fixed by calling the two-parameter constructor variant of StatusConsoleListener
from StatusLogger
:
diff --git log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java
index 6aec303cba..699dc66c8a 100644
--- log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java
+++ log4j-api/src/main/java/org/apache/logging/log4j/status/StatusLogger.java
@@ -531,7 +531,7 @@ public class StatusLogger extends AbstractLogger {
StatusLogger.class.getSimpleName(),
ParameterizedNoReferenceMessageFactory.INSTANCE,
Config.getInstance(),
- new StatusConsoleListener(requireNonNull(Config.getInstance().fallbackListenerLevel)));
+ new StatusConsoleListener(requireNonNull(Config.getInstance().fallbackListenerLevel), System.err));
}
/**
Logs & Reproduction
import org.apache.logging.log4j.LogManager;
public class LogTest {
public static void main(String[] args) {
LogManager.getLogger(LogTest.class);
System.out.println("{\"this is\":\"stdout\"}");
System.err.println("This is stderr");
}
}
[0] ~ # javac -cp Downloads/log4j-api-2.24.3.jar LogTest.java
[0] ~ # for i in Downloads/log4j-api-*.jar; echo $i && (java -cp .:$i LogTest | jq . ; echo "")
Downloads/log4j-api-2.20.0.jar
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
This is stderr
{
"this is": "stdout"
}
Downloads/log4j-api-2.21.0.jar
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
This is stderr
{
"this is": "stdout"
}
Downloads/log4j-api-2.21.1.jar
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
This is stderr
{
"this is": "stdout"
}
Downloads/log4j-api-2.22.0.jar
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
This is stderr
{
"this is": "stdout"
}
Downloads/log4j-api-2.22.1.jar
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...
This is stderr
{
"this is": "stdout"
}
Downloads/log4j-api-2.23.0.jar
jq: parse error: Invalid numeric literal at line 1, column 14
This is stderr
Downloads/log4j-api-2.23.1.jar
jq: parse error: Invalid numeric literal at line 1, column 14
This is stderr
Downloads/log4j-api-2.24.0.jar
jq: parse error: Invalid numeric literal at line 1, column 14
This is stderr
Downloads/log4j-api-2.24.1.jar
jq: parse error: Invalid numeric literal at line 1, column 14
This is stderr
Downloads/log4j-api-2.24.3.jar
jq: parse error: Invalid numeric literal at line 1, column 14
This is stderr
Metadata
Metadata
Assignees
Labels
apiAffects the public APIAffects the public APIbugIncorrect, unexpected, or unintended behavior of existing codeIncorrect, unexpected, or unintended behavior of existing code
Type
Projects
Status
Done