diff --git a/log4j-core-test/pom.xml b/log4j-core-test/pom.xml
index fcb6329be83..071668d291d 100644
--- a/log4j-core-test/pom.xml
+++ b/log4j-core-test/pom.xml
@@ -182,13 +182,6 @@
true
-
-
- org.fusesource.jansi
- jansi
- true
-
-
org.junit.jupiter
junit-jupiter-engine
diff --git a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/TestConstants.java b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/TestConstants.java
index 21a60e631d9..6ba7b9a19e4 100644
--- a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/TestConstants.java
+++ b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/TestConstants.java
@@ -67,8 +67,6 @@ private TestConstants() {}
public static final String CONFIGURATION_USE_PRECISE_CLOCK = CONFIGURATION + "usePreciseClock";
- public static final String CONSOLE_JANSI_ENABLED = "log4j.console.jansiEnabled";
-
private static final String GC = "log4j.gc.";
public static final String GC_ENABLE_DIRECT_ENCODERS = GC + "enableDirectEncoders";
diff --git a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/categories/Layouts.java b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/categories/Layouts.java
index 4b78f1fdc47..3838ab71d6e 100644
--- a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/categories/Layouts.java
+++ b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/categories/Layouts.java
@@ -21,6 +21,4 @@
*/
public interface Layouts {
interface Csv {}
-
- interface Jansi {}
}
diff --git a/log4j-core-test/src/main/resources/Log4j-config.xsd b/log4j-core-test/src/main/resources/Log4j-config.xsd
index c17d1c59e3f..3ff224097a0 100644
--- a/log4j-core-test/src/main/resources/Log4j-config.xsd
+++ b/log4j-core-test/src/main/resources/Log4j-config.xsd
@@ -696,7 +696,7 @@
Write directly to java.io.FileDescriptor and bypass java.lang.System.out/.err. Can give up to 10x performance boost when the
- output is redirected to file or other process. Cannot be used with Jansi on Windows. Cannot be used with follow.
+ output is redirected to file or other process. Cannot be used with follow.
@@ -704,7 +704,7 @@
Identifies whether the appender honors reassignments of System.out or System.err via System.setOut or System.setErr made after
- configuration. Note that the follow attribute cannot be used with Jansi on Windows. Cannot be used with direct.
+ configuration. Cannot be used with direct.
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiMessagesMain.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiMessagesMain.java
index 3088ca2bc1b..a44d064ab49 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiMessagesMain.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiMessagesMain.java
@@ -30,7 +30,7 @@
*
*
*
- * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes;%HOME%\.m2\repository\org\fusesource\jansi\jansi\1.14\jansi-1.14.jar; org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiMessagesMain log4j-core/target/test-classes/log4j2-console.xml
+ * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiMessagesMain log4j-core/target/test-classes/log4j2-console.xml
*
*/
public class ConsoleAppenderAnsiMessagesMain {
@@ -38,8 +38,7 @@ public class ConsoleAppenderAnsiMessagesMain {
private static final Logger LOG = LogManager.getLogger(ConsoleAppenderAnsiMessagesMain.class);
public static void main(final String[] args) {
- System.setProperty("log4j.skipJansi", "false"); // LOG4J2-2087: explicitly enable
- try (final LoggerContext ctx = Configurator.initialize(
+ try (final LoggerContext ignored = Configurator.initialize(
ConsoleAppenderAnsiMessagesMain.class.getName(), "target/test-classes/log4j2-console.xml")) {
LOG.fatal("\u001b[1;35mFatal message.\u001b[0m");
LOG.error("\u001b[1;31mError message.\u001b[0m");
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleJira180Main.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleJira180Main.java
index dffc5b42893..bd8491c6667 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleJira180Main.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleJira180Main.java
@@ -23,13 +23,13 @@
import org.apache.logging.log4j.core.config.Configurator;
/**
- * Tests https://issues.apache.org/jira/browse/LOG4J2-180
+ * Tests LOG4J2-180
*
* Running from a Windows command line from the root of the project:
*
*
*
- * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes;%HOME%\.m2\repository\org\fusesource\jansi\jansi\1.14\jansi-1.14.jar; org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiStyleJira180Main log4j-core/target/test-classes/log4j2-180.xml
+ * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiStyleJira180Main log4j-core/target/test-classes/log4j2-180.xml
*
*/
public class ConsoleAppenderAnsiStyleJira180Main {
@@ -37,10 +37,8 @@ public class ConsoleAppenderAnsiStyleJira180Main {
private static final Logger LOG = LogManager.getLogger(ConsoleAppenderAnsiStyleJira180Main.class);
public static void main(final String[] args) {
- System.setProperty("log4j.skipJansi", "false"); // LOG4J2-2087: explicitly enable
- // System.out.println(System.getProperty("java.class.path"));
final String config = args.length == 0 ? "target/test-classes/log4j2-180.xml" : args[0];
- try (final LoggerContext ctx =
+ try (final LoggerContext ignored =
Configurator.initialize(ConsoleAppenderAnsiMessagesMain.class.getName(), config)) {
LOG.fatal("Fatal message.");
LOG.error("Error message.");
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleJira272Main.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleJira272Main.java
index 0f2844abe77..65a4ed1ee79 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleJira272Main.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleJira272Main.java
@@ -23,12 +23,12 @@
import org.apache.logging.log4j.core.config.Configurator;
/**
- * Tests https://issues.apache.org/jira/browse/LOG4J2-272
+ * Tests LOG4J2-272
*
* Running from a Windows command line from the root of the project:
*
*
- * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes;%HOME%\.m2\repository\org\fusesource\jansi\jansi\1.14\jansi-1.14.jar; org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiStyleJira272Main log4j-core/target/test-classes/log4j2-272.xml
+ * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiStyleJira272Main log4j-core/target/test-classes/log4j2-272.xml
*
*/
public class ConsoleAppenderAnsiStyleJira272Main {
@@ -36,10 +36,8 @@ public class ConsoleAppenderAnsiStyleJira272Main {
private static final Logger LOG = LogManager.getLogger(ConsoleAppenderAnsiStyleJira272Main.class);
public static void main(final String[] args) {
- System.setProperty("log4j.skipJansi", "false"); // LOG4J2-2087: explicitly enable
- // System.out.println(System.getProperty("java.class.path"));
final String config = args.length == 0 ? "target/test-classes/log4j2-272.xml" : args[0];
- try (final LoggerContext ctx =
+ try (final LoggerContext ignored =
Configurator.initialize(ConsoleAppenderAnsiMessagesMain.class.getName(), config)) {
LOG.fatal("Fatal message.");
LOG.error("Error message.");
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleJira319Main.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleJira319Main.java
index 48681a85f71..957a58e9bf6 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleJira319Main.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleJira319Main.java
@@ -23,13 +23,13 @@
import org.apache.logging.log4j.core.config.Configurator;
/**
- * Tests https://issues.apache.org/jira/browse/LOG4J2-319
+ * Tests LOG4J2-319
*
* Running from a Windows command line from the root of the project:
*
*
*
- * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes;%HOME%\.m2\repository\org\fusesource\jansi\jansi\1.14\jansi-1.14.jar; org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiStyleJira319Main log4j-core/target/test-classes/log4j2-319.xml
+ * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiStyleJira319Main log4j-core/target/test-classes/log4j2-319.xml
*
*/
public class ConsoleAppenderAnsiStyleJira319Main {
@@ -37,10 +37,8 @@ public class ConsoleAppenderAnsiStyleJira319Main {
private static final Logger LOG = LogManager.getLogger(ConsoleAppenderAnsiStyleJira319Main.class);
public static void main(final String[] args) {
- System.setProperty("log4j.skipJansi", "false"); // LOG4J2-2087: explicitly enable
- // System.out.println(System.getProperty("java.class.path"));
final String config = args.length == 0 ? "target/test-classes/log4j2-319.xml" : args[0];
- try (final LoggerContext ctx =
+ try (final LoggerContext ignored =
Configurator.initialize(ConsoleAppenderAnsiMessagesMain.class.getName(), config)) {
LOG.fatal("Fatal message.");
LOG.error("Error message.");
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleLayoutMain.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleLayoutMain.java
index 87730d9a5a4..2ef1c52c9fa 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleLayoutMain.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleLayoutMain.java
@@ -35,7 +35,7 @@
*
* or:
*
- * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes;%HOME%\.m2\repository\org\fusesource\jansi\jansi\1.14\jansi-1.14.jar; org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiStyleLayoutMain log4j-core/target/test-classes/log4j2-console-style-ansi.xml
+ * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiStyleLayoutMain log4j-core/target/test-classes/log4j2-console-style-ansi.xml
*
*
*/
@@ -54,11 +54,9 @@ public void test() {
}
public void test(final String[] args) {
- System.setProperty("log4j.skipJansi", "false"); // LOG4J2-2087: explicitly enable
- // System.out.println(System.getProperty("java.class.path"));
final String config =
args == null || args.length == 0 ? "target/test-classes/log4j2-console-style-ansi.xml" : args[0];
- try (final LoggerContext ctx =
+ try (final LoggerContext ignored =
Configurator.initialize(ConsoleAppenderAnsiMessagesMain.class.getName(), config)) {
final Logger logger = LogManager.getLogger(ConsoleAppenderAnsiStyleLayoutMain.class);
logger.fatal("Fatal message.");
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleNameLayoutMain.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleNameLayoutMain.java
index 9088b75d47a..5cdc81ee452 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleNameLayoutMain.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiStyleNameLayoutMain.java
@@ -31,8 +31,7 @@ public class ConsoleAppenderAnsiStyleNameLayoutMain {
private static final Logger LOG = LogManager.getLogger(ConsoleAppenderAnsiStyleNameLayoutMain.class);
public static void main(final String[] args) {
- System.setProperty("log4j.skipJansi", "false"); // LOG4J2-2087: explicitly enable
- try (final LoggerContext ctx = Configurator.initialize(
+ try (final LoggerContext ignored = Configurator.initialize(
ConsoleAppenderAnsiMessagesMain.class.getName(),
"target/test-classes/log4j2-console-style-name-ansi.xml")) {
LOG.fatal("Fatal message.");
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiXExceptionMain.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiXExceptionMain.java
similarity index 78%
rename from log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiXExceptionMain.java
rename to log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiXExceptionMain.java
index d681e02c754..ee062add98e 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiXExceptionMain.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderAnsiXExceptionMain.java
@@ -22,9 +22,7 @@
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configurator;
-import org.apache.logging.log4j.core.test.categories.Layouts;
import org.junit.Test;
-import org.junit.experimental.categories.Category;
/**
* Shows how to use ANSI escape codes to color messages. Each message is printed to the console in color, but the rest
@@ -34,21 +32,20 @@
*
*
*
- * mvn -Dtest=org.apache.logging.log4j.core.appender.ConsoleAppenderJAnsiXExceptionMain test
+ * mvn -Dtest=org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiXExceptionMain test
*
*
* or, on Windows:
*
*
- * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes;%USERPROFILE%\.m2\repository\org\fusesource\jansi\jansi\1.14\jansi-1.14.jar; org.apache.logging.log4j.core.appender.ConsoleAppenderJAnsiXExceptionMain log4j-core/src/test/resources/log4j2-console-xex-ansi.xml
+ * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiXExceptionMain log4j-core/src/test/resources/log4j2-console-xex-ansi.xml
*
*
*/
-@Category(Layouts.Jansi.class)
-public class ConsoleAppenderJAnsiXExceptionMain {
+public class ConsoleAppenderAnsiXExceptionMain {
public static void main(final String[] args) {
- new ConsoleAppenderJAnsiXExceptionMain().test(args);
+ new ConsoleAppenderAnsiXExceptionMain().test(args);
}
/**
@@ -60,12 +57,10 @@ public void test() {
}
public void test(final String[] args) {
- System.setProperty("log4j.skipJansi", "false"); // LOG4J2-2087: explicitly enable
- // System.out.println(System.getProperty("java.class.path"));
final String config =
args == null || args.length == 0 ? "target/test-classes/log4j2-console-xex-ansi.xml" : args[0];
final LoggerContext ctx = Configurator.initialize(ConsoleAppenderAnsiMessagesMain.class.getName(), config);
- final Logger logger = LogManager.getLogger(ConsoleAppenderJAnsiXExceptionMain.class);
+ final Logger logger = LogManager.getLogger(ConsoleAppenderAnsiXExceptionMain.class);
try {
Files.getFileStore(Paths.get("?BOGUS?"));
} catch (final Exception e) {
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderDefaultSuppressedThrowable.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderDefaultSuppressedThrowable.java
index 8553eb3f1d0..2432df32c93 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderDefaultSuppressedThrowable.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderDefaultSuppressedThrowable.java
@@ -31,7 +31,7 @@
*
*
*
- * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes;%HOME%\.m2\repository\org\fusesource\jansi\jansi\1.14\jansi-1.14.jar; org.apache.logging.log4j.core.appender.ConsoleAppenderNoAnsiStyleLayoutMain log4j-core/target/test-classes/log4j2-console-style-ansi.xml
+ * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes org.apache.logging.log4j.core.appender.ConsoleAppenderNoAnsiStyleLayoutMain log4j-core/target/test-classes/log4j2-console-style-ansi.xml
*
*/
public class ConsoleAppenderDefaultSuppressedThrowable {
@@ -41,12 +41,11 @@ public class ConsoleAppenderDefaultSuppressedThrowable {
public static void main(final String[] args) {
final String config =
args.length == 0 ? "target/test-classes/log4j2-console-default-suppressed-throwable.xml" : args[0];
- test(args, config);
+ test(config);
}
- static void test(final String[] args, final String config) {
- // System.out.println(System.getProperty("java.class.path"));
- try (final LoggerContext ctx =
+ static void test(final String config) {
+ try (final LoggerContext ignored =
Configurator.initialize(ConsoleAppenderDefaultSuppressedThrowable.class.getName(), config)) {
final IOException ioEx = new IOException("test suppressed");
ioEx.addSuppressed(new IOException("test suppressed 1", new IOException("test 1")));
@@ -55,8 +54,6 @@ static void test(final String[] args, final String config) {
ioEx.addSuppressed(new IOException("test suppressed 2", ioEx2));
final IOException e = new IOException("test", ioEx);
LOG.error("Error message {}, suppressed?", "Hi", e);
- System.out.println("printStackTrace");
- e.printStackTrace();
}
}
}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutDefaultMain.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutDefaultMain.java
index 7a1b7cf616e..d9b5eeba270 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutDefaultMain.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutDefaultMain.java
@@ -31,8 +31,7 @@ public class ConsoleAppenderHighlightLayoutDefaultMain {
private static final Logger LOG = LogManager.getLogger(ConsoleAppenderHighlightLayoutDefaultMain.class);
public static void main(final String[] args) {
- System.setProperty("log4j.skipJansi", "false"); // LOG4J2-2087: explicitly enable
- try (final LoggerContext ctx = Configurator.initialize(
+ try (final LoggerContext ignored = Configurator.initialize(
ConsoleAppenderAnsiMessagesMain.class.getName(),
"target/test-classes/log4j2-console-highlight-default.xml")) {
LOG.fatal("Fatal message.");
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutMain.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutMain.java
index dbb6958ea25..ad86c245707 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutMain.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderHighlightLayoutMain.java
@@ -31,8 +31,7 @@ public class ConsoleAppenderHighlightLayoutMain {
private static final Logger LOG = LogManager.getLogger(ConsoleAppenderHighlightLayoutMain.class);
public static void main(final String[] args) {
- System.setProperty("log4j.skipJansi", "false"); // LOG4J2-2087: explicitly enable
- try (final LoggerContext ctx = Configurator.initialize(
+ try (final LoggerContext ignored = Configurator.initialize(
ConsoleAppenderAnsiMessagesMain.class.getName(), "target/test-classes/log4j2-console-highlight.xml")) {
LOG.fatal("Fatal message.");
LOG.error("Error message.");
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiMessageMain.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiMessageMain.java
deleted file mode 100644
index 56cce35a74b..00000000000
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJAnsiMessageMain.java
+++ /dev/null
@@ -1,84 +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.core.appender;
-
-import static org.fusesource.jansi.Ansi.Color.CYAN;
-import static org.fusesource.jansi.Ansi.Color.RED;
-import static org.fusesource.jansi.Ansi.ansi;
-
-import java.util.Map.Entry;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.LoggerContext;
-import org.apache.logging.log4j.core.config.Configurator;
-import org.apache.logging.log4j.core.test.categories.Layouts;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.jupiter.api.parallel.ResourceLock;
-import org.junit.jupiter.api.parallel.Resources;
-
-/**
- * Shows how to use ANSI escape codes to color messages. Each message is printed to the console in color, but the rest
- * of the log entry (time stamp for example) is in the default color for that console.
- *
- * Running from a Windows command line from the root of the project:
- *
- *
- *
- * mvn -Dtest=org.apache.logging.log4j.core.appender.ConsoleAppenderJAnsiMessageMain test
- *
- *
- * or, on Windows:
- *
- *
- * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes;%USERPROFILE%\.m2\repository\org\fusesource\jansi\jansi\1.14\jansi-1.14.jar; org.apache.logging.log4j.core.appender.ConsoleAppenderJAnsiMessageMain log4j-core/src/test/resources/log4j2-console-msg-ansi.xml
- *
- *
- */
-@Category(Layouts.Jansi.class)
-public class ConsoleAppenderJAnsiMessageMain {
-
- public static void main(final String[] args) {
- new ConsoleAppenderJAnsiMessageMain().test(args);
- }
-
- /**
- * This is a @Test method to make it easy to run from a command line with {@code mvn -Dtest=FQCN test}
- */
- @Test
- @ResourceLock(Resources.SYSTEM_PROPERTIES)
- public void test() {
- test(null);
- }
-
- public void test(final String[] args) {
- System.setProperty("log4j.skipJansi", "false"); // LOG4J2-2087: explicitly enable
- // System.out.println(System.getProperty("java.class.path"));
- final String config =
- args == null || args.length == 0 ? "target/test-classes/log4j2-console-msg-ansi.xml" : args[0];
- try (final LoggerContext ctx =
- Configurator.initialize(ConsoleAppenderAnsiMessagesMain.class.getName(), config)) {
- final Logger logger = LogManager.getLogger(ConsoleAppenderJAnsiMessageMain.class);
- logger.info(ansi().fg(RED).a("Hello").fg(CYAN).a(" World").reset());
- // JAnsi format:
- // logger.info("@|red Hello|@ @|cyan World|@");
- for (final Entry entry : System.getProperties().entrySet()) {
- logger.info("@|KeyStyle {}|@ = @|ValueStyle {}|@", entry.getKey(), entry.getValue());
- }
- }
- }
-}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJira1002ShortThrowableLayoutMain.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJira1002ShortThrowableLayoutMain.java
index b75e3e03259..b1177acdd25 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJira1002ShortThrowableLayoutMain.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderJira1002ShortThrowableLayoutMain.java
@@ -21,7 +21,7 @@
*/
public class ConsoleAppenderJira1002ShortThrowableLayoutMain {
- public static void main(final String[] args) {
- ConsoleAppenderNoAnsiStyleLayoutMain.test(args, "target/test-classes/log4j2-1002.xml");
+ public static void main() {
+ ConsoleAppenderNoAnsiStyleLayoutMain.test("target/test-classes/log4j2-1002.xml");
}
}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderNoAnsiStyleLayoutMain.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderNoAnsiStyleLayoutMain.java
index 1c35103862e..1165fc6a609 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderNoAnsiStyleLayoutMain.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderNoAnsiStyleLayoutMain.java
@@ -30,7 +30,7 @@
*
*
*
- * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes;%HOME%\.m2\repository\org\fusesource\jansi\jansi\1.14\jansi-1.14.jar; org.apache.logging.log4j.core.appender.ConsoleAppenderNoAnsiStyleLayoutMain log4j-core/target/test-classes/log4j2-console-style-ansi.xml
+ * java -classpath log4j-core\target\test-classes;log4j-core\target\classes;log4j-api\target\classes org.apache.logging.log4j.core.appender.ConsoleAppenderNoAnsiStyleLayoutMain log4j-core/target/test-classes/log4j2-console-style-ansi.xml
*
*/
public class ConsoleAppenderNoAnsiStyleLayoutMain {
@@ -43,12 +43,11 @@ private static void logThrowableFromMethod() {
public static void main(final String[] args) {
final String config = args.length == 0 ? "target/test-classes/log4j2-console-style-no-ansi.xml" : args[0];
- test(args, config);
+ test(config);
}
- static void test(final String[] args, final String config) {
- // System.out.println(System.getProperty("java.class.path"));
- try (final LoggerContext ctx =
+ static void test(final String config) {
+ try (final LoggerContext ignored =
Configurator.initialize(ConsoleAppenderNoAnsiStyleLayoutMain.class.getName(), config)) {
LOG.fatal("Fatal message.");
LOG.error("Error message.");
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
index 5eba5acbd73..4e77e0c4331 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
@@ -33,9 +33,7 @@
import org.apache.logging.log4j.core.appender.ConsoleAppender.Target;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.core.layout.PatternLayout;
-import org.apache.logging.log4j.core.test.TestConstants;
import org.apache.logging.log4j.message.SimpleMessage;
-import org.apache.logging.log4j.test.junit.SetTestProperty;
import org.apache.logging.log4j.util.Strings;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -44,7 +42,6 @@
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
-@SetTestProperty(key = TestConstants.CONSOLE_JANSI_ENABLED, value = "false")
public class ConsoleAppenderTest {
ByteArrayOutputStream baos;
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/JansiConsoleAppenderJira965.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/JansiConsoleAppenderJira965.java
deleted file mode 100644
index 8bdd3e13efe..00000000000
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/JansiConsoleAppenderJira965.java
+++ /dev/null
@@ -1,28 +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.core.appender;
-
-import org.slf4j.LoggerFactory;
-
-public class JansiConsoleAppenderJira965 {
-
- public static void main(final String[] args) {
- System.out.println("Able to print on Windows");
- LoggerFactory.getLogger(JansiConsoleAppenderJira965.class);
- System.out.println("Unable to print on Windows");
- }
-}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
index 4719db85637..5323eace0ec 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
@@ -16,26 +16,27 @@
*/
package org.apache.logging.log4j.core.impl;
-import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.apache.logging.log4j.util.Strings.toRootUpperCase;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import org.apache.logging.log4j.core.pattern.JAnsiTextRenderer;
+import org.apache.logging.log4j.core.pattern.AnsiEscape;
+import org.apache.logging.log4j.core.pattern.AnsiTextRenderer;
import org.apache.logging.log4j.core.pattern.TextRenderer;
import org.apache.logging.log4j.util.Strings;
-import org.fusesource.jansi.AnsiRenderer.Code;
import org.junit.jupiter.api.Test;
/**
* Unit tests for {@code ThrowableFormatOptions}.
*/
-public final class ThrowableFormatOptionsTest {
+final class ThrowableFormatOptionsTest {
/**
* Runs a given test comparing against the expected values.
@@ -71,7 +72,7 @@ private static ThrowableFormatOptions test(
* Test {@code %throwable} with null options.
*/
@Test
- public void testNull() {
+ void testNull() {
test(null, Integer.MAX_VALUE, Strings.LINE_SEPARATOR, null);
}
@@ -79,7 +80,7 @@ public void testNull() {
* Test {@code %throwable}
*/
@Test
- public void testEmpty() {
+ void testEmpty() {
test(new String[] {}, Integer.MAX_VALUE, Strings.LINE_SEPARATOR, null);
}
@@ -87,7 +88,7 @@ public void testEmpty() {
* Test {@code %throwable{} } with null option value.
*/
@Test
- public void testOneNullElement() {
+ void testOneNullElement() {
test(new String[] {null}, Integer.MAX_VALUE, Strings.LINE_SEPARATOR, null);
}
@@ -95,7 +96,7 @@ public void testOneNullElement() {
* Test {@code %throwable{} }
*/
@Test
- public void testOneEmptyElement() {
+ void testOneEmptyElement() {
test(new String[] {""}, Integer.MAX_VALUE, Strings.LINE_SEPARATOR, null);
}
@@ -103,7 +104,7 @@ public void testOneEmptyElement() {
* Test {@code %throwable{full} }
*/
@Test
- public void testFull() {
+ void testFull() {
test(new String[] {"full"}, Integer.MAX_VALUE, Strings.LINE_SEPARATOR, null);
}
@@ -111,7 +112,7 @@ public void testFull() {
* Test {@code %throwable{full}{ansi} }
*/
@Test
- public void testFullAnsi() {
+ void testFullAnsi() {
final ThrowableFormatOptions tfo =
test(new String[] {"full", "ansi"}, Integer.MAX_VALUE, Strings.LINE_SEPARATOR, null);
testFullAnsiEmptyConfig(tfo);
@@ -121,7 +122,7 @@ public void testFullAnsi() {
* Test {@code %throwable{full}{ansi()} }
*/
@Test
- public void testFullAnsiEmptyConfig() {
+ void testFullAnsiEmptyConfig() {
final ThrowableFormatOptions tfo =
test(new String[] {"full", "ansi()"}, Integer.MAX_VALUE, Strings.LINE_SEPARATOR, null);
testFullAnsiEmptyConfig(tfo);
@@ -130,34 +131,34 @@ public void testFullAnsiEmptyConfig() {
private void testFullAnsiEmptyConfig(final ThrowableFormatOptions tfo) {
final TextRenderer textRenderer = tfo.getTextRenderer();
assertNotNull(textRenderer);
- assertTrue(textRenderer instanceof JAnsiTextRenderer);
- final JAnsiTextRenderer jansiRenderer = (JAnsiTextRenderer) textRenderer;
- final Map styleMap = jansiRenderer.getStyleMap();
+ assertInstanceOf(AnsiTextRenderer.class, textRenderer);
+ final AnsiTextRenderer ansiRenderer = (AnsiTextRenderer) textRenderer;
+ final Map styleMap = ansiRenderer.getStyleMap();
// We have defaults
assertFalse(styleMap.isEmpty());
- assertNotNull(styleMap.get("Name"));
+ assertNotNull(styleMap.get(toRootUpperCase("Name")));
}
/**
* Test {@code %throwable{full}{ansi(Warning=red))} }
*/
@Test
- public void testFullAnsiWithCustomStyle() {
+ void testFullAnsiWithCustomStyle() {
final ThrowableFormatOptions tfo =
test(new String[] {"full", "ansi(Warning=red)"}, Integer.MAX_VALUE, Strings.LINE_SEPARATOR, null);
final TextRenderer textRenderer = tfo.getTextRenderer();
assertNotNull(textRenderer);
- assertTrue(textRenderer instanceof JAnsiTextRenderer);
- final JAnsiTextRenderer jansiRenderer = (JAnsiTextRenderer) textRenderer;
- final Map styleMap = jansiRenderer.getStyleMap();
- assertArrayEquals(new Code[] {Code.RED}, styleMap.get("Warning"));
+ assertInstanceOf(AnsiTextRenderer.class, textRenderer);
+ final AnsiTextRenderer ansiRenderer = (AnsiTextRenderer) textRenderer;
+ final Map styleMap = ansiRenderer.getStyleMap();
+ assertThat(styleMap.get(toRootUpperCase("Warning"))).isEqualTo(AnsiEscape.createSequence("RED"));
}
/**
* Test {@code %throwable{full}{ansi(Warning=red Key=blue Value=cyan))} }
*/
@Test
- public void testFullAnsiWithCustomStyles() {
+ void testFullAnsiWithCustomStyles() {
final ThrowableFormatOptions tfo = test(
new String[] {"full", "ansi(Warning=red Key=blue Value=cyan)"},
Integer.MAX_VALUE,
@@ -165,19 +166,19 @@ public void testFullAnsiWithCustomStyles() {
null);
final TextRenderer textRenderer = tfo.getTextRenderer();
assertNotNull(textRenderer);
- assertTrue(textRenderer instanceof JAnsiTextRenderer);
- final JAnsiTextRenderer jansiRenderer = (JAnsiTextRenderer) textRenderer;
- final Map styleMap = jansiRenderer.getStyleMap();
- assertArrayEquals(new Code[] {Code.RED}, styleMap.get("Warning"));
- assertArrayEquals(new Code[] {Code.BLUE}, styleMap.get("Key"));
- assertArrayEquals(new Code[] {Code.CYAN}, styleMap.get("Value"));
+ assertInstanceOf(AnsiTextRenderer.class, textRenderer);
+ final AnsiTextRenderer ansiRenderer = (AnsiTextRenderer) textRenderer;
+ final Map styleMap = ansiRenderer.getStyleMap();
+ assertThat(styleMap.get(toRootUpperCase("Warning"))).isEqualTo(AnsiEscape.createSequence("RED"));
+ assertThat(styleMap.get(toRootUpperCase("Key"))).isEqualTo(AnsiEscape.createSequence("BLUE"));
+ assertThat(styleMap.get(toRootUpperCase("Value"))).isEqualTo(AnsiEscape.createSequence("CYAN"));
}
/**
* Test {@code %throwable{full}{ansi(Warning=red Key=blue,bg_red Value=cyan,bg_black,underline)} }
*/
@Test
- public void testFullAnsiWithCustomComplexStyles() {
+ void testFullAnsiWithCustomComplexStyles() {
final ThrowableFormatOptions tfo = test(
new String[] {"full", "ansi(Warning=red Key=blue,bg_red Value=cyan,bg_black,underline)"},
Integer.MAX_VALUE,
@@ -185,19 +186,20 @@ public void testFullAnsiWithCustomComplexStyles() {
null);
final TextRenderer textRenderer = tfo.getTextRenderer();
assertNotNull(textRenderer);
- assertTrue(textRenderer instanceof JAnsiTextRenderer);
- final JAnsiTextRenderer jansiRenderer = (JAnsiTextRenderer) textRenderer;
- final Map styleMap = jansiRenderer.getStyleMap();
- assertArrayEquals(new Code[] {Code.RED}, styleMap.get("Warning"));
- assertArrayEquals(new Code[] {Code.BLUE, Code.BG_RED}, styleMap.get("Key"));
- assertArrayEquals(new Code[] {Code.CYAN, Code.BG_BLACK, Code.UNDERLINE}, styleMap.get("Value"));
+ assertInstanceOf(AnsiTextRenderer.class, textRenderer);
+ final AnsiTextRenderer ansiRenderer = (AnsiTextRenderer) textRenderer;
+ final Map styleMap = ansiRenderer.getStyleMap();
+ assertThat(styleMap.get(toRootUpperCase("Warning"))).isEqualTo(AnsiEscape.createSequence("RED"));
+ assertThat(styleMap.get(toRootUpperCase("Key"))).isEqualTo(AnsiEscape.createSequence("BLUE", "BG_RED"));
+ assertThat(styleMap.get(toRootUpperCase("Value")))
+ .isEqualTo(AnsiEscape.createSequence("CYAN", "BG_BLACK", "UNDERLINE"));
}
/**
* Test {@code %throwable{none} }
*/
@Test
- public void testNone() {
+ void testNone() {
test(new String[] {"none"}, 0, Strings.LINE_SEPARATOR, null);
}
@@ -205,7 +207,7 @@ public void testNone() {
* Test {@code %throwable{short} }
*/
@Test
- public void testShort() {
+ void testShort() {
test(new String[] {"short"}, 2, Strings.LINE_SEPARATOR, null);
}
@@ -213,7 +215,7 @@ public void testShort() {
* Test {@code %throwable{10} }
*/
@Test
- public void testDepth() {
+ void testDepth() {
test(new String[] {"10"}, 10, Strings.LINE_SEPARATOR, null);
}
@@ -221,7 +223,7 @@ public void testDepth() {
* Test {@code %throwable{separator(|)} }
*/
@Test
- public void testSeparator() {
+ void testSeparator() {
test(new String[] {"separator(|)"}, Integer.MAX_VALUE, "|", null);
}
@@ -229,7 +231,7 @@ public void testSeparator() {
* Test {@code %throwable{separator()} }
*/
@Test
- public void testSeparatorAsEmpty() {
+ void testSeparatorAsEmpty() {
test(new String[] {"separator()"}, Integer.MAX_VALUE, Strings.EMPTY, null);
}
@@ -237,7 +239,7 @@ public void testSeparatorAsEmpty() {
* Test {@code %throwable{separator(\n)} }
*/
@Test
- public void testSeparatorAsDefaultLineSeparator() {
+ void testSeparatorAsDefaultLineSeparator() {
test(
new String[] {"separator(" + Strings.LINE_SEPARATOR + ')'},
Integer.MAX_VALUE,
@@ -249,7 +251,7 @@ public void testSeparatorAsDefaultLineSeparator() {
* Test {@code %throwable{separator( | )} }
*/
@Test
- public void testSeparatorAsMultipleCharacters() {
+ void testSeparatorAsMultipleCharacters() {
test(new String[] {"separator( | )"}, Integer.MAX_VALUE, " | ", null);
}
@@ -257,7 +259,7 @@ public void testSeparatorAsMultipleCharacters() {
* Test {@code %throwable{full}{separator(|)} }
*/
@Test
- public void testFullAndSeparator() {
+ void testFullAndSeparator() {
test(new String[] {"full", "separator(|)"}, Integer.MAX_VALUE, "|", null);
}
@@ -265,7 +267,7 @@ public void testFullAndSeparator() {
* Test {@code %throwable{full}{filters(org.junit)}{separator(|)} }
*/
@Test
- public void testFullAndFiltersAndSeparator() {
+ void testFullAndFiltersAndSeparator() {
test(
new String[] {"full", "filters(org.junit)", "separator(|)"},
Integer.MAX_VALUE,
@@ -277,7 +279,7 @@ public void testFullAndFiltersAndSeparator() {
* Test {@code %throwable{none}{separator(|)} }
*/
@Test
- public void testNoneAndSeparator() {
+ void testNoneAndSeparator() {
test(new String[] {"none", "separator(|)"}, 0, "|", null);
}
@@ -285,7 +287,7 @@ public void testNoneAndSeparator() {
* Test {@code %throwable{short}{separator(|)} }
*/
@Test
- public void testShortAndSeparator() {
+ void testShortAndSeparator() {
test(new String[] {"short", "separator(|)"}, 2, "|", null);
}
@@ -293,7 +295,7 @@ public void testShortAndSeparator() {
* Test {@code %throwable{10}{separator(|)} }
*/
@Test
- public void testDepthAndSeparator() {
+ void testDepthAndSeparator() {
test(new String[] {"10", "separator(|)"}, 10, "|", null);
}
@@ -301,7 +303,7 @@ public void testDepthAndSeparator() {
* Test {@code %throwable{filters(packages)} }
*/
@Test
- public void testFilters() {
+ void testFilters() {
test(
new String[] {"filters(packages)"},
Integer.MAX_VALUE,
@@ -313,7 +315,7 @@ public void testFilters() {
* Test {@code %throwable{filters()} }
*/
@Test
- public void testFiltersAsEmpty() {
+ void testFiltersAsEmpty() {
test(new String[] {"filters()"}, Integer.MAX_VALUE, Strings.LINE_SEPARATOR, null);
}
@@ -321,7 +323,7 @@ public void testFiltersAsEmpty() {
* Test {@code %throwable{filters(package1,package2)} }
*/
@Test
- public void testFiltersAsMultiplePackages() {
+ void testFiltersAsMultiplePackages() {
test(
new String[] {"filters(package1,package2)"},
Integer.MAX_VALUE,
@@ -333,7 +335,7 @@ public void testFiltersAsMultiplePackages() {
* Test {@code %throwable{full}{filters(packages)} }
*/
@Test
- public void testFullAndFilters() {
+ void testFullAndFilters() {
test(
new String[] {"full", "filters(packages)"},
Integer.MAX_VALUE,
@@ -345,7 +347,7 @@ public void testFullAndFilters() {
* Test {@code %throwable{none}{filters(packages)} }
*/
@Test
- public void testNoneAndFilters() {
+ void testNoneAndFilters() {
test(
new String[] {"none", "filters(packages)"},
0,
@@ -357,7 +359,7 @@ public void testNoneAndFilters() {
* Test {@code %throwable{short}{filters(packages)} }
*/
@Test
- public void testShortAndFilters() {
+ void testShortAndFilters() {
test(
new String[] {"short", "filters(packages)"},
2,
@@ -369,7 +371,7 @@ public void testShortAndFilters() {
* Test {@code %throwable{10}{filters(packages)} }
*/
@Test
- public void testDepthAndFilters() {
+ void testDepthAndFilters() {
test(
new String[] {"10", "filters(packages)"},
10,
@@ -381,7 +383,7 @@ public void testDepthAndFilters() {
* Test {@code %throwable{full}{separator(|)}{filters(packages)} }
*/
@Test
- public void testFullAndSeparatorAndFilter() {
+ void testFullAndSeparatorAndFilter() {
test(
new String[] {"full", "separator(|)", "filters(packages)"},
Integer.MAX_VALUE,
@@ -393,7 +395,7 @@ public void testFullAndSeparatorAndFilter() {
* Test {@code %throwable{full}{separator(|)}{filters(package1,package2)} }
*/
@Test
- public void testFullAndSeparatorAndFilters() {
+ void testFullAndSeparatorAndFilters() {
test(
new String[] {"full", "separator(|)", "filters(package1,package2)"},
Integer.MAX_VALUE,
@@ -405,7 +407,7 @@ public void testFullAndSeparatorAndFilters() {
* Test {@code %throwable{none}{separator(|)}{filters(packages)} }
*/
@Test
- public void testNoneAndSeparatorAndFilters() {
+ void testNoneAndSeparatorAndFilters() {
test(new String[] {"none", "separator(|)", "filters(packages)"}, 0, "|", Collections.singletonList("packages"));
}
@@ -413,7 +415,7 @@ public void testNoneAndSeparatorAndFilters() {
* Test {@code %throwable{short}{separator(|)}{filters(packages)} }
*/
@Test
- public void testShortAndSeparatorAndFilters() {
+ void testShortAndSeparatorAndFilters() {
test(
new String[] {"short", "separator(|)", "filters(packages)"},
2,
@@ -425,7 +427,7 @@ public void testShortAndSeparatorAndFilters() {
* Test {@code %throwable{10}{separator(|)}{filters(packages)} }
*/
@Test
- public void testDepthAndSeparatorAndFilters() {
+ void testDepthAndSeparatorAndFilters() {
test(new String[] {"10", "separator(|)", "filters(packages)"}, 10, "|", Collections.singletonList("packages"));
}
@@ -433,7 +435,7 @@ public void testDepthAndSeparatorAndFilters() {
* Test {@code %throwable{full,filters(packages)} }
*/
@Test
- public void testSingleOptionFullAndFilters() {
+ void testSingleOptionFullAndFilters() {
test(
new String[] {"full,filters(packages)"},
Integer.MAX_VALUE,
@@ -445,7 +447,7 @@ public void testSingleOptionFullAndFilters() {
* Test {@code %throwable{none,filters(packages)} }
*/
@Test
- public void testSingleOptionNoneAndFilters() {
+ void testSingleOptionNoneAndFilters() {
test(new String[] {"none,filters(packages)"}, 0, Strings.LINE_SEPARATOR, Collections.singletonList("packages"));
}
@@ -453,7 +455,7 @@ public void testSingleOptionNoneAndFilters() {
* Test {@code %throwable{short,filters(packages)} }
*/
@Test
- public void testSingleOptionShortAndFilters() {
+ void testSingleOptionShortAndFilters() {
test(
new String[] {"short,filters(packages)"},
2,
@@ -465,7 +467,7 @@ public void testSingleOptionShortAndFilters() {
* Test {@code %throwable{none,filters(packages)} }
*/
@Test
- public void testSingleOptionDepthAndFilters() {
+ void testSingleOptionDepthAndFilters() {
test(new String[] {"10,filters(packages)"}, 10, Strings.LINE_SEPARATOR, Collections.singletonList("packages"));
}
@@ -473,7 +475,7 @@ public void testSingleOptionDepthAndFilters() {
* Test {@code %throwable{full,filters(package1,package2)} }
*/
@Test
- public void testSingleOptionFullAndMultipleFilters() {
+ void testSingleOptionFullAndMultipleFilters() {
test(
new String[] {"full,filters(package1,package2)"},
Integer.MAX_VALUE,
@@ -485,7 +487,7 @@ public void testSingleOptionFullAndMultipleFilters() {
* Test {@code %throwable{none,filters(package1,package2)} }
*/
@Test
- public void testSingleOptionNoneAndMultipleFilters() {
+ void testSingleOptionNoneAndMultipleFilters() {
test(
new String[] {"none,filters(package1,package2)"},
0,
@@ -497,7 +499,7 @@ public void testSingleOptionNoneAndMultipleFilters() {
* Test {@code %throwable{short,filters(package1,package2)} }
*/
@Test
- public void testSingleOptionShortAndMultipleFilters() {
+ void testSingleOptionShortAndMultipleFilters() {
test(
new String[] {"short,filters(package1,package2)"},
2,
@@ -509,7 +511,7 @@ public void testSingleOptionShortAndMultipleFilters() {
* Test {@code %throwable{none,filters(package1,package2)} }
*/
@Test
- public void testSingleOptionDepthAndMultipleFilters() {
+ void testSingleOptionDepthAndMultipleFilters() {
test(
new String[] {"10,filters(package1,package2)"},
10,
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/AnsiTextRendererTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/AnsiTextRendererTest.java
new file mode 100644
index 00000000000..17e590a86a2
--- /dev/null
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/AnsiTextRendererTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.core.pattern;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.presentation.HexadecimalRepresentation.HEXA_REPRESENTATION;
+
+import java.util.Map;
+import java.util.stream.Stream;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+class AnsiTextRendererTest {
+
+ public static Stream testRendering() {
+ return Stream.of(
+ // Use style names
+ Arguments.of(
+ "KeyStyle=white ValueStyle=cyan,bold",
+ "@|KeyStyle key|@ = @|ValueStyle some value|@",
+ "\u001b[37mkey\u001b[m = \u001b[36;1msome value\u001b[m"),
+ // Use AnsiEscape codes directly
+ Arguments.of(
+ "",
+ "@|white key|@ = @|cyan,bold some value|@",
+ "\u001b[37mkey\u001b[m = \u001b[36;1msome value\u001b[m"),
+ // Return broken escapes as is
+ Arguments.of("", "Hello @|crazy|@ world!", "Hello @|crazy|@ world!"),
+ Arguments.of("", "Hello @|world!", "Hello @|world!"));
+ }
+
+ @ParameterizedTest
+ @MethodSource
+ void testRendering(final String format, final String text, final String expected) {
+ final AnsiTextRenderer renderer = new AnsiTextRenderer(new String[] {"ansi", format}, Map.of());
+ final StringBuilder actual = new StringBuilder();
+ renderer.render(new StringBuilder(text), actual);
+ assertThat(actual.toString())
+ .as("Rendering text '%s'", text)
+ .withRepresentation(HEXA_REPRESENTATION)
+ .isEqualTo(expected);
+ }
+}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageJansiConverterTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageAnsiConverterTest.java
similarity index 94%
rename from log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageJansiConverterTest.java
rename to log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageAnsiConverterTest.java
index 293db30ba99..670fefd097f 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageJansiConverterTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageAnsiConverterTest.java
@@ -31,7 +31,7 @@
import org.junit.jupiter.api.Test;
@LoggerContextSource("log4j-message-ansi.xml")
-public class MessageJansiConverterTest {
+public class MessageAnsiConverterTest {
private static final String EXPECTED =
"\u001B[31;1mWarning!\u001B[m Pants on \u001B[31mfire!\u001B[m" + Strings.LINE_SEPARATOR;
@@ -47,7 +47,7 @@ public void setUp(final LoggerContext context, @Named("List") final ListAppender
@Test
public void testReplacement() {
- // See org.fusesource.jansi.AnsiRenderer
+ // See https://www.javadoc.io/doc/org.jline/jline/latest/org/jline/jansi/AnsiRenderer.html
logger.error("@|red,bold Warning!|@ Pants on @|red fire!|@");
final List msgs = app.getMessages();
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageStyledConverterTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageStyledConverterTest.java
index 71fb6fbc77b..06ab681fedd 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageStyledConverterTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageStyledConverterTest.java
@@ -47,7 +47,7 @@ public void setUp(final LoggerContext context, @Named("List") final ListAppender
@Test
public void testReplacement() {
- // See org.fusesource.jansi.AnsiRenderer
+ // See https://www.javadoc.io/doc/org.jline/jline/latest/org/jline/jansi/AnsiRenderer.html
logger.error("@|WarningStyle Warning!|@ Pants on @|WarningStyle fire!|@");
final List msgs = app.getMessages();
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/StyleConverterTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/StyleConverterTest.java
index 6a5a77951fa..01b3f51d306 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/StyleConverterTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/StyleConverterTest.java
@@ -26,19 +26,16 @@
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.core.test.TestConstants;
import org.apache.logging.log4j.core.test.appender.ListAppender;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
import org.apache.logging.log4j.core.test.junit.Named;
import org.apache.logging.log4j.test.ListStatusListener;
-import org.apache.logging.log4j.test.junit.SetTestProperty;
import org.apache.logging.log4j.test.junit.UsingStatusListener;
import org.apache.logging.log4j.util.Strings;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
-@SetTestProperty(key = TestConstants.CONSOLE_JANSI_ENABLED, value = "true")
public class StyleConverterTest {
private static final String EXPECTED =
diff --git a/log4j-core-test/src/test/resources/log4j2-console-msg-ansi.xml b/log4j-core-test/src/test/resources/log4j2-console-msg-ansi.xml
deleted file mode 100644
index d30b0fb406b..00000000000
--- a/log4j-core-test/src/test/resources/log4j2-console-msg-ansi.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
index 0062f543ff6..b2b00b30d82 100644
--- a/log4j-core/pom.xml
+++ b/log4j-core/pom.xml
@@ -43,10 +43,8 @@
org.jspecify.*;resolution:=optional,
-
- org.fusesource.jansi;resolution:=optional,
-
+
java.lang.management;resolution:=optional,
javax.management.*;resolution:=optional,
@@ -64,7 +62,6 @@
java.sql;transitive=false,
java.xml;transitive=false,
jdk.unsupported;transitive=false,
- org.fusesource.jansi;transitive=false,
org.jspecify;transitive=false
@@ -101,13 +98,6 @@
log4j-plugins
-
-
- org.fusesource.jansi
- jansi
- true
-
-
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
index 5077bba5ed7..4e6dbb47ae0 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
@@ -20,29 +20,19 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
-import java.io.PrintStream;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Constructor;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
-import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.Property;
-import org.apache.logging.log4j.core.impl.CoreProperties.ConsoleProperties;
import org.apache.logging.log4j.core.util.CloseShieldOutputStream;
-import org.apache.logging.log4j.core.util.Loader;
-import org.apache.logging.log4j.core.util.Throwables;
-import org.apache.logging.log4j.kit.env.PropertyEnvironment;
import org.apache.logging.log4j.plugins.Configurable;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.plugins.PluginFactory;
import org.apache.logging.log4j.plugins.validation.constraints.Required;
-import org.apache.logging.log4j.util.Chars;
-import org.apache.logging.log4j.util.PropertiesUtil;
/**
* Appends log events to System.out
or System.err
using a layout specified by the user. The
@@ -59,7 +49,6 @@
public final class ConsoleAppender extends AbstractOutputStreamAppender {
public static final String PLUGIN_NAME = "Console";
- private static final String JANSI_CLASS = "org.fusesource.jansi.WindowsAnsiOutputStream";
private static final ConsoleManagerFactory factory = new ConsoleManagerFactory();
private static final Target DEFAULT_TARGET = Target.SYSTEM_OUT;
private static final AtomicInteger COUNT = new AtomicInteger();
@@ -127,7 +116,7 @@ public static ConsoleAppender createDefaultAppenderForLayout(final Layout layout
"DefaultConsole-" + COUNT.incrementAndGet(),
layout,
null,
- getDefaultManager(DEFAULT_TARGET, false, false, layout),
+ getDefaultManager(layout),
true,
DEFAULT_TARGET,
null);
@@ -172,91 +161,43 @@ public B setDirect(final boolean shouldDirect) {
@Override
public ConsoleAppender build() {
- if (follow && direct) {
- throw new IllegalArgumentException(
- "Cannot use both follow and direct on ConsoleAppender '" + getName() + "'");
+ if (direct && follow) {
+ LOGGER.error("Cannot use both `direct` and `follow` on ConsoleAppender.");
+ return null;
}
final Layout layout = getOrCreateLayout(target.getDefaultCharset());
- final Configuration configuration = getConfiguration();
- final PropertyEnvironment propertyEnvironment =
- configuration != null && configuration.getLoggerContext() != null
- ? configuration.getLoggerContext().getEnvironment()
- : PropertyEnvironment.getGlobal();
+
+ OutputStream stream = direct
+ ? getDirectOutputStream(target)
+ : follow ? getFollowOutputStream(target) : getDefaultOutputStream(target);
+
+ final String managerName = target.name() + '.' + follow + '.' + direct;
+ final OutputStreamManager manager =
+ OutputStreamManager.getManager(managerName, new FactoryData(stream, managerName, layout), factory);
return new ConsoleAppender(
- getName(),
- layout,
- getFilter(),
- getManager(target, follow, direct, layout, propertyEnvironment),
- isIgnoreExceptions(),
- target,
- getPropertyArray());
+ getName(), layout, getFilter(), manager, isIgnoreExceptions(), target, getPropertyArray());
}
}
- private static OutputStreamManager getDefaultManager(
- final Target target, final boolean follow, final boolean direct, final Layout layout) {
- final OutputStream os = getOutputStream(follow, direct, target, PropertyEnvironment.getGlobal());
-
+ private static OutputStreamManager getDefaultManager(final Layout layout) {
+ final OutputStream os = new CloseShieldOutputStream(
+ ConsoleAppender.DEFAULT_TARGET == Target.SYSTEM_ERR ? System.err : System.out);
// LOG4J2-1176 DefaultConfiguration should not share OutputStreamManager instances to avoid memory leaks.
- final String managerName = target.name() + '.' + follow + '.' + direct + "-" + COUNT.get();
+ final String managerName = ConsoleAppender.DEFAULT_TARGET.name() + ".false.false-" + COUNT.get();
return OutputStreamManager.getManager(managerName, new FactoryData(os, managerName, layout), factory);
}
- private static OutputStreamManager getManager(
- final Target target,
- final boolean follow,
- final boolean direct,
- final Layout layout,
- final PropertyEnvironment properties) {
- final OutputStream os = getOutputStream(follow, direct, target, properties);
- final String managerName = target.name() + '.' + follow + '.' + direct;
- return OutputStreamManager.getManager(managerName, new FactoryData(os, managerName, layout), factory);
+ private static OutputStream getDefaultOutputStream(Target target) {
+ return new CloseShieldOutputStream(target == Target.SYSTEM_OUT ? System.out : System.err);
}
- private static OutputStream getOutputStream(
- final boolean follow, final boolean direct, final Target target, final PropertyEnvironment properties) {
- final String enc = Charset.defaultCharset().name();
- OutputStream outputStream;
- try {
- // @formatter:off
- outputStream = target == Target.SYSTEM_OUT
- ? direct
- ? new FileOutputStream(FileDescriptor.out)
- : (follow ? new PrintStream(new SystemOutStream(), true, enc) : System.out)
- : direct
- ? new FileOutputStream(FileDescriptor.err)
- : (follow ? new PrintStream(new SystemErrStream(), true, enc) : System.err);
- // @formatter:on
- outputStream = new CloseShieldOutputStream(outputStream);
- } catch (final UnsupportedEncodingException ex) { // should never happen
- throw new IllegalStateException("Unsupported default encoding " + enc, ex);
- }
- if (!PropertiesUtil.getProperties().isOsWindows()
- || !Boolean.FALSE.equals(
- properties.getProperty(ConsoleProperties.class).jansiEnabled())
- || direct) {
- return outputStream;
- }
- try {
- // We type the parameter as a wildcard to avoid a hard reference to Jansi.
- final Class> clazz = Loader.loadClass(JANSI_CLASS);
- final Constructor> constructor = clazz.getConstructor(OutputStream.class);
- return new CloseShieldOutputStream((OutputStream) constructor.newInstance(outputStream));
- } catch (final ClassNotFoundException cnfe) {
- LOGGER.debug("Jansi is not installed, cannot find {}", JANSI_CLASS);
- } catch (final NoSuchMethodException nsme) {
- LOGGER.warn("{} is missing the proper constructor", JANSI_CLASS);
- } catch (final Exception ex) {
- LOGGER.warn(
- "Unable to instantiate {} due to {}",
- JANSI_CLASS,
- clean(Throwables.getRootCause(ex).toString()).trim());
- }
- return outputStream;
+ private static OutputStream getDirectOutputStream(Target target) {
+ return new CloseShieldOutputStream(
+ new FileOutputStream(target == Target.SYSTEM_OUT ? FileDescriptor.out : FileDescriptor.err));
}
- private static String clean(final String string) {
- return string.replace(Chars.NUL, Chars.SPACE);
+ private static OutputStream getFollowOutputStream(Target target) {
+ return target == Target.SYSTEM_OUT ? new SystemOutStream() : new SystemErrStream();
}
/**
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/CoreProperties.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/CoreProperties.java
index 27188eba778..82abc8733a1 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/CoreProperties.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/CoreProperties.java
@@ -107,12 +107,6 @@ public record ConfigurationProperties(
boolean usePreciseClock,
@Log4jProperty(defaultValue = "5000") long waitMillisBeforeStopOldConfig) {}
- /**
- * Properties to tune console output.
- */
- @Log4jProperty(name = "console")
- public record ConsoleProperties(@Nullable Boolean jansiEnabled) {}
-
/**
* Properties to tune garbage collection.
*/
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
index 832f7646e09..07a5d4ab249 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
@@ -19,12 +19,10 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
-import org.apache.logging.log4j.core.pattern.JAnsiTextRenderer;
+import org.apache.logging.log4j.core.pattern.AnsiTextRenderer;
import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
import org.apache.logging.log4j.core.pattern.TextRenderer;
-import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.core.util.Patterns;
-import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.Strings;
/**
@@ -289,17 +287,11 @@ public static ThrowableFormatOptions newInstance(String[] options) {
|| option.equalsIgnoreCase(LOCALIZED_MESSAGE)) {
lines = 2;
} else if (option.startsWith("ansi(") && option.endsWith(")") || option.equals("ansi")) {
- if (Loader.isJansiAvailable()) {
- final String styleMapStr = option.equals("ansi")
- ? Strings.EMPTY
- : option.substring("ansi(".length(), option.length() - 1);
- ansiRenderer = new JAnsiTextRenderer(
- new String[] {null, styleMapStr}, JAnsiTextRenderer.DefaultExceptionStyleMap);
- } else {
- StatusLogger.getLogger()
- .warn(
- "You requested ANSI exception rendering but JANSI is not on the classpath. Please see https://logging.apache.org/log4j/2.x/runtime-dependencies.html");
- }
+ final String styleMapStr = option.equals("ansi")
+ ? Strings.EMPTY
+ : option.substring("ansi(".length(), option.length() - 1);
+ ansiRenderer = new AnsiTextRenderer(
+ new String[] {null, styleMapStr}, AnsiTextRenderer.DEFAULT_EXCEPTION_STYLE_MAP);
} else if (option.startsWith("S(") && option.endsWith(")")) {
suffix = option.substring("S(".length(), option.length() - 1);
} else if (option.startsWith("suffix(") && option.endsWith(")")) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
index 24ce2d345a5..b9b3f9f7dc9 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
@@ -16,8 +16,6 @@
*/
package org.apache.logging.log4j.core.layout;
-import static java.lang.Boolean.TRUE;
-
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
@@ -27,20 +25,17 @@
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
-import org.apache.logging.log4j.core.impl.CoreProperties;
import org.apache.logging.log4j.core.pattern.FormattingInfo;
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
import org.apache.logging.log4j.core.pattern.PatternFormatter;
import org.apache.logging.log4j.core.pattern.PatternParser;
import org.apache.logging.log4j.core.pattern.RegexReplacement;
-import org.apache.logging.log4j.kit.env.PropertyEnvironment;
import org.apache.logging.log4j.kit.recycler.Recycler;
import org.apache.logging.log4j.plugins.Configurable;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.plugins.PluginElement;
import org.apache.logging.log4j.plugins.PluginFactory;
-import org.apache.logging.log4j.util.PropertiesUtil;
import org.apache.logging.log4j.util.Strings;
/**
@@ -577,7 +572,7 @@ public static class Builder implements org.apache.logging.log4j.plugins.util.Bui
private boolean alwaysWriteExceptions = true;
@PluginBuilderAttribute
- private boolean disableAnsi = !useAnsiEscapeCodes();
+ private boolean disableAnsi;
@PluginBuilderAttribute
private boolean noConsoleNoAnsi;
@@ -590,16 +585,6 @@ public static class Builder implements org.apache.logging.log4j.plugins.util.Bui
private Builder() {}
- private boolean useAnsiEscapeCodes() {
- final PropertyEnvironment properties = PropertyEnvironment.getGlobal();
- final boolean isPlatformSupportsAnsi =
- !PropertiesUtil.getProperties().isOsWindows();
- final boolean isJansiRequested = TRUE.equals(PropertyEnvironment.getGlobal()
- .getProperty(CoreProperties.ConsoleProperties.class)
- .jansiEnabled());
- return isPlatformSupportsAnsi || isJansiRequested;
- }
-
/**
* @param pattern
* The pattern. If not specified, defaults to DEFAULT_CONVERSION_PATTERN.
@@ -659,8 +644,7 @@ public Builder setAlwaysWriteExceptions(final boolean alwaysWriteExceptions) {
/**
* @param disableAnsi
- * If {@code "true"} (default is value of system property `log4j.skipJansi`, or `true` if undefined),
- * do not output ANSI escape codes
+ * If {@code true}, do not output ANSI escape codes.
*/
public Builder setDisableAnsi(final boolean disableAnsi) {
this.disableAnsi = disableAnsi;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiEscape.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiEscape.java
index be655ca0fe4..d51d5e7c824 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiEscape.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiEscape.java
@@ -420,6 +420,11 @@ public static Map createMap(final String values, final String[]
* @return a new map
*/
public static Map createMap(final String[] values, final String[] dontEscapeKeys) {
+ return createMap(values, dontEscapeKeys, "\\s");
+ }
+
+ static Map createMap(
+ final String[] values, final String[] dontEscapeKeys, final String separatorRegex) {
final String[] sortedIgnoreKeys = dontEscapeKeys != null ? dontEscapeKeys.clone() : Strings.EMPTY_ARRAY;
Arrays.sort(sortedIgnoreKeys);
final Map map = new HashMap<>();
@@ -429,7 +434,7 @@ public static Map createMap(final String[] values, final String[
final String key = toRootUpperCase(keyValue[0]);
final String value = keyValue[1];
final boolean escape = Arrays.binarySearch(sortedIgnoreKeys, key) < 0;
- map.put(key, escape ? createSequence(value.split("\\s")) : value);
+ map.put(key, escape ? createSequence(value.split(separatorRegex)) : value);
}
}
return map;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiTextRenderer.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiTextRenderer.java
new file mode 100644
index 00000000000..84382815b5e
--- /dev/null
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiTextRenderer.java
@@ -0,0 +1,294 @@
+/*
+ * 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.core.pattern;
+
+import static org.apache.logging.log4j.core.pattern.AnsiEscape.BG_RED;
+import static org.apache.logging.log4j.core.pattern.AnsiEscape.BOLD;
+import static org.apache.logging.log4j.core.pattern.AnsiEscape.RED;
+import static org.apache.logging.log4j.core.pattern.AnsiEscape.WHITE;
+import static org.apache.logging.log4j.core.pattern.AnsiEscape.YELLOW;
+import static org.apache.logging.log4j.util.Strings.toRootUpperCase;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.status.StatusLogger;
+
+/**
+ * Renders an input as ANSI escaped output.
+ *
+ * Uses the
+ * JLine AnsiRenderer syntax
+ * to render a message into an ANSI escaped string.
+ *
+ *
+ * The default syntax for embedded ANSI codes is:
+ *
+ *
+ * @|code (,code )* text |@
+ *
+ *
+ * For example, to render the message {@code "Hello"} in green, use:
+ *
+ *
+ * @|green Hello|@
+ *
+ *
+ * To render the message {@code "Hello"} in bold and red, use:
+ *
+ *
+ * @|bold,red Warning!|@
+ *
+ *
+ * You can also define custom style names in the configuration with the syntax:
+ *
+ *
+ * %message{ansi}{StyleName=value(,value)*( StyleName=value(,value)*)*}%n
+ *
+ *
+ * For example:
+ *
+ *
+ * %message{ansi}{WarningStyle=red,bold KeyStyle=white ValueStyle=blue}%n
+ *
+ *
+ * The call site can look like this:
+ *
+ *
+ * logger.info("@|KeyStyle {}|@ = @|ValueStyle {}|@", entry.getKey(), entry.getValue());
+ *
+ *
+ *
+ * Note: this class was originally copied and then heavily modified from
+ * JAnsi/JLine AnsiRenderer ,
+ * licensed under an Apache Software License, version 2.0.
+ *
+ */
+public final class AnsiTextRenderer implements TextRenderer {
+
+ private static final Logger LOGGER = StatusLogger.getLogger();
+
+ public static final Map DEFAULT_EXCEPTION_STYLE_MAP;
+ static final Map DEFAULT_MESSAGE_STYLE_MAP;
+ private static final Map> PREFEDINED_STYLE_MAPS;
+
+ private static final String BEGIN_TOKEN = "@|";
+ private static final String END_TOKEN = "|@";
+ // The length of AnsiEscape.CSI
+ private static final int CSI_LENGTH = 2;
+
+ private static Map.Entry entry(final String name, final AnsiEscape... codes) {
+ final StringBuilder sb = new StringBuilder(AnsiEscape.CSI.getCode());
+ for (final AnsiEscape code : codes) {
+ sb.append(code.getCode());
+ }
+ return Map.entry(name, sb.toString());
+ }
+
+ static {
+ // Default style: Spock
+ final Map spock = Map.ofEntries(
+ entry("Prefix", WHITE),
+ entry("Name", BG_RED, WHITE),
+ entry("NameMessageSeparator", BG_RED, WHITE),
+ entry("Message", BG_RED, WHITE, BOLD),
+ entry("At", WHITE),
+ entry("CauseLabel", WHITE),
+ entry("Text", WHITE),
+ entry("More", WHITE),
+ entry("Suppressed", WHITE),
+ // StackTraceElement
+ entry("StackTraceElement.ClassName", YELLOW),
+ entry("StackTraceElement.ClassMethodSeparator", YELLOW),
+ entry("StackTraceElement.MethodName", YELLOW),
+ entry("StackTraceElement.NativeMethod", YELLOW),
+ entry("StackTraceElement.FileName", RED),
+ entry("StackTraceElement.LineNumber", RED),
+ entry("StackTraceElement.Container", RED),
+ entry("StackTraceElement.ContainerSeparator", WHITE),
+ entry("StackTraceElement.UnknownSource", RED),
+ // ExtraClassInfo
+ entry("ExtraClassInfo.Inexact", YELLOW),
+ entry("ExtraClassInfo.Container", YELLOW),
+ entry("ExtraClassInfo.ContainerSeparator", YELLOW),
+ entry("ExtraClassInfo.Location", YELLOW),
+ entry("ExtraClassInfo.Version", YELLOW));
+
+ // Style: Kirk
+ final Map kirk = Map.ofEntries(
+ entry("Prefix", WHITE),
+ entry("Name", BG_RED, YELLOW, BOLD),
+ entry("NameMessageSeparator", BG_RED, YELLOW),
+ entry("Message", BG_RED, WHITE, BOLD),
+ entry("At", WHITE),
+ entry("CauseLabel", WHITE),
+ entry("Text", WHITE),
+ entry("More", WHITE),
+ entry("Suppressed", WHITE),
+ // StackTraceElement
+ entry("StackTraceElement.ClassName", BG_RED, WHITE),
+ entry("StackTraceElement.ClassMethodSeparator", BG_RED, YELLOW),
+ entry("StackTraceElement.MethodName", BG_RED, YELLOW),
+ entry("StackTraceElement.NativeMethod", BG_RED, YELLOW),
+ entry("StackTraceElement.FileName", RED),
+ entry("StackTraceElement.LineNumber", RED),
+ entry("StackTraceElement.Container", RED),
+ entry("StackTraceElement.ContainerSeparator", WHITE),
+ entry("StackTraceElement.UnknownSource", RED),
+ // ExtraClassInfo
+ entry("ExtraClassInfo.Inexact", YELLOW),
+ entry("ExtraClassInfo.Container", WHITE),
+ entry("ExtraClassInfo.ContainerSeparator", WHITE),
+ entry("ExtraClassInfo.Location", YELLOW),
+ entry("ExtraClassInfo.Version", YELLOW));
+
+ // Save
+ DEFAULT_EXCEPTION_STYLE_MAP = spock;
+ DEFAULT_MESSAGE_STYLE_MAP = Map.of();
+ PREFEDINED_STYLE_MAPS = Map.of("Spock", spock, "Kirk", kirk);
+ }
+
+ private final String beginToken;
+ private final int beginTokenLen;
+ private final String endToken;
+ private final int endTokenLen;
+ private final Map styleMap;
+
+ public AnsiTextRenderer(final String[] formats, final Map defaultStyleMap) {
+ // The format string is a list of whitespace-separated expressions:
+ // Key=AnsiEscape(,AnsiEscape)*
+ if (formats.length > 1) {
+ final String stylesStr = formats[1];
+ final Map map = AnsiEscape.createMap(
+ stylesStr.split("\\s", -1), new String[] {"BeginToken", "EndToken", "Style"}, ",");
+
+ // Handle the special tokens
+ beginToken = Objects.toString(map.remove("BeginToken"), BEGIN_TOKEN);
+ endToken = Objects.toString(map.remove("EndToken"), END_TOKEN);
+ final String predefinedStyle = map.remove("Style");
+
+ // Create style map
+ final Map styleMap = new HashMap<>(map.size() + defaultStyleMap.size());
+ defaultStyleMap.forEach((k, v) -> styleMap.put(toRootUpperCase(k), v));
+ if (predefinedStyle != null) {
+ final Map predefinedMap = PREFEDINED_STYLE_MAPS.get(predefinedStyle);
+ if (predefinedMap != null) {
+ map.putAll(predefinedMap);
+ } else {
+ LOGGER.warn(
+ "Unknown predefined map name {}, pick one of {}",
+ predefinedStyle,
+ PREFEDINED_STYLE_MAPS.keySet());
+ }
+ }
+ styleMap.putAll(map);
+ this.styleMap = Collections.unmodifiableMap(styleMap);
+ } else {
+ beginToken = BEGIN_TOKEN;
+ endToken = END_TOKEN;
+ this.styleMap = Collections.unmodifiableMap(defaultStyleMap);
+ }
+ beginTokenLen = beginToken.length();
+ endTokenLen = endToken.length();
+ }
+
+ /**
+ * Renders the given input with the given names which can be ANSI code names or Log4j style names.
+ *
+ * @param input
+ * The input to render
+ * @param styleNames
+ * ANSI code names or Log4j style names.
+ */
+ private void render(final String input, final StringBuilder output, final String... styleNames) {
+ boolean first = true;
+ for (final String styleName : styleNames) {
+ final String escape = styleMap.get(toRootUpperCase(styleName));
+ if (escape != null) {
+ merge(escape, output, first);
+ } else {
+ merge(AnsiEscape.createSequence(styleName), output, first);
+ }
+ first = false;
+ }
+ output.append(input).append(AnsiEscape.getDefaultStyle());
+ }
+
+ private static void merge(final String escapeSequence, final StringBuilder output, final boolean first) {
+ if (first) {
+ output.append(escapeSequence);
+ } else {
+ // Delete the trailing AnsiEscape.SUFFIX
+ output.setLength(output.length() - 1);
+ output.append(AnsiEscape.SEPARATOR.getCode());
+ output.append(escapeSequence.substring(CSI_LENGTH));
+ }
+ }
+
+ // EXACT COPY OF StringBuilder version of the method but typed as String for input
+ @Override
+ public void render(final String input, final StringBuilder output, final String styleName)
+ throws IllegalArgumentException {
+ render(input, output, styleName.split(",", -1));
+ }
+
+ @Override
+ public void render(final StringBuilder input, final StringBuilder output) throws IllegalArgumentException {
+ int pos = 0;
+ int beginTokenPos, endTokenPos;
+
+ while (true) {
+ beginTokenPos = input.indexOf(beginToken, pos);
+ if (beginTokenPos == -1) {
+ output.append(pos == 0 ? input : input.substring(pos, input.length()));
+ return;
+ }
+ output.append(input.substring(pos, beginTokenPos));
+ endTokenPos = input.indexOf(endToken, beginTokenPos);
+
+ if (endTokenPos == -1) {
+ LOGGER.warn(
+ "Missing matching end token {} for token at position {}: '{}'", endToken, beginTokenPos, input);
+ output.append(beginTokenPos == 0 ? input : input.substring(beginTokenPos, input.length()));
+ return;
+ }
+ beginTokenPos += beginTokenLen;
+ final String spec = input.substring(beginTokenPos, endTokenPos);
+
+ final String[] items = spec.split("\\s", 2);
+ if (items.length == 1) {
+ LOGGER.warn("Missing argument in ANSI escape specification '{}'", spec);
+ output.append(beginToken).append(spec).append(endToken);
+ } else {
+ render(items[1], output, items[0].split(",", -1));
+ }
+ pos = endTokenPos + endTokenLen;
+ }
+ }
+
+ public Map getStyleMap() {
+ return styleMap;
+ }
+
+ @Override
+ public String toString() {
+ return "AnsiMessageRenderer [beginToken=" + beginToken + ", beginTokenLen=" + beginTokenLen + ", endToken="
+ + endToken + ", endTokenLen=" + endTokenLen + ", styleMap=" + styleMap + "]";
+ }
+}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/JAnsiTextRenderer.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/JAnsiTextRenderer.java
deleted file mode 100644
index 58d4afa46cd..00000000000
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/JAnsiTextRenderer.java
+++ /dev/null
@@ -1,338 +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.core.pattern;
-
-import static org.apache.logging.log4j.util.Strings.toRootUpperCase;
-import static org.fusesource.jansi.AnsiRenderer.Code.BG_RED;
-import static org.fusesource.jansi.AnsiRenderer.Code.BOLD;
-import static org.fusesource.jansi.AnsiRenderer.Code.RED;
-import static org.fusesource.jansi.AnsiRenderer.Code.WHITE;
-import static org.fusesource.jansi.AnsiRenderer.Code.YELLOW;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.fusesource.jansi.Ansi;
-import org.fusesource.jansi.AnsiRenderer;
-import org.fusesource.jansi.AnsiRenderer.Code;
-
-/**
- * Renders an input as ANSI escaped output.
- *
- * Uses the JAnsi rendering syntax as the default to render a message into an ANSI escaped string.
- *
- * The default syntax for embedded ANSI codes is:
- *
- *
- * @|code (,code )* text |@
- *
- *
- * For example, to render the message {@code "Hello"} in green, use:
- *
- *
- * @|green Hello|@
- *
- *
- * To render the message {@code "Hello"} in bold and red, use:
- *
- *
- * @|bold,red Warning!|@
- *
- *
- * You can also define custom style names in the configuration with the syntax:
- *
- *
- * %message{ansi}{StyleName=value(,value)*( StyleName=value(,value)*)*}%n
- *
- *
- * For example:
- *
- *
- * %message{ansi}{WarningStyle=red,bold KeyStyle=white ValueStyle=blue}%n
- *
- *
- * The call site can look like this:
- *
- *
- * logger.info("@|KeyStyle {}|@ = @|ValueStyle {}|@", entry.getKey(), entry.getValue());
- *
- *
- * Note: This class originally copied and then heavily modified code from JAnsi's AnsiRenderer (which is licensed as
- * Apache 2.0.)
- *
- * @see AnsiRenderer
- */
-public final class JAnsiTextRenderer implements TextRenderer {
-
- public static final Map DefaultExceptionStyleMap;
- static final Map DefaultMessageStyleMap;
- private static final Map> PrefedinedStyleMaps;
-
- private static void put(final Map map, final String name, final Code... codes) {
- map.put(name, codes);
- }
-
- static {
- final Map> tempPreDefs = new HashMap<>();
- // Default style: Spock
- {
- // TODO Should the keys be in an enum?
- final Map map = new HashMap<>();
- put(map, "Prefix", WHITE);
- put(map, "Name", BG_RED, WHITE);
- put(map, "NameMessageSeparator", BG_RED, WHITE);
- put(map, "Message", BG_RED, WHITE, BOLD);
- put(map, "At", WHITE);
- put(map, "CauseLabel", WHITE);
- put(map, "Text", WHITE);
- put(map, "More", WHITE);
- put(map, "Suppressed", WHITE);
- // StackTraceElement
- put(map, "StackTraceElement.ClassName", YELLOW);
- put(map, "StackTraceElement.ClassMethodSeparator", YELLOW);
- put(map, "StackTraceElement.MethodName", YELLOW);
- put(map, "StackTraceElement.NativeMethod", YELLOW);
- put(map, "StackTraceElement.FileName", RED);
- put(map, "StackTraceElement.LineNumber", RED);
- put(map, "StackTraceElement.Container", RED);
- put(map, "StackTraceElement.ContainerSeparator", WHITE);
- put(map, "StackTraceElement.UnknownSource", RED);
- // ExtraClassInfo
- put(map, "ExtraClassInfo.Inexact", YELLOW);
- put(map, "ExtraClassInfo.Container", YELLOW);
- put(map, "ExtraClassInfo.ContainerSeparator", YELLOW);
- put(map, "ExtraClassInfo.Location", YELLOW);
- put(map, "ExtraClassInfo.Version", YELLOW);
- // Save
- DefaultExceptionStyleMap = Collections.unmodifiableMap(map);
- tempPreDefs.put("Spock", DefaultExceptionStyleMap);
- }
- // Style: Kirk
- {
- // TODO Should the keys be in an enum?
- final Map map = new HashMap<>();
- put(map, "Prefix", WHITE);
- put(map, "Name", BG_RED, YELLOW, BOLD);
- put(map, "NameMessageSeparator", BG_RED, YELLOW);
- put(map, "Message", BG_RED, WHITE, BOLD);
- put(map, "At", WHITE);
- put(map, "CauseLabel", WHITE);
- put(map, "Text", WHITE);
- put(map, "More", WHITE);
- put(map, "Suppressed", WHITE);
- // StackTraceElement
- put(map, "StackTraceElement.ClassName", BG_RED, WHITE);
- put(map, "StackTraceElement.ClassMethodSeparator", BG_RED, YELLOW);
- put(map, "StackTraceElement.MethodName", BG_RED, YELLOW);
- put(map, "StackTraceElement.NativeMethod", BG_RED, YELLOW);
- put(map, "StackTraceElement.FileName", RED);
- put(map, "StackTraceElement.LineNumber", RED);
- put(map, "StackTraceElement.Container", RED);
- put(map, "StackTraceElement.ContainerSeparator", WHITE);
- put(map, "StackTraceElement.UnknownSource", RED);
- // ExtraClassInfo
- put(map, "ExtraClassInfo.Inexact", YELLOW);
- put(map, "ExtraClassInfo.Container", WHITE);
- put(map, "ExtraClassInfo.ContainerSeparator", WHITE);
- put(map, "ExtraClassInfo.Location", YELLOW);
- put(map, "ExtraClassInfo.Version", YELLOW);
- // Save
- tempPreDefs.put("Kirk", Collections.unmodifiableMap(map));
- }
- {
- final Map temp = new HashMap<>();
- // TODO
- DefaultMessageStyleMap = Collections.unmodifiableMap(temp);
- }
- PrefedinedStyleMaps = Collections.unmodifiableMap(tempPreDefs);
- }
-
- private final String beginToken;
- private final int beginTokenLen;
- private final String endToken;
- private final int endTokenLen;
- private final Map styleMap;
-
- public JAnsiTextRenderer(final String[] formats, final Map defaultStyleMap) {
- String tempBeginToken = AnsiRenderer.BEGIN_TOKEN;
- String tempEndToken = AnsiRenderer.END_TOKEN;
- final Map map;
- if (formats.length > 1) {
- final String allStylesStr = formats[1];
- // Style def split
- final String[] allStyleAssignmentsArr = allStylesStr.split(" ");
- map = new HashMap<>(allStyleAssignmentsArr.length + defaultStyleMap.size());
- map.putAll(defaultStyleMap);
- for (final String styleAssignmentStr : allStyleAssignmentsArr) {
- final String[] styleAssignmentArr = styleAssignmentStr.split("=");
- if (styleAssignmentArr.length != 2) {
- StatusLogger.getLogger()
- .warn(
- "{} parsing style \"{}\", expected format: StyleName=Code(,Code)*",
- getClass().getSimpleName(),
- styleAssignmentStr);
- } else {
- final String styleName = styleAssignmentArr[0];
- final String codeListStr = styleAssignmentArr[1];
- final String[] codeNames = codeListStr.split(",");
- if (codeNames.length == 0) {
- StatusLogger.getLogger()
- .warn(
- "{} parsing style \"{}\", expected format: StyleName=Code(,Code)*",
- getClass().getSimpleName(),
- styleAssignmentStr);
- } else {
- switch (styleName) {
- case "BeginToken":
- tempBeginToken = codeNames[0];
- break;
- case "EndToken":
- tempEndToken = codeNames[0];
- break;
- case "StyleMapName":
- final String predefinedMapName = codeNames[0];
- final Map predefinedMap = PrefedinedStyleMaps.get(predefinedMapName);
- if (predefinedMap != null) {
- map.putAll(predefinedMap);
- } else {
- StatusLogger.getLogger()
- .warn(
- "Unknown predefined map name {}, pick one of {}",
- predefinedMapName,
- null);
- }
- break;
- default:
- final Code[] codes = new Code[codeNames.length];
- for (int i = 0; i < codes.length; i++) {
- codes[i] = toCode(codeNames[i]);
- }
- map.put(styleName, codes);
- }
- }
- }
- }
- } else {
- map = defaultStyleMap;
- }
- styleMap = map;
- beginToken = tempBeginToken;
- endToken = tempEndToken;
- beginTokenLen = tempBeginToken.length();
- endTokenLen = tempEndToken.length();
- }
-
- public Map getStyleMap() {
- return styleMap;
- }
-
- private void render(final Ansi ansi, final Code code) {
- if (code.isColor()) {
- if (code.isBackground()) {
- ansi.bg(code.getColor());
- } else {
- ansi.fg(code.getColor());
- }
- } else if (code.isAttribute()) {
- ansi.a(code.getAttribute());
- }
- }
-
- private void render(final Ansi ansi, final Code... codes) {
- for (final Code code : codes) {
- render(ansi, code);
- }
- }
-
- /**
- * Renders the given text with the given names which can be ANSI code names or Log4j style names.
- *
- * @param text
- * The text to render
- * @param names
- * ANSI code names or Log4j style names.
- * @return A rendered string containing ANSI codes.
- */
- private String render(final String text, final String... names) {
- final Ansi ansi = Ansi.ansi();
- for (final String name : names) {
- final Code[] codes = styleMap.get(name);
- if (codes != null) {
- render(ansi, codes);
- } else {
- render(ansi, toCode(name));
- }
- }
- return ansi.a(text).reset().toString();
- }
-
- // EXACT COPY OF StringBuilder version of the method but typed as String for input
- @Override
- public void render(final String input, final StringBuilder output, final String styleName)
- throws IllegalArgumentException {
- output.append(render(input, styleName));
- }
-
- @Override
- public void render(final StringBuilder input, final StringBuilder output) throws IllegalArgumentException {
- int i = 0;
- int j, k;
-
- while (true) {
- j = input.indexOf(beginToken, i);
- if (j == -1) {
- if (i == 0) {
- output.append(input);
- return;
- }
- output.append(input.substring(i, input.length()));
- return;
- }
- output.append(input.substring(i, j));
- k = input.indexOf(endToken, j);
-
- if (k == -1) {
- output.append(input);
- return;
- }
- j += beginTokenLen;
- final String spec = input.substring(j, k);
-
- final String[] items = spec.split(AnsiRenderer.CODE_TEXT_SEPARATOR, 2);
- if (items.length == 1) {
- output.append(input);
- return;
- }
- final String replacement = render(items[1], items[0].split(","));
-
- output.append(replacement);
-
- i = k + endTokenLen;
- }
- }
-
- private Code toCode(final String name) {
- return Code.valueOf(toRootUpperCase(name));
- }
-
- @Override
- public String toString() {
- return "JAnsiMessageRenderer [beginToken=" + beginToken + ", beginTokenLen=" + beginTokenLen + ", endToken="
- + endToken + ", endTokenLen=" + endTokenLen + ", styleMap=" + styleMap + "]";
- }
-}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java
index 1408d4d9e6a..f323dd93064 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java
@@ -22,12 +22,10 @@
import java.util.List;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
-import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.message.Message;
import org.apache.logging.log4j.message.MultiformatMessage;
import org.apache.logging.log4j.plugins.Namespace;
import org.apache.logging.log4j.plugins.Plugin;
-import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.MultiFormatStringBuilderFormattable;
import org.apache.logging.log4j.util.PerformanceSensitive;
import org.apache.logging.log4j.util.StringBuilderFormattable;
@@ -54,12 +52,7 @@ private static TextRenderer loadMessageRenderer(final String[] options) {
for (final String option : options) {
switch (toRootUpperCase(option)) {
case "ANSI":
- if (Loader.isJansiAvailable()) {
- return new JAnsiTextRenderer(options, JAnsiTextRenderer.DefaultMessageStyleMap);
- }
- StatusLogger.getLogger()
- .warn("You requested ANSI message rendering but JANSI is not on the classpath.");
- return null;
+ return new AnsiTextRenderer(options, AnsiTextRenderer.DEFAULT_MESSAGE_STYLE_MAP);
case "HTML":
return new HtmlTextRenderer(options);
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
index 84667ce9483..2e86daf2ca3 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
@@ -275,26 +275,6 @@ public static T newInstanceOf(final Class clazz)
}
}
- /**
- * Determines if a named Class can be loaded or not.
- *
- * @param className The class name.
- * @return {@code true} if the class could be found or {@code false} otherwise.
- */
- public static boolean isClassAvailable(final String className) {
- final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
- try {
- Thread.currentThread().setContextClassLoader(getClassLoader());
- return LoaderUtil.isClassAvailable(className);
- } finally {
- Thread.currentThread().setContextClassLoader(contextClassLoader);
- }
- }
-
- public static boolean isJansiAvailable() {
- return isClassAvailable("org.fusesource.jansi.AnsiRenderer");
- }
-
/**
* Loads a class by name. This method respects the {@link LoaderProperties#ignoreTccl()} Log4j property. If this
* property is
diff --git a/log4j-core/src/main/resources/Log4j-config.xsd b/log4j-core/src/main/resources/Log4j-config.xsd
index c17d1c59e3f..3ff224097a0 100644
--- a/log4j-core/src/main/resources/Log4j-config.xsd
+++ b/log4j-core/src/main/resources/Log4j-config.xsd
@@ -696,7 +696,7 @@
Write directly to java.io.FileDescriptor and bypass java.lang.System.out/.err. Can give up to 10x performance boost when the
- output is redirected to file or other process. Cannot be used with Jansi on Windows. Cannot be used with follow.
+ output is redirected to file or other process. Cannot be used with follow.
@@ -704,7 +704,7 @@
Identifies whether the appender honors reassignments of System.out or System.err via System.setOut or System.setErr made after
- configuration. Note that the follow attribute cannot be used with Jansi on Windows. Cannot be used with direct.
+ configuration. Cannot be used with direct.
diff --git a/log4j-parent/pom.xml b/log4j-parent/pom.xml
index fb8f3993001..1da3976381c 100644
--- a/log4j-parent/pom.xml
+++ b/log4j-parent/pom.xml
@@ -113,7 +113,6 @@
2.2.2
2.7.3
2.18.0
- 2.4.0
2.0.1
3.3.4
4.0.5
@@ -352,12 +351,6 @@
${hsqldb.version}
-
- org.fusesource.jansi
- jansi
- ${jansi.version}
-
-
com.google.code.java-allocation-instrumenter
diff --git a/pom.xml b/pom.xml
index 5b4e43691f2..2b37e957625 100644
--- a/pom.xml
+++ b/pom.xml
@@ -343,7 +343,6 @@
1.3.4
1.2.21
1.11.0
- 1.18
18.3.12
3.0.0-beta2
3.0.0-alpha1
@@ -816,12 +815,6 @@
${site-flume.version}
-
- org.fusesource.jansi
- jansi
- ${site-jansi.version}
-
-
com.sleepycat
je
diff --git a/src/changelog/.3.x.x/1736_split_jansi_support.xml b/src/changelog/.3.x.x/1736_split_jansi_support.xml
new file mode 100644
index 00000000000..1005cb42a05
--- /dev/null
+++ b/src/changelog/.3.x.x/1736_split_jansi_support.xml
@@ -0,0 +1,8 @@
+
+
+
+ Remove JAnsi library support, since Windows console supports ANSI escapes now.
+
diff --git a/src/changelog/.3.x.x/2916_rewrite_jansi_renderer.xml b/src/changelog/.3.x.x/2916_rewrite_jansi_renderer.xml
new file mode 100644
index 00000000000..7fad82b6d5b
--- /dev/null
+++ b/src/changelog/.3.x.x/2916_rewrite_jansi_renderer.xml
@@ -0,0 +1,8 @@
+
+
+
+ Rewrite `JAnsiTextRenderer` to work without JAnsi library.
+
diff --git a/src/site/antora/antora.tmpl.yml b/src/site/antora/antora.tmpl.yml
index 632124c8676..b568da3457c 100644
--- a/src/site/antora/antora.tmpl.yml
+++ b/src/site/antora/antora.tmpl.yml
@@ -59,7 +59,6 @@ asciidoc:
disruptor-version: "${site-disruptor.version}"
flume-version: "${site-flume.version}"
jackson-version: "${site-jackson.version}"
- jansi-version: "${site-jansi.version}"
je-version: "${site-je.version}"
log4j-api-version: "${log4j-api.version}"
log4j-core-version: "${site-log4j-core.version}"
diff --git a/src/site/antora/antora.yml b/src/site/antora/antora.yml
index 9fbdd43fcac..e4d86990b46 100644
--- a/src/site/antora/antora.yml
+++ b/src/site/antora/antora.yml
@@ -59,7 +59,6 @@ asciidoc:
disruptor-version: "1.2.3-disruptor"
flume-version: "1.2.3-flume"
jackson-version: "1.2.3-jackson"
- jansi-version: "1.2.3-jansi"
je-version: "1.2.3-je"
log4j-api-version: "1.2.3-api"
log4j-core-version: "1.2.3-core"
diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
index a25db96530b..aee25f66224 100644
--- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
@@ -214,7 +214,7 @@ They are documented in separate pages based on their target resource:
=== Console Appender
As one might expect, the Console Appender writes its output to either the standard output or standard error output.
-The appender supports four different ways to access the output streams:
+The appender supports three different ways to access the output streams:
`direct`::
This mode gives the best performance.
@@ -234,39 +234,6 @@ This setting might be useful in multi-application environments.
Some application servers modify `System.out` and `System.err` to always point to the currently running application.
====
-`JANSI`::
-If the application is running on Windows and the
-https://fusesource.github.io/jansi/[JANSI library]
-is available, the Console appender will use JANSI to emulate ANSI sequence support.
-This mode can be enabled by setting the
-xref:manual/systemproperties.adoc#log4j.console.jansiEnabled[`log4j.console.jansiEnabled`]
-configuration attribute to `true`.
-+
-Additional runtime dependencies are required to use JANSI:
-+
-[tabs]
-====
-Maven::
-+
-[source,xml,subs="+attributes"]
-----
-
- org.fusesource.jansi
- jansi
- {jansi-version}
-
-
-----
-
-Gradle::
-+
-[source,groovy,subs="+attributes"]
-----
-runtimeOnly 'org.fusesource.jansi:jansi:{jansi-version}'
-----
-
-====
-
[#ConsoleAppender-attributes]
.Console Appender configuration attributes
[cols="1m,1,1,5"]
@@ -311,9 +278,7 @@ If other logging backends or the application itself uses `System.out/System.err`
====
This setting is incompatible with the
-<>
-and
-xref:manual/systemproperties.adoc#log4j.console.jansiEnabled[JANSI support].
+<>.
| [[ConsoleAppender-attr-follow]]
follow
@@ -328,9 +293,7 @@ https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#setOut-java.io.P
Otherwise, the value of `System.out` (resp. `System.err`) at configuration time will be used.
This setting is incompatible with the
-<>
-and
-xref:manual/systemproperties.adoc#log4j.console.jansiEnabled[JANSI support].
+<>.
| [[ConsoleAppender-attr-ignoreExceptions]]
ignoreExceptions
diff --git a/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc b/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
index a65b931604f..57c29d892f8 100644
--- a/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
@@ -209,7 +209,7 @@ The optional footer to include at the bottom of each log file
|Default value |`false`
|===
-If `true`, do not output ANSI escape codes
+If `true`, do not output ANSI escape codes.
[#plugin-attr-noConsoleNoAnsi]
==== `noConsoleNoAnsi`
@@ -220,7 +220,7 @@ If `true`, do not output ANSI escape codes
|Default value |`false`
|===
-If `true` and `System.console()` is null, do not output ANSI escape codes
+If `true` and `System.console()` is `null`, do not output ANSI escape codes
[#plugin-elements]
=== Plugin elements
@@ -739,7 +739,7 @@ fqcn
==== Highlight
Adds ANSI colors to the result of the enclosed pattern based on the current event's {log4j2-url}/manual/customloglevels.html[logging level].
-Windows users should refer to <>.
+Windows users should refer to <>.
.link:../javadoc/log4j-core/org/apache/logging/log4j/core/pattern/HighlightConverter.html[`HighlightConverter`] specifier grammar
[source,text]
@@ -1041,7 +1041,7 @@ message{lookups}{ansi}
----
Add `\{ansi}` to render messages with ANSI escape codes.
-Windows users should refer to <>.
+Windows users should refer to <>.
The default syntax for embedded ANSI codes is:
@@ -1235,7 +1235,7 @@ The counter is a static variable, so will only be unique within applications tha
Use ANSI escape sequences to style the result of the enclosed pattern.
The syntax of the `style_expression` parameter is described in <>.
-Windows users should also refer to <>.
+Windows users should also refer to <>.
.link:../javadoc/log4j-core/org/apache/logging/log4j/core/pattern/StyleConverter.html[`StyleConverter`] specifier grammar
[source,text]
@@ -1585,22 +1585,17 @@ If your terminal supports 24-bit colors, you can specify:
* the text color using the `#rrggbb` syntax, e.g. `#dc143c` will color your text crimson,
* the background color using the `bg_#rrggbb` syntax, e.g. `bg_#87ceeb` will use a sky blue background.
-[#jansi]
+[#ansi-windows]
==== ANSI styling on Windows
-ANSI escape sequences are supported natively on many platforms, but not by default on Windows.
-To enable ANSI support add the
-http://fusesource.github.io/jansi/[Jansi]
-dependency to your application, and set xref:manual/systemproperties.adoc#log4j.console.jansiEnabled[the `log4j.console.jansiEnabled` system property] to `true`.
-This allows Log4j to use Jansi to add ANSI escape codes when writing to the console.
+ANSI escape sequences are supported natively on many platforms, but is disabled by default in `cmd.exe` on Windows.
+To enable ANSI escape sequences, create a registry key of name `HKEY_CURRENT_USER\Console\VirtualTerminalLevel` of type `DWORD` and set its value to `0x1`.
-[NOTE]
-====
-Before Log4j 2.10, Jansi was enabled by default.
-The fact that Jansi requires native code means that Jansi can only be loaded by a single class loader.
-For web applications, this means the Jansi jar has to be in the web container's classpath.
-To avoid causing problems for web applications, Log4j no longer automatically tries to load Jansi without explicit configuration from Log4j 2.10 onward.
-====
+See
+https://devblogs.microsoft.com/commandline/understanding-windows-console-host-settings/[Understanding Windows Console Host Settings]
+and
+https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences[Console Virtual Terminal Sequences]
+Microsoft documentation for more details.
[#garbage-free]
=== Garbage-free configuration
diff --git a/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc b/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc
index 941748710c3..ebbe0f2174d 100644
--- a/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc
@@ -170,13 +170,6 @@ include::partial$manual/systemproperties/properties-log-event.adoc[leveloffset=+
include::partial$manual/systemproperties/properties-garbage-collection.adoc[leveloffset=+2]
-[id=properties-jansi]
-=== JANSI
-
-If the https://fusesource.github.io/jansi/[JANSI] library is on the runtime classpath of the application, the following property can be used to control its usage:
-
-include::partial$manual/systemproperties/properties-jansi.adoc[leveloffset=+2]
-
[id=properties-log4j-core-thread-context]
=== Thread context
diff --git a/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-jansi.adoc b/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-jansi.adoc
deleted file mode 100644
index 0aefd398320..00000000000
--- a/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-jansi.adoc
+++ /dev/null
@@ -1,32 +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.
-////
-[id=log4j.console.jansiEnabled]
-== `log4j.console.jansiEnabled`
-
-[cols="1h,5"]
-|===
-| Env. variable | `LOG4J_CONSOLE_JANSI_ENABLED`
-| Type | `boolean`
-| Default value | `false`
-|===
-
-If the following conditions are satisfied:
-
-* Log4j runs on Windows,
-* this property is set to `true`,
-
-Log4j will use the JANSI library to color the output of the console appender.
\ No newline at end of file