This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/2.x by this push:
new f345dedb2a Remove JANSI dependency in `2.x` (#3070)
f345dedb2a is described below
commit f345dedb2aaba25e84e03234a12666b1332a3078
Author: Piotr P. Karwasz <[email protected]>
AuthorDate: Wed Oct 16 11:12:53 2024 +0200
Remove JANSI dependency in `2.x` (#3070)
This commit:
- Removes support for the outdated [Jansi
1.x](http://fusesource.github.io/jansi/) version in `Console` appender.
- Rewrites `JAnsiTextRenderer`, use in the `%m{ansi}` and `%ex{ansi}`
pattern converters to use our internal ANSI support instead of Jansi.
Fixes #1736.
---
.../config/AbstractLog4j1ConfigurationTest.java | 124 +++---
log4j-core-test/pom.xml | 7 -
.../log4j/core/test/categories/Layouts.java | 2 -
.../log4j/core/test/categories/package-info.java | 4 +-
.../appender/ConsoleAppenderAnsiMessagesMain.java | 5 +-
.../ConsoleAppenderAnsiStyleJira180Main.java | 8 +-
.../ConsoleAppenderAnsiStyleJira272Main.java | 8 +-
.../ConsoleAppenderAnsiStyleJira319Main.java | 8 +-
.../ConsoleAppenderAnsiStyleLayoutMain.java | 6 +-
.../ConsoleAppenderAnsiStyleNameLayoutMain.java | 3 +-
...java => ConsoleAppenderAnsiXExceptionMain.java} | 15 +-
.../ConsoleAppenderDefaultSuppressedThrowable.java | 11 +-
.../ConsoleAppenderHighlightLayoutDefaultMain.java | 3 +-
.../ConsoleAppenderHighlightLayoutMain.java | 3 +-
.../appender/ConsoleAppenderJAnsiMessageMain.java | 84 ----
...leAppenderJira1002ShortThrowableLayoutMain.java | 4 +-
.../ConsoleAppenderNoAnsiStyleLayoutMain.java | 9 +-
.../core/appender/JansiConsoleAppenderJira965.java | 28 --
.../core/impl/ThrowableFormatOptionsTest.java | 134 +++----
.../log4j/core/pattern/JAnsiTextRendererTest.java | 58 +++
...rterTest.java => MessageAnsiConverterTest.java} | 4 +-
.../core/pattern/MessageStyledConverterTest.java | 2 +-
.../src/test/resources/log4j2-console-msg-ansi.xml | 30 --
log4j-core/pom.xml | 8 -
.../log4j/core/appender/ConsoleAppender.java | 151 +++-----
.../log4j/core/impl/ThrowableFormatOptions.java | 18 +-
.../logging/log4j/core/impl/package-info.java | 2 +-
.../logging/log4j/core/layout/PatternLayout.java | 13 +-
.../logging/log4j/core/pattern/AnsiEscape.java | 7 +-
.../log4j/core/pattern/JAnsiTextRenderer.java | 423 ++++++++++-----------
.../core/pattern/MessagePatternConverter.java | 9 +-
.../logging/log4j/core/pattern/package-info.java | 2 +-
.../org/apache/logging/log4j/core/util/Loader.java | 4 +
.../logging/log4j/smtp/SmtpAppenderAsyncTest.java | 4 +-
log4j-parent/pom.xml | 7 -
pom.xml | 7 -
src/changelog/.2.x.x/.release-notes.adoc.ftl | 6 +
src/changelog/.2.x.x/1736_split_jansi_support.xml | 8 +
.../.2.x.x/2916_rewrite_jansi_renderer.xml | 8 +
src/site/antora/antora.tmpl.yml | 1 -
src/site/antora/antora.yml | 1 -
.../modules/ROOT/pages/manual/appenders.adoc | 43 +--
.../modules/ROOT/pages/manual/pattern-layout.adoc | 23 +-
.../ROOT/pages/manual/systemproperties.adoc | 7 -
.../manual/systemproperties/properties-jansi.adoc | 32 --
45 files changed, 513 insertions(+), 831 deletions(-)
diff --git
a/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationTest.java
b/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationTest.java
index 90214096ff..85851f52e6 100644
---
a/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationTest.java
+++
b/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationTest.java
@@ -31,7 +31,6 @@ import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
-import java.nio.file.FileSystemException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
@@ -66,7 +65,6 @@ import org.apache.logging.log4j.core.filter.Filterable;
import org.apache.logging.log4j.core.filter.ThresholdFilter;
import org.apache.logging.log4j.core.layout.HtmlLayout;
import org.apache.logging.log4j.core.layout.PatternLayout;
-import org.apache.logging.log4j.core.util.CloseShieldOutputStream;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
@@ -78,7 +76,7 @@ public abstract class AbstractLog4j1ConfigurationTest {
abstract Configuration getConfiguration(String configResourcePrefix)
throws URISyntaxException, IOException;
- protected InputStream getResourceAsStream(final String configResource)
throws IOException {
+ protected InputStream getResourceAsStream(final String configResource) {
final InputStream is =
getClass().getClassLoader().getResourceAsStream(configResource);
assertNotNull(is);
return is;
@@ -123,7 +121,7 @@ public abstract class AbstractLog4j1ConfigurationTest {
final ConsoleAppender appender = configuration.getAppender(name);
assertNotNull(
"Missing appender '" + name + "' in configuration " +
configResource + " → " + configuration, appender);
- assertEquals("follow", true, getFollowProperty(appender));
+ assertTrue("follow", getFollowProperty(appender));
assertEquals(Target.SYSTEM_ERR, appender.getTarget());
//
final LoggerConfig loggerConfig =
configuration.getLoggerConfig("com.example.foo");
@@ -141,16 +139,15 @@ public abstract class AbstractLog4j1ConfigurationTest {
}
public void testRollingFileAppender() throws Exception {
- testRollingFileAppender("config-1.2/log4j-RollingFileAppender", "RFA",
"target/hadoop.log.%i");
+ testRollingFileAppender("config-1.2/log4j-RollingFileAppender");
}
public void testDailyRollingFileAppender() throws Exception {
- testDailyRollingFileAppender(
- "config-1.2/log4j-DailyRollingFileAppender", "DRFA",
"target/hadoop.log%d{.dd-MM-yyyy}");
+
testDailyRollingFileAppender("config-1.2/log4j-DailyRollingFileAppender");
}
public void testRollingFileAppenderWithProperties() throws Exception {
-
testRollingFileAppender("config-1.2/log4j-RollingFileAppender-with-props",
"RFA", "target/hadoop.log.%i");
+
testRollingFileAppender("config-1.2/log4j-RollingFileAppender-with-props");
}
public void testSystemProperties1() throws Exception {
@@ -160,13 +157,13 @@ public abstract class AbstractLog4j1ConfigurationTest {
final Configuration configuration =
getConfiguration("config-1.2/log4j-system-properties-1");
try {
final RollingFileAppender appender =
configuration.getAppender("RFA");
- assertEquals("append", false, getAppendProperty(appender));
+ assertFalse("append", getAppendProperty(appender));
assertEquals("bufferSize", 1000,
appender.getManager().getBufferSize());
- assertEquals("immediateFlush", false,
appender.getImmediateFlush());
+ assertFalse("immediateFlush", appender.getImmediateFlush());
final DefaultRolloverStrategy rolloverStrategy =
(DefaultRolloverStrategy)
appender.getManager().getRolloverStrategy();
assertEquals(16, rolloverStrategy.getMaxIndex());
- final CompositeTriggeringPolicy ctp = (CompositeTriggeringPolicy)
appender.getTriggeringPolicy();
+ final CompositeTriggeringPolicy ctp =
appender.getTriggeringPolicy();
final TriggeringPolicy[] triggeringPolicies =
ctp.getTriggeringPolicies();
assertEquals(1, triggeringPolicies.length);
final TriggeringPolicy tp = triggeringPolicies[0];
@@ -174,17 +171,11 @@ public abstract class AbstractLog4j1ConfigurationTest {
final SizeBasedTriggeringPolicy sbtp = (SizeBasedTriggeringPolicy)
tp;
assertEquals(20 * 1024 * 1024, sbtp.getMaxFileSize());
appender.stop(10, TimeUnit.SECONDS);
- // System.out.println("expected: " + tempFileName + " Actual: " +
- // appender.getFileName());
assertEquals(tempFileName, appender.getFileName());
} finally {
configuration.start();
configuration.stop();
- try {
- Files.deleteIfExists(tempFilePath);
- } catch (final FileSystemException e) {
- e.printStackTrace();
- }
+ Files.deleteIfExists(tempFilePath);
}
}
@@ -195,22 +186,17 @@ public abstract class AbstractLog4j1ConfigurationTest {
assertEquals(tmpDir + "/hadoop.log", appender.getFileName());
appender.stop(10, TimeUnit.SECONDS);
// Try to clean up
- try {
- Path path = new File(appender.getFileName()).toPath();
- Files.deleteIfExists(path);
- path = new File("${java.io.tmpdir}").toPath();
- Files.deleteIfExists(path);
- } catch (IOException e) {
- e.printStackTrace();
- }
+ Path path = new File(appender.getFileName()).toPath();
+ Files.deleteIfExists(path);
+ path = new File("${java.io.tmpdir}").toPath();
+ Files.deleteIfExists(path);
}
- private void testRollingFileAppender(final String configResource, final
String name, final String filePattern)
- throws Exception {
+ private void testRollingFileAppender(final String configResource) throws
Exception {
final Configuration configuration = getConfiguration(configResource);
- final Appender appender = configuration.getAppender(name);
+ final Appender appender = configuration.getAppender("RFA");
assertNotNull(appender);
- assertEquals(name, appender.getName());
+ assertEquals("RFA", appender.getName());
assertTrue(appender.getClass().getName(), appender instanceof
RollingFileAppender);
final RollingFileAppender rfa = (RollingFileAppender) appender;
@@ -218,11 +204,11 @@ public abstract class AbstractLog4j1ConfigurationTest {
"defaultRolloverStrategy",
rfa.getManager().getRolloverStrategy() instanceof DefaultRolloverStrategy);
assertFalse(
"rolloverStrategy", ((DefaultRolloverStrategy)
rfa.getManager().getRolloverStrategy()).isUseMax());
- assertEquals("append", false, getAppendProperty(rfa));
+ assertFalse("append", getAppendProperty(rfa));
assertEquals("bufferSize", 1000, rfa.getManager().getBufferSize());
- assertEquals("immediateFlush", false, rfa.getImmediateFlush());
+ assertFalse("immediateFlush", rfa.getImmediateFlush());
assertEquals("target/hadoop.log", rfa.getFileName());
- assertEquals(filePattern, rfa.getFilePattern());
+ assertEquals("target/hadoop.log.%i", rfa.getFilePattern());
final TriggeringPolicy triggeringPolicy = rfa.getTriggeringPolicy();
assertNotNull(triggeringPolicy);
assertTrue(triggeringPolicy.getClass().getName(), triggeringPolicy
instanceof CompositeTriggeringPolicy);
@@ -241,20 +227,19 @@ public abstract class AbstractLog4j1ConfigurationTest {
configuration.stop();
}
- private void testDailyRollingFileAppender(final String configResource,
final String name, final String filePattern)
- throws Exception {
+ private void testDailyRollingFileAppender(final String configResource)
throws Exception {
final Configuration configuration = getConfiguration(configResource);
try {
- final Appender appender = configuration.getAppender(name);
+ final Appender appender = configuration.getAppender("DRFA");
assertNotNull(appender);
- assertEquals(name, appender.getName());
+ assertEquals("DRFA", appender.getName());
assertTrue(appender.getClass().getName(), appender instanceof
RollingFileAppender);
final RollingFileAppender rfa = (RollingFileAppender) appender;
- assertEquals("append", false, getAppendProperty(rfa));
+ assertFalse("append", getAppendProperty(rfa));
assertEquals("bufferSize", 1000, rfa.getManager().getBufferSize());
- assertEquals("immediateFlush", false, rfa.getImmediateFlush());
+ assertFalse("immediateFlush", rfa.getImmediateFlush());
assertEquals("target/hadoop.log", rfa.getFileName());
- assertEquals(filePattern, rfa.getFilePattern());
+ assertEquals("target/hadoop.log%d{.dd-MM-yyyy}",
rfa.getFilePattern());
final TriggeringPolicy triggeringPolicy =
rfa.getTriggeringPolicy();
assertNotNull(triggeringPolicy);
assertTrue(triggeringPolicy.getClass().getName(), triggeringPolicy
instanceof CompositeTriggeringPolicy);
@@ -275,8 +260,8 @@ public abstract class AbstractLog4j1ConfigurationTest {
}
}
- private Layout<?> testFile(final String configResource) throws Exception {
- final Configuration configuration = getConfiguration(configResource);
+ private Layout<?> testFile() throws Exception {
+ final Configuration configuration =
getConfiguration("config-1.2/log4j-file-SimpleLayout");
final FileAppender appender = configuration.getAppender("File");
assertNotNull(appender);
assertEquals("target/mylog.txt", appender.getFileName());
@@ -284,9 +269,9 @@ public abstract class AbstractLog4j1ConfigurationTest {
final LoggerConfig loggerConfig =
configuration.getLoggerConfig("com.example.foo");
assertNotNull(loggerConfig);
assertEquals(Level.DEBUG, loggerConfig.getLevel());
- assertEquals("append", false, getAppendProperty(appender));
+ assertFalse("append", getAppendProperty(appender));
assertEquals("bufferSize", 1000,
appender.getManager().getBufferSize());
- assertEquals("immediateFlush", false, appender.getImmediateFlush());
+ assertFalse("immediateFlush", appender.getImmediateFlush());
configuration.start();
configuration.stop();
return appender.getLayout();
@@ -316,7 +301,7 @@ public abstract class AbstractLog4j1ConfigurationTest {
}
public void testFileSimpleLayout() throws Exception {
- final PatternLayout layout = (PatternLayout)
testFile("config-1.2/log4j-file-SimpleLayout");
+ final PatternLayout layout = (PatternLayout) testFile();
assertEquals("%v1Level - %m%n", layout.getConversionPattern());
}
@@ -328,14 +313,11 @@ public abstract class AbstractLog4j1ConfigurationTest {
assertTrue(appender.getClass().getName(), appender instanceof
NullAppender);
}
- private boolean getFollowProperty(final ConsoleAppender consoleAppender)
- throws Exception, NoSuchFieldException, IllegalAccessException {
- final CloseShieldOutputStream wrapperStream =
- (CloseShieldOutputStream)
getOutputStream(consoleAppender.getManager());
- final Field delegateField =
CloseShieldOutputStream.class.getDeclaredField("delegate");
- delegateField.setAccessible(true);
- final boolean follow =
!System.out.equals(delegateField.get(wrapperStream));
- return follow;
+ private boolean getFollowProperty(final ConsoleAppender consoleAppender)
throws Exception {
+ OutputStream outputStream =
getOutputStream(consoleAppender.getManager());
+ String className = outputStream.getClass().getName();
+ return className.endsWith("ConsoleAppender$SystemErrStream")
+ || className.endsWith("ConsoleAppender$SystemOutStream");
}
private boolean getAppendProperty(final RollingFileAppender appender)
throws Exception {
@@ -383,7 +365,7 @@ public abstract class AbstractLog4j1ConfigurationTest {
final HtmlLayout htmlLayout = (HtmlLayout) testLayout(config,
"HTMLLayout");
assertNotNull(htmlLayout);
assertEquals("title", "Log4J Log Messages", htmlLayout.getTitle());
- assertEquals("locationInfo", false, htmlLayout.isLocationInfo());
+ assertFalse("locationInfo", htmlLayout.isLocationInfo());
// PatternLayout
final PatternLayout patternLayout = (PatternLayout) testLayout(config,
"PatternLayout");
assertNotNull(patternLayout);
@@ -403,7 +385,7 @@ public abstract class AbstractLog4j1ConfigurationTest {
assertNotNull(consoleAppender);
assertEquals("target", Target.SYSTEM_OUT, consoleAppender.getTarget());
final boolean follow = getFollowProperty(consoleAppender);
- assertEquals("follow", false, follow);
+ assertFalse("follow", follow);
// DailyRollingFileAppender
final RollingFileAppender dailyRollingFileAppender =
config.getAppender("DailyRollingFileAppender");
assertNotNull(dailyRollingFileAppender);
@@ -411,15 +393,15 @@ public abstract class AbstractLog4j1ConfigurationTest {
"equivalent file pattern",
"target/dailyRollingFileAppender%d{.yyyy-MM-dd}",
dailyRollingFileAppender.getFilePattern());
- assertEquals("append", true,
getAppendProperty(dailyRollingFileAppender));
+ assertTrue("append", getAppendProperty(dailyRollingFileAppender));
assertEquals("bufferSize", 8192,
dailyRollingFileAppender.getManager().getBufferSize());
- assertEquals("immediateFlush", true,
dailyRollingFileAppender.getImmediateFlush());
+ assertTrue("immediateFlush",
dailyRollingFileAppender.getImmediateFlush());
// FileAppender
final FileAppender fileAppender = config.getAppender("FileAppender");
assertNotNull(fileAppender);
- assertEquals("append", true, getAppendProperty(fileAppender));
+ assertTrue("append", getAppendProperty(fileAppender));
assertEquals("bufferSize", 8192,
fileAppender.getManager().getBufferSize());
- assertEquals("immediateFlush", true, fileAppender.getImmediateFlush());
+ assertTrue("immediateFlush", fileAppender.getImmediateFlush());
// RollingFileAppender
final RollingFileAppender rollingFileAppender =
config.getAppender("RollingFileAppender");
assertNotNull(rollingFileAppender);
@@ -433,9 +415,9 @@ public abstract class AbstractLog4j1ConfigurationTest {
final DefaultRolloverStrategy strategy =
(DefaultRolloverStrategy)
rollingFileAppender.getManager().getRolloverStrategy();
assertEquals("maxBackupIndex", 1, strategy.getMaxIndex());
- assertEquals("append", true, getAppendProperty(rollingFileAppender));
+ assertTrue("append", getAppendProperty(rollingFileAppender));
assertEquals("bufferSize", 8192,
rollingFileAppender.getManager().getBufferSize());
- assertEquals("immediateFlush", true,
rollingFileAppender.getImmediateFlush());
+ assertTrue("immediateFlush", rollingFileAppender.getImmediateFlush());
config.start();
config.stop();
}
@@ -443,7 +425,7 @@ public abstract class AbstractLog4j1ConfigurationTest {
/**
* Checks a hierarchy of filters.
*
- * @param filter
+ * @param filter A filter
* @return the number of filters
*/
private int checkFilters(final org.apache.logging.log4j.core.Filter
filter) {
@@ -467,7 +449,7 @@ public abstract class AbstractLog4j1ConfigurationTest {
/**
* Checks a hierarchy of filters.
*
- * @param filter
+ * @param filter A filter
* @return the number of filters
*/
private int checkFilters(final org.apache.log4j.spi.Filter filter) {
@@ -581,9 +563,9 @@ public abstract class AbstractLog4j1ConfigurationTest {
appender = configuration.getAppender("DEFAULT_TIME");
assertTrue("is RollingFileAppender", appender instanceof
RollingFileAppender);
final RollingFileAppender defaultTime = (RollingFileAppender) appender;
- assertEquals("append", true, defaultTime.getManager().isAppend());
+ assertTrue("append", defaultTime.getManager().isAppend());
assertEquals("bufferSize", 8192,
defaultTime.getManager().getBufferSize());
- assertEquals("immediateFlush", true, defaultTime.getImmediateFlush());
+ assertTrue("immediateFlush", defaultTime.getImmediateFlush());
assertEquals("fileName",
"target/EnhancedRollingFileAppender/defaultTime.log",
defaultTime.getFileName());
assertEquals(
"filePattern",
@@ -595,9 +577,9 @@ public abstract class AbstractLog4j1ConfigurationTest {
appender = configuration.getAppender("DEFAULT_SIZE");
assertTrue("is RollingFileAppender", appender instanceof
RollingFileAppender);
final RollingFileAppender defaultSize = (RollingFileAppender) appender;
- assertEquals("append", true, defaultSize.getManager().isAppend());
+ assertTrue("append", defaultSize.getManager().isAppend());
assertEquals("bufferSize", 8192,
defaultSize.getManager().getBufferSize());
- assertEquals("immediateFlush", true, defaultSize.getImmediateFlush());
+ assertTrue("immediateFlush", defaultSize.getImmediateFlush());
assertEquals("fileName",
"target/EnhancedRollingFileAppender/defaultSize.log",
defaultSize.getFileName());
assertEquals(
"filePattern",
"target/EnhancedRollingFileAppender/defaultSize.%i.log",
defaultSize.getFilePattern());
@@ -613,9 +595,9 @@ public abstract class AbstractLog4j1ConfigurationTest {
appender = configuration.getAppender("TIME");
assertTrue("is RollingFileAppender", appender instanceof
RollingFileAppender);
final RollingFileAppender time = (RollingFileAppender) appender;
- assertEquals("append", false, time.getManager().isAppend());
+ assertFalse("append", time.getManager().isAppend());
assertEquals("bufferSize", 1000, time.getManager().getBufferSize());
- assertEquals("immediateFlush", false, time.getImmediateFlush());
+ assertFalse("immediateFlush", time.getImmediateFlush());
assertEquals("fileName",
"target/EnhancedRollingFileAppender/time.log", time.getFileName());
assertEquals(
"filePattern",
"target/EnhancedRollingFileAppender/time.%d{yyyy-MM-dd}.log",
time.getFilePattern());
@@ -625,9 +607,9 @@ public abstract class AbstractLog4j1ConfigurationTest {
appender = configuration.getAppender("SIZE");
assertTrue("is RollingFileAppender", appender instanceof
RollingFileAppender);
final RollingFileAppender size = (RollingFileAppender) appender;
- assertEquals("append", false, size.getManager().isAppend());
+ assertFalse("append", size.getManager().isAppend());
assertEquals("bufferSize", 1000, size.getManager().getBufferSize());
- assertEquals("immediateFlush", false, size.getImmediateFlush());
+ assertFalse("immediateFlush", size.getImmediateFlush());
assertEquals("fileName",
"target/EnhancedRollingFileAppender/size.log", size.getFileName());
assertEquals("filePattern",
"target/EnhancedRollingFileAppender/size.%i.log", size.getFilePattern());
policy = size.getTriggeringPolicy();
diff --git a/log4j-core-test/pom.xml b/log4j-core-test/pom.xml
index 56f7fd885f..8c8cbc19bb 100644
--- a/log4j-core-test/pom.xml
+++ b/log4j-core-test/pom.xml
@@ -242,13 +242,6 @@
<scope>test</scope>
</dependency>
- <!-- Required for console color support in Windows -->
- <dependency>
- <groupId>org.fusesource.jansi</groupId>
- <artifactId>jansi</artifactId>
- <scope>test</scope>
- </dependency>
-
<!-- Used for JMS appenders (needs an implementation of course) -->
<dependency>
<groupId>javax.jms</groupId>
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 0cdc8b4540..89057c90c0 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
@@ -22,8 +22,6 @@ package org.apache.logging.log4j.core.test.categories;
public interface Layouts {
interface Csv {}
- interface Jansi {}
-
interface Json {}
interface Xml {}
diff --git
a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/categories/package-info.java
b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/categories/package-info.java
index a299ed2b4c..fbbe417285 100644
---
a/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/categories/package-info.java
+++
b/log4j-core-test/src/main/java/org/apache/logging/log4j/core/test/categories/package-info.java
@@ -20,8 +20,10 @@
* integration tests, an appropriate category interface should be specified.
*/
@Export
-@Version("2.20.1")
+@Version("2.20.2")
+@BaselineIgnore("2.25.0")
package org.apache.logging.log4j.core.test.categories;
+import aQute.bnd.annotation.baseline.BaselineIgnore;
import org.osgi.annotation.bundle.Export;
import org.osgi.annotation.versioning.Version;
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 3088ca2bc1..a44d064ab4 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 @@ import org.apache.logging.log4j.core.config.Configurator;
* </p>
*
* <pre>
- * 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
* </pre>
*/
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 dffc5b4289..bd8491c666 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.LoggerContext;
import org.apache.logging.log4j.core.config.Configurator;
/**
- * Tests https://issues.apache.org/jira/browse/LOG4J2-180
+ * Tests <a
href="https://issues.apache.org/jira/browse/LOG4J2-180">LOG4J2-180</a>
* <p>
* Running from a Windows command line from the root of the project:
* </p>
*
* <pre>
- * 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
* </pre>
*/
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 0f2844abe7..65a4ed1ee7 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.LoggerContext;
import org.apache.logging.log4j.core.config.Configurator;
/**
- * Tests https://issues.apache.org/jira/browse/LOG4J2-272
+ * Tests <a
href="https://issues.apache.org/jira/browse/LOG4J2-272">LOG4J2-272</a>
* <p>
* Running from a Windows command line from the root of the project:
* </p>
* <pre>
- * 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
* </pre>
*/
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 48681a85f7..957a58e9bf 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.LoggerContext;
import org.apache.logging.log4j.core.config.Configurator;
/**
- * Tests https://issues.apache.org/jira/browse/LOG4J2-319
+ * Tests <a
href="https://issues.apache.org/jira/browse/LOG4J2-319">LOG4J2-319</a>
* <p>
* Running from a Windows command line from the root of the project:
* </p>
*
* <pre>
- * 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
* </pre>
*/
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 87730d9a5a..2ef1c52c9f 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 @@ import org.junit.Test;
* </pre>
* or:
* <pre>
- * 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
* </pre>
*
*/
@@ -54,11 +54,9 @@ public class ConsoleAppenderAnsiStyleLayoutMain {
}
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 9088b75d47..5cdc81ee45 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 d681e02c75..ee062add98 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.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;
/**
* 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 @@ import org.junit.experimental.categories.Category;
* </p>
*
* <pre>
- * mvn
-Dtest=org.apache.logging.log4j.core.appender.ConsoleAppenderJAnsiXExceptionMain
test
+ * mvn
-Dtest=org.apache.logging.log4j.core.appender.ConsoleAppenderAnsiXExceptionMain
test
* </pre>
*
* or, on Windows:
*
* <pre>
- * 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
* </pre>
*
*/
-@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 class ConsoleAppenderJAnsiXExceptionMain {
}
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 8553eb3f1d..2432df32c9 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 @@ import org.apache.logging.log4j.core.config.Configurator;
* </p>
*
* <pre>
- * 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
* </pre>
*/
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 @@ public class ConsoleAppenderDefaultSuppressedThrowable {
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 7a1b7cf616..d9b5eeba27 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 dbb6958ea2..ad86c24570 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 56cce35a74..0000000000
---
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.
- * <p>
- * Running from a Windows command line from the root of the project:
- * </p>
- *
- * <pre>
- * mvn
-Dtest=org.apache.logging.log4j.core.appender.ConsoleAppenderJAnsiMessageMain
test
- * </pre>
- *
- * or, on Windows:
- *
- * <pre>
- * 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
- * </pre>
- *
- */
-@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<Object, Object> 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 b75e3e0325..b1177acdd2 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 @@ package org.apache.logging.log4j.core.appender;
*/
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 1c35103862..1165fc6a60 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 @@ import org.apache.logging.log4j.core.config.Configurator;
* </p>
*
* <pre>
- * 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
* </pre>
*/
public class ConsoleAppenderNoAnsiStyleLayoutMain {
@@ -43,12 +43,11 @@ public class ConsoleAppenderNoAnsiStyleLayoutMain {
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/JansiConsoleAppenderJira965.java
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/JansiConsoleAppenderJira965.java
deleted file mode 100644
index 8bdd3e13ef..0000000000
---
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 4719db8563..10dea80250 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.AnsiEscape;
import org.apache.logging.log4j.core.pattern.JAnsiTextRenderer;
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 @@ public final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* Test {@code %throwable}
*/
@Test
- public void testEmpty() {
+ void testEmpty() {
test(new String[] {}, Integer.MAX_VALUE, Strings.LINE_SEPARATOR, null);
}
@@ -87,7 +88,7 @@ public final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* Test {@code %throwable{} }
*/
@Test
- public void testOneEmptyElement() {
+ void testOneEmptyElement() {
test(new String[] {""}, Integer.MAX_VALUE, Strings.LINE_SEPARATOR,
null);
}
@@ -103,7 +104,7 @@ public final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
private void testFullAnsiEmptyConfig(final ThrowableFormatOptions tfo) {
final TextRenderer textRenderer = tfo.getTextRenderer();
assertNotNull(textRenderer);
- assertTrue(textRenderer instanceof JAnsiTextRenderer);
- final JAnsiTextRenderer jansiRenderer = (JAnsiTextRenderer)
textRenderer;
- final Map<String, Code[]> styleMap = jansiRenderer.getStyleMap();
+ assertInstanceOf(JAnsiTextRenderer.class, textRenderer);
+ final JAnsiTextRenderer ansiRenderer = (JAnsiTextRenderer)
textRenderer;
+ final Map<String, String> 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<String, Code[]> styleMap = jansiRenderer.getStyleMap();
- assertArrayEquals(new Code[] {Code.RED}, styleMap.get("Warning"));
+ assertInstanceOf(JAnsiTextRenderer.class, textRenderer);
+ final JAnsiTextRenderer ansiRenderer = (JAnsiTextRenderer)
textRenderer;
+ final Map<String, String> 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 final class ThrowableFormatOptionsTest {
null);
final TextRenderer textRenderer = tfo.getTextRenderer();
assertNotNull(textRenderer);
- assertTrue(textRenderer instanceof JAnsiTextRenderer);
- final JAnsiTextRenderer jansiRenderer = (JAnsiTextRenderer)
textRenderer;
- final Map<String, Code[]> 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(JAnsiTextRenderer.class, textRenderer);
+ final JAnsiTextRenderer ansiRenderer = (JAnsiTextRenderer)
textRenderer;
+ final Map<String, String> 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 final class ThrowableFormatOptionsTest {
null);
final TextRenderer textRenderer = tfo.getTextRenderer();
assertNotNull(textRenderer);
- assertTrue(textRenderer instanceof JAnsiTextRenderer);
- final JAnsiTextRenderer jansiRenderer = (JAnsiTextRenderer)
textRenderer;
- final Map<String, Code[]> 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(JAnsiTextRenderer.class, textRenderer);
+ final JAnsiTextRenderer ansiRenderer = (JAnsiTextRenderer)
textRenderer;
+ final Map<String, String> 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 final class ThrowableFormatOptionsTest {
* Test {@code %throwable{short} }
*/
@Test
- public void testShort() {
+ void testShort() {
test(new String[] {"short"}, 2, Strings.LINE_SEPARATOR, null);
}
@@ -213,7 +215,7 @@ public final class ThrowableFormatOptionsTest {
* Test {@code %throwable{10} }
*/
@Test
- public void testDepth() {
+ void testDepth() {
test(new String[] {"10"}, 10, Strings.LINE_SEPARATOR, null);
}
@@ -221,7 +223,7 @@ public final class ThrowableFormatOptionsTest {
* Test {@code %throwable{separator(|)} }
*/
@Test
- public void testSeparator() {
+ void testSeparator() {
test(new String[] {"separator(|)"}, Integer.MAX_VALUE, "|", null);
}
@@ -229,7 +231,7 @@ public final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* Test {@code %throwable{separator( | )} }
*/
@Test
- public void testSeparatorAsMultipleCharacters() {
+ void testSeparatorAsMultipleCharacters() {
test(new String[] {"separator( | )"}, Integer.MAX_VALUE, " | ", null);
}
@@ -257,7 +259,7 @@ public final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* Test {@code %throwable{none}{separator(|)} }
*/
@Test
- public void testNoneAndSeparator() {
+ void testNoneAndSeparator() {
test(new String[] {"none", "separator(|)"}, 0, "|", null);
}
@@ -285,7 +287,7 @@ public final class ThrowableFormatOptionsTest {
* Test {@code %throwable{short}{separator(|)} }
*/
@Test
- public void testShortAndSeparator() {
+ void testShortAndSeparator() {
test(new String[] {"short", "separator(|)"}, 2, "|", null);
}
@@ -293,7 +295,7 @@ public final class ThrowableFormatOptionsTest {
* Test {@code %throwable{10}{separator(|)} }
*/
@Test
- public void testDepthAndSeparator() {
+ void testDepthAndSeparator() {
test(new String[] {"10", "separator(|)"}, 10, "|", null);
}
@@ -301,7 +303,7 @@ public final class ThrowableFormatOptionsTest {
* Test {@code %throwable{filters(packages)} }
*/
@Test
- public void testFilters() {
+ void testFilters() {
test(
new String[] {"filters(packages)"},
Integer.MAX_VALUE,
@@ -313,7 +315,7 @@ public final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* Test {@code %throwable{none}{filters(packages)} }
*/
@Test
- public void testNoneAndFilters() {
+ void testNoneAndFilters() {
test(
new String[] {"none", "filters(packages)"},
0,
@@ -357,7 +359,7 @@ public final class ThrowableFormatOptionsTest {
* Test {@code %throwable{short}{filters(packages)} }
*/
@Test
- public void testShortAndFilters() {
+ void testShortAndFilters() {
test(
new String[] {"short", "filters(packages)"},
2,
@@ -369,7 +371,7 @@ public final class ThrowableFormatOptionsTest {
* Test {@code %throwable{10}{filters(packages)} }
*/
@Test
- public void testDepthAndFilters() {
+ void testDepthAndFilters() {
test(
new String[] {"10", "filters(packages)"},
10,
@@ -381,7 +383,7 @@ public final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* Test {@code %throwable{short,filters(packages)} }
*/
@Test
- public void testSingleOptionShortAndFilters() {
+ void testSingleOptionShortAndFilters() {
test(
new String[] {"short,filters(packages)"},
2,
@@ -465,7 +467,7 @@ public final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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 final class ThrowableFormatOptionsTest {
* 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/JAnsiTextRendererTest.java
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/JAnsiTextRendererTest.java
new file mode 100644
index 0000000000..0595f68533
--- /dev/null
+++
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/JAnsiTextRendererTest.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.Collections;
+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 JAnsiTextRendererTest {
+
+ public static Stream<Arguments> 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 JAnsiTextRenderer renderer = new JAnsiTextRenderer(new String[]
{"ansi", format}, Collections.emptyMap());
+ 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 294355a173..51278a04d6 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.BeforeEach;
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 class MessageJansiConverterTest {
@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<String> 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 71fb6fbc77..06ab681fed 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 class MessageStyledConverterTest {
@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<String> msgs = app.getMessages();
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 d30b0fb406..0000000000
--- a/log4j-core-test/src/test/resources/log4j2-console-msg-ansi.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-<Configuration status="OFF">
- <Appenders>
- <Console name="Console" target="SYSTEM_OUT">
- <PatternLayout pattern="%style{%d}{white} %style{[%t]}
%style{%-5level:}{yellow} %style{%msg{ansi}{KeyStyle=white
ValueStyle=cyan,bold}%n%throwable}{green}" />
- </Console>
- </Appenders>
- <Loggers>
- <Logger name="org.foo" level="DEBUG" />
- <Root level="TRACE">
- <AppenderRef ref="Console" />
- </Root>
- </Loggers>
-</Configuration>
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
index 1e35ebce72..f5693dc2e9 100644
--- a/log4j-core/pom.xml
+++ b/log4j-core/pom.xml
@@ -66,7 +66,6 @@
org.apache.commons.csv;resolution:=optional,
org.apache.kafka.*;resolution:=optional,
org.codehaus.stax2;resolution:=optional,
- org.fusesource.jansi;resolution:=optional,
org.jctools.*;resolution:=optional,
org.zeromq;resolution:=optional,
javax.lang.model.*;resolution:=optional,
@@ -97,7 +96,6 @@
java.management;transitive=false;static=true,
java.naming;transitive=false,
org.apache.commons.csv;transitive=false,
- org.fusesource.jansi;transitive=false,
org.jspecify;transitive=false,
org.zeromq.jeromq;transitive=false,
<!-- A module descriptor is only available in version 1.2.16+, hence it
is not detected -->
@@ -194,12 +192,6 @@
<artifactId>jackson-dataformat-yaml</artifactId>
<optional>true</optional>
</dependency>
- <!-- Required for console color support in Windows -->
- <dependency>
- <groupId>org.fusesource.jansi</groupId>
- <artifactId>jansi</artifactId>
- <optional>true</optional>
- </dependency>
<!-- Alternative implementation of BlockingQueue using JCTools for
AsyncAppender -->
<dependency>
<groupId>org.jctools</groupId>
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 986c82863f..1b1bf5e2bd 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,10 +20,7 @@ import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
-import java.io.PrintStream;
import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.lang.reflect.Constructor;
import java.nio.charset.Charset;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.logging.log4j.core.Appender;
@@ -35,12 +32,8 @@ import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import
org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
-import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.core.util.Booleans;
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.util.Chars;
import org.apache.logging.log4j.util.PropertiesUtil;
/**
@@ -61,8 +54,7 @@ import org.apache.logging.log4j.util.PropertiesUtil;
public final class ConsoleAppender extends
AbstractOutputStreamAppender<OutputStreamManager> {
public static final String PLUGIN_NAME = "Console";
- private static final String JANSI_CLASS =
"org.fusesource.jansi.WindowsAnsiOutputStream";
- private static ConsoleManagerFactory factory = new ConsoleManagerFactory();
+ private static final ConsoleManagerFactory factory = new
ConsoleManagerFactory();
private static final Target DEFAULT_TARGET = Target.SYSTEM_OUT;
private static final AtomicInteger COUNT = new AtomicInteger();
@@ -116,10 +108,10 @@ public final class ConsoleAppender extends
AbstractOutputStreamAppender<OutputSt
*
* @param layout The layout to use (required).
* @param filter The Filter or null.
- * @param targetStr The target ("SYSTEM_OUT" or "SYSTEM_ERR"). The default
is "SYSTEM_OUT".
+ * @param target The target ("SYSTEM_OUT" or "SYSTEM_ERR"). The default is
"SYSTEM_OUT".
* @param name The name of the Appender (required).
* @param follow If true will follow changes to the underlying output
stream.
- * @param ignore If {@code "true"} (default) exceptions encountered when
appending events are logged; otherwise they
+ * @param ignoreExceptions If {@code "true"} (default) exceptions
encountered when appending events are logged; otherwise they
* are propagated to the caller.
* @return The ConsoleAppender.
* @deprecated Deprecated in 2.7; use {@link #newBuilder()}.
@@ -128,22 +120,18 @@ public final class ConsoleAppender extends
AbstractOutputStreamAppender<OutputSt
public static ConsoleAppender createAppender(
Layout<? extends Serializable> layout,
final Filter filter,
- final String targetStr,
+ final String target,
final String name,
final String follow,
- final String ignore) {
- if (name == null) {
- LOGGER.error("No name provided for ConsoleAppender");
- return null;
- }
- if (layout == null) {
- layout = PatternLayout.createDefaultLayout();
- }
- final boolean isFollow = Boolean.parseBoolean(follow);
- final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
- final Target target = targetStr == null ? DEFAULT_TARGET :
Target.valueOf(targetStr);
- return new ConsoleAppender(
- name, layout, filter, getManager(target, isFollow, false,
layout), ignoreExceptions, target, null);
+ final String ignoreExceptions) {
+ return newBuilder()
+ .setLayout(layout)
+ .setFilter(filter)
+ .setTarget(target == null ? DEFAULT_TARGET :
Target.valueOf(target))
+ .setName(name)
+ .setFollow(Boolean.parseBoolean(follow))
+ .setIgnoreExceptions(Booleans.parseBoolean(ignoreExceptions,
true))
+ .build();
}
/**
@@ -171,21 +159,15 @@ public final class ConsoleAppender extends
AbstractOutputStreamAppender<OutputSt
final boolean follow,
final boolean direct,
final boolean ignoreExceptions) {
- // @formatter:on
- if (name == null) {
- LOGGER.error("No name provided for ConsoleAppender");
- return null;
- }
- if (layout == null) {
- layout = PatternLayout.createDefaultLayout();
- }
- target = target == null ? Target.SYSTEM_OUT : target;
- if (follow && direct) {
- LOGGER.error("Cannot use both follow and direct on
ConsoleAppender");
- return null;
- }
- return new ConsoleAppender(
- name, layout, filter, getManager(target, follow, direct,
layout), ignoreExceptions, target, null);
+ return newBuilder()
+ .setLayout(layout)
+ .setFilter(filter)
+ .setTarget(target)
+ .setName(name)
+ .setFollow(follow)
+ .setDirect(direct)
+ .setIgnoreExceptions(ignoreExceptions)
+ .build();
}
public static ConsoleAppender createDefaultAppenderForLayout(final
Layout<? extends Serializable> layout) {
@@ -194,7 +176,7 @@ public final class ConsoleAppender extends
AbstractOutputStreamAppender<OutputSt
"DefaultConsole-" + COUNT.incrementAndGet(),
layout,
null,
- getDefaultManager(DEFAULT_TARGET, false, false, layout),
+ getDefaultManager(layout),
true,
DEFAULT_TARGET,
null);
@@ -242,85 +224,42 @@ public final class ConsoleAppender extends
AbstractOutputStreamAppender<OutputSt
if (!isValid()) {
return null;
}
- 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<? extends Serializable> layout =
getOrCreateLayout(target.getDefaultCharset());
+
+ 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),
- 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<? extends Serializable> layout) {
- final OutputStream os = getOutputStream(follow, direct, target);
-
+ private static OutputStreamManager getDefaultManager(final Layout<?
extends Serializable> layout) {
+ final OutputStream os =
getDefaultOutputStream(ConsoleAppender.DEFAULT_TARGET);
// 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<? extends Serializable> layout) {
- final OutputStream os = getOutputStream(follow, direct, target);
- 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 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);
- }
- final PropertiesUtil propsUtil = PropertiesUtil.getProperties();
- if (!propsUtil.isOsWindows() ||
propsUtil.getBooleanProperty("log4j.skipJansi", true) || 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/ThrowableFormatOptions.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
index 5df74e5d9c..74bc937ab6 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
@@ -23,9 +23,7 @@ import
org.apache.logging.log4j.core.pattern.JAnsiTextRenderer;
import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
import org.apache.logging.log4j.core.pattern.TextRenderer;
import org.apache.logging.log4j.core.util.Integers;
-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;
/**
@@ -290,17 +288,11 @@ public final class ThrowableFormatOptions {
|| 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 JAnsiTextRenderer(
+ new String[] {null, styleMapStr},
JAnsiTextRenderer.DefaultExceptionStyleMap);
} 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/impl/package-info.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/package-info.java
index 2d4bdcd199..666e8325ed 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/package-info.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/package-info.java
@@ -18,7 +18,7 @@
* Log4j 2 private implementation classes.
*/
@Export
-@Version("2.25.0")
+@Version("2.24.1")
package org.apache.logging.log4j.core.impl;
import org.osgi.annotation.bundle.Export;
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 a915cdadfb..5f6e429927 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
@@ -38,7 +38,6 @@ 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.util.PropertiesUtil;
import org.apache.logging.log4j.util.Strings;
/**
@@ -652,7 +651,7 @@ public final class PatternLayout extends
AbstractStringLayout {
private boolean alwaysWriteExceptions = true;
@PluginBuilderAttribute
- private boolean disableAnsi = !useAnsiEscapeCodes();
+ private boolean disableAnsi;
@PluginBuilderAttribute
private boolean noConsoleNoAnsi;
@@ -665,13 +664,6 @@ public final class PatternLayout extends
AbstractStringLayout {
private Builder() {}
- private boolean useAnsiEscapeCodes() {
- final PropertiesUtil propertiesUtil =
PropertiesUtil.getProperties();
- final boolean isPlatformSupportsAnsi =
!propertiesUtil.isOsWindows();
- final boolean isJansiRequested =
!propertiesUtil.getBooleanProperty("log4j.skipJansi", true);
- return isPlatformSupportsAnsi || isJansiRequested;
- }
-
/**
* @param pattern
* The pattern. If not specified, defaults to
DEFAULT_CONVERSION_PATTERN.
@@ -731,8 +723,7 @@ public final class PatternLayout extends
AbstractStringLayout {
/**
* @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 withDisableAnsi(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 74633b10a1..34213373df 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
@@ -421,6 +421,11 @@ public enum AnsiEscape {
* @return a new map
*/
public static Map<String, String> createMap(final String[] values, final
String[] dontEscapeKeys) {
+ return createMap(values, dontEscapeKeys, "\\s");
+ }
+
+ static Map<String, String> 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<String, String> map = new HashMap<>();
@@ -430,7 +435,7 @@ public enum AnsiEscape {
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);
} else {
LOGGER.warn("Syntax error, missing '=': Expected
\"{KEY1=VALUE, KEY2=VALUE, ...}");
}
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
index b952957345..072dfeb87f 100644
---
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
@@ -16,28 +16,31 @@
*/
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 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.AbstractMap;
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;
-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.
- *
+ * <p>
+ * Uses the
+ * <a
href="https://www.javadoc.io/doc/org.jline/jline/latest/org/jline/jansi/AnsiRenderer.html">JLine
AnsiRenderer syntax</a>
+ * to render a message into an ANSI escaped string.
+ * </p>
+ * <p>
* The default syntax for embedded ANSI codes is:
- *
+ * </p>
* <pre>
* @|<em>code</em>(,<em>code</em>)* <em>text</em>|@
* </pre>
@@ -72,279 +75,245 @@ import org.fusesource.jansi.AnsiRenderer.Code;
* logger.info("@|KeyStyle {}|@ = @|ValueStyle {}|@", entry.getKey(),
entry.getValue());
* </pre>
*
- * Note: This class originally copied and then heavily modified code from
JAnsi's AnsiRenderer (which is licensed as
- * Apache 2.0.)
- *
- * @see AnsiRenderer
+ * <p>
+ * <strong>Note:</strong> this class was originally copied and then
heavily modified from
+ * <a
href="https://www.javadoc.io/doc/org.jline/jline/latest/org/jline/jansi/AnsiRenderer.html">JAnsi/JLine
AnsiRenderer</a>,
+ * licensed under an Apache Software License, version 2.0.
+ * </p>
*/
public final class JAnsiTextRenderer implements TextRenderer {
- public static final Map<String, Code[]> DefaultExceptionStyleMap;
- static final Map<String, Code[]> DefaultMessageStyleMap;
- private static final Map<String, Map<String, Code[]>> PrefedinedStyleMaps;
+ private static final Logger LOGGER = StatusLogger.getLogger();
+
+ public static final Map<String, String> DefaultExceptionStyleMap;
+ static final Map<String, String> DEFAULT_MESSAGE_STYLE_MAP;
+ private static final Map<String, Map<String, String>>
PREFEDINED_STYLE_MAPS;
- private static void put(final Map<String, Code[]> map, final String name,
final Code... codes) {
- map.put(name, codes);
+ 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<String, String> 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 new AbstractMap.SimpleImmutableEntry<>(name, sb.toString());
+ }
+
+ @SafeVarargs
+ private static <V> Map<String, V> ofEntries(final Map.Entry<String, V>...
entries) {
+ final Map<String, V> map = new HashMap<>(entries.length);
+ for (final Map.Entry<String, V> entry : entries) {
+ map.put(entry.getKey(), entry.getValue());
+ }
+ return Collections.unmodifiableMap(map);
}
static {
- final Map<String, Map<String, Code[]>> tempPreDefs = new HashMap<>();
// Default style: Spock
- {
- // TODO Should the keys be in an enum?
- final Map<String, Code[]> 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.ClassLoaderName", WHITE);
- put(map, "StackTraceElement.ClassLoaderSeparator", WHITE);
- put(map, "StackTraceElement.ModuleName", WHITE);
- put(map, "StackTraceElement.ModuleVersionSeparator", WHITE);
- put(map, "StackTraceElement.ModuleVersion", WHITE);
- put(map, "StackTraceElement.ModuleNameSeparator", WHITE);
- 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);
- }
+ final Map<String, String> spock = 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.ClassLoaderName", WHITE),
+ entry("StackTraceElement.ClassLoaderSeparator", WHITE),
+ entry("StackTraceElement.ModuleName", WHITE),
+ entry("StackTraceElement.ModuleVersionSeparator", WHITE),
+ entry("StackTraceElement.ModuleVersion", WHITE),
+ entry("StackTraceElement.ModuleNameSeparator", WHITE),
+ 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
- {
- // TODO Should the keys be in an enum?
- final Map<String, Code[]> 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.ClassLoaderName", WHITE);
- put(map, "StackTraceElement.ClassLoaderSeparator", WHITE);
- put(map, "StackTraceElement.ModuleName", WHITE);
- put(map, "StackTraceElement.ModuleVersionSeparator", WHITE);
- put(map, "StackTraceElement.ModuleVersion", WHITE);
- put(map, "StackTraceElement.ModuleNameSeparator", WHITE);
- 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<String, Code[]> temp = new HashMap<>();
- // TODO
- DefaultMessageStyleMap = Collections.unmodifiableMap(temp);
- }
- PrefedinedStyleMaps = Collections.unmodifiableMap(tempPreDefs);
+ final Map<String, String> kirk = 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.ClassLoaderName", WHITE),
+ entry("StackTraceElement.ClassLoaderSeparator", WHITE),
+ entry("StackTraceElement.ModuleName", WHITE),
+ entry("StackTraceElement.ModuleVersionSeparator", WHITE),
+ entry("StackTraceElement.ModuleVersion", WHITE),
+ entry("StackTraceElement.ModuleNameSeparator", WHITE),
+ 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
+ DefaultExceptionStyleMap = spock;
+ DEFAULT_MESSAGE_STYLE_MAP = Collections.emptyMap();
+ Map<String, Map<String, String>> predefinedStyleMaps = new HashMap<>();
+ predefinedStyleMaps.put("Spock", spock);
+ predefinedStyleMaps.put("Kirk", kirk);
+ PREFEDINED_STYLE_MAPS =
Collections.unmodifiableMap(predefinedStyleMaps);
}
private final String beginToken;
private final int beginTokenLen;
private final String endToken;
private final int endTokenLen;
- private final Map<String, Code[]> styleMap;
+ private final Map<String, String> styleMap;
- public JAnsiTextRenderer(final String[] formats, final Map<String, Code[]>
defaultStyleMap) {
- String tempBeginToken = AnsiRenderer.BEGIN_TOKEN;
- String tempEndToken = AnsiRenderer.END_TOKEN;
- final Map<String, Code[]> map;
+ public JAnsiTextRenderer(final String[] formats, final Map<String, String>
defaultStyleMap) {
+ // The format string is a list of whitespace-separated expressions:
+ // Key=AnsiEscape(,AnsiEscape)*
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);
+ final String stylesStr = formats[1];
+ final Map<String, String> 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<String, String> styleMap = new HashMap<>(map.size() +
defaultStyleMap.size());
+ defaultStyleMap.forEach((k, v) -> styleMap.put(toRootUpperCase(k),
v));
+ if (predefinedStyle != null) {
+ final Map<String, String> predefinedMap =
PREFEDINED_STYLE_MAPS.get(predefinedStyle);
+ if (predefinedMap != null) {
+ map.putAll(predefinedMap);
} 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<String, Code[]> 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);
- }
- }
+ LOGGER.warn(
+ "Unknown predefined map name {}, pick one of {}",
+ predefinedStyle,
+ PREFEDINED_STYLE_MAPS.keySet());
}
}
+ styleMap.putAll(map);
+ this.styleMap = Collections.unmodifiableMap(styleMap);
} else {
- map = defaultStyleMap;
- }
- styleMap = map;
- beginToken = tempBeginToken;
- endToken = tempEndToken;
- beginTokenLen = tempBeginToken.length();
- endTokenLen = tempEndToken.length();
- }
-
- public Map<String, Code[]> 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);
+ beginToken = BEGIN_TOKEN;
+ endToken = END_TOKEN;
+ this.styleMap = Collections.unmodifiableMap(defaultStyleMap);
}
+ beginTokenLen = beginToken.length();
+ endTokenLen = endToken.length();
}
/**
- * Renders the given text with the given names which can be ANSI code
names or Log4j style names.
+ * Renders the given input with the given names which can be ANSI code
names or Log4j style names.
*
- * @param text
- * The text to render
- * @param names
+ * @param input
+ * The input to render
+ * @param styleNames
* 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);
+ 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 {
- render(ansi, toCode(name));
+ 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));
}
- 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));
+ render(input, output, styleName.split(",", -1));
}
@Override
public void render(final StringBuilder input, final StringBuilder output)
throws IllegalArgumentException {
- int i = 0;
- int j, k;
+ int pos = 0;
+ int beginTokenPos, endTokenPos;
while (true) {
- j = input.indexOf(beginToken, i);
- if (j == -1) {
- if (i == 0) {
- output.append(input);
- return;
- }
- output.append(input.substring(i, input.length()));
+ beginTokenPos = input.indexOf(beginToken, pos);
+ if (beginTokenPos == -1) {
+ output.append(pos == 0 ? input : input.substring(pos,
input.length()));
return;
}
- output.append(input.substring(i, j));
- k = input.indexOf(endToken, j);
+ output.append(input.substring(pos, beginTokenPos));
+ endTokenPos = input.indexOf(endToken, beginTokenPos);
- if (k == -1) {
- output.append(input);
+ 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;
}
- j += beginTokenLen;
- final String spec = input.substring(j, k);
+ beginTokenPos += beginTokenLen;
+ final String spec = input.substring(beginTokenPos, endTokenPos);
- final String[] items =
spec.split(AnsiRenderer.CODE_TEXT_SEPARATOR, 2);
+ final String[] items = spec.split("\\s", 2);
if (items.length == 1) {
- output.append(input);
- return;
+ 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));
}
- final String replacement = render(items[1], items[0].split(","));
-
- output.append(replacement);
-
- i = k + endTokenLen;
+ pos = endTokenPos + endTokenLen;
}
}
- private Code toCode(final String name) {
- return Code.valueOf(toRootUpperCase(name));
+ public Map<String, String> getStyleMap() {
+ return styleMap;
}
@Override
public String toString() {
- return "JAnsiMessageRenderer [beginToken=" + beginToken + ",
beginTokenLen=" + beginTokenLen + ", endToken="
+ 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/MessagePatternConverter.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java
index 44016664af..dd7df75faf 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
@@ -23,10 +23,8 @@ 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.config.plugins.Plugin;
-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.status.StatusLogger;
import org.apache.logging.log4j.util.MultiFormatStringBuilderFormattable;
import org.apache.logging.log4j.util.PerformanceSensitive;
import org.apache.logging.log4j.util.StringBuilderFormattable;
@@ -52,12 +50,7 @@ public class MessagePatternConverter extends
LogEventPatternConverter {
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 JAnsiTextRenderer(options,
JAnsiTextRenderer.DEFAULT_MESSAGE_STYLE_MAP);
case "HTML":
return new HtmlTextRenderer(options);
}
diff --git
a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/package-info.java
b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/package-info.java
index 5c047848b5..ac6407f47b 100644
---
a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/package-info.java
+++
b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/package-info.java
@@ -18,7 +18,7 @@
* Provides classes implementing format specifiers in conversion patterns.
*/
@Export
-@Version("2.25.0")
+@Version("2.24.1")
package org.apache.logging.log4j.core.pattern;
import org.osgi.annotation.bundle.Export;
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 64ee6be359..4ae5d46335 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
@@ -349,6 +349,10 @@ public final class Loader {
}
}
+ /**
+ * @deprecated Since 2.25.0 without a replacement.
+ */
+ @Deprecated
public static boolean isJansiAvailable() {
return isClassAvailable("org.fusesource.jansi.AnsiRenderer");
}
diff --git
a/log4j-jakarta-smtp/src/test/java/org/apache/logging/log4j/smtp/SmtpAppenderAsyncTest.java
b/log4j-jakarta-smtp/src/test/java/org/apache/logging/log4j/smtp/SmtpAppenderAsyncTest.java
index 0dbd426d30..f460c5c607 100644
---
a/log4j-jakarta-smtp/src/test/java/org/apache/logging/log4j/smtp/SmtpAppenderAsyncTest.java
+++
b/log4j-jakarta-smtp/src/test/java/org/apache/logging/log4j/smtp/SmtpAppenderAsyncTest.java
@@ -16,8 +16,8 @@
*/
package org.apache.logging.log4j.smtp;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
import java.util.Iterator;
import org.apache.logging.log4j.ThreadContext;
diff --git a/log4j-parent/pom.xml b/log4j-parent/pom.xml
index 4c82d04e14..3ae996ef97 100644
--- a/log4j-parent/pom.xml
+++ b/log4j-parent/pom.xml
@@ -100,7 +100,6 @@
<javax-persistence.version>2.2</javax-persistence.version>
<javax-servlet.version>4.0.1</javax-servlet.version>
<javax-servlet-jsp.version>2.3.3</javax-servlet-jsp.version>
- <jansi.version>2.4.1</jansi.version>
<java-allocation-instrumenter.version>3.3.4</java-allocation-instrumenter.version>
<jazzer.version>0.22.1</jazzer.version>
<jconsole.version>1.7.0</jconsole.version>
@@ -471,12 +470,6 @@
<version>${jakarta-mail.version}</version>
</dependency>
- <dependency>
- <groupId>org.fusesource.jansi</groupId>
- <artifactId>jansi</artifactId>
- <version>${jansi.version}</version>
- </dependency>
-
<!-- Used for garbage-free tests: -->
<dependency>
<groupId>com.google.code.java-allocation-instrumenter</groupId>
diff --git a/pom.xml b/pom.xml
index 03760b9eb0..88bf7db62f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -345,7 +345,6 @@
<site-disruptor.version>4.0.0</site-disruptor.version>
<site-flume.version>1.11.0</site-flume.version>
<site-jackson.version>2.18.0</site-jackson.version>
- <site-jansi.version>1.18</site-jansi.version>
<site-javax-mail.version>1.6.2</site-javax-mail.version>
<site-jctools.version>4.0.5</site-jctools.version>
<site-je.version>18.3.12</site-je.version>
@@ -769,12 +768,6 @@
<type>pom</type>
</dependency>
- <dependency>
- <groupId>org.fusesource.jansi</groupId>
- <artifactId>jansi</artifactId>
- <version>${site-jansi.version}</version>
- </dependency>
-
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
diff --git a/src/changelog/.2.x.x/.release-notes.adoc.ftl
b/src/changelog/.2.x.x/.release-notes.adoc.ftl
index 16be1ddfc7..47b4447337 100644
--- a/src/changelog/.2.x.x/.release-notes.adoc.ftl
+++ b/src/changelog/.2.x.x/.release-notes.adoc.ftl
@@ -38,4 +38,10 @@ This effectively helped with fixing some bugs by matching
the feature parity of
Additionally, rendered stack traces are ensured to be prefixed with a newline,
which used to be a whitespace in earlier versions.
The support for the `\{ansi}` option in exception converters is removed too.
+=== ANSI support on Windows
+
+Since 2017, Windows 10 and newer have offered native support for ANSI escapes.
+The support for the outdated Jansi 1.x library has therefore been removed.
+See xref:manual/pattern-layout.adoc#jansi[ANSI styling on Windows] for more
information.
+
<#include "../.changelog.adoc.ftl">
diff --git a/src/changelog/.2.x.x/1736_split_jansi_support.xml
b/src/changelog/.2.x.x/1736_split_jansi_support.xml
new file mode 100644
index 0000000000..a585fed74f
--- /dev/null
+++ b/src/changelog/.2.x.x/1736_split_jansi_support.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="https://logging.apache.org/xml/ns"
+ xsi:schemaLocation="https://logging.apache.org/xml/ns
https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
+ type="changed">
+ <issue id="1736"
link="https://github.com/apache/logging-log4j2/issues/1736"/>
+ <description format="asciidoc">Remove JAnsi library support. Windows 10
console has supported ANSI escapes since 2017.</description>
+</entry>
diff --git a/src/changelog/.2.x.x/2916_rewrite_jansi_renderer.xml
b/src/changelog/.2.x.x/2916_rewrite_jansi_renderer.xml
new file mode 100644
index 0000000000..7fad82b6d5
--- /dev/null
+++ b/src/changelog/.2.x.x/2916_rewrite_jansi_renderer.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="https://logging.apache.org/xml/ns"
+ xsi:schemaLocation="https://logging.apache.org/xml/ns
https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
+ type="changed">
+ <issue id="2916" link="https://github.com/apache/logging-log4j2/pull/2916"/>
+ <description format="asciidoc">Rewrite `JAnsiTextRenderer` to work without
JAnsi library.</description>
+</entry>
diff --git a/src/site/antora/antora.tmpl.yml b/src/site/antora/antora.tmpl.yml
index 8ec9a597b2..7cdcf41ecf 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}"
javax-mail-version: "${site-javax-mail.version}"
jctools-version: "${site-jctools.version}"
je-version: "${site-je.version}"
diff --git a/src/site/antora/antora.yml b/src/site/antora/antora.yml
index 21652d7e98..ff6edf566a 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"
javax-mail-version: "1.2.3-javax-mail"
jctools-version: "1.2.3-jctools"
je-version: "1.2.3-je"
diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
index 6f0c4aaad7..a43675fb54 100644
--- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
@@ -216,7 +216,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.
@@ -236,39 +236,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 disabled by setting the
-xref:manual/systemproperties.adoc#log4j2.skipJansi[`log4j2.skipJansi`]
-configuration attribute to `true`.
-+
-Additional runtime dependencies are required to use JANSI:
-+
-[tabs]
-====
-Maven::
-+
-[source,xml,subs="+attributes"]
-----
-<dependency>
- <groupId>org.fusesource.jansi</groupId>
- <artifactId>jansi</artifactId>
- <version>{jansi-version}</version>
-</dependency>
-
-----
-
-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
-<<ConsoleAppender-attr-follow,`follow` attribute>>
-and
-xref:manual/systemproperties.adoc#log4j2.skipJansi[JANSI support].
+<<ConsoleAppender-attr-follow,`follow` attribute>>.
| [[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
-<<ConsoleAppender-attr-direct,`direct` attribute>>
-and
-xref:manual/systemproperties.adoc#log4j2.skipJansi[JANSI support].
+<<ConsoleAppender-attr-direct,`direct` attribute>>.
| [[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 1817b38822..4972398648 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
@@ -1598,19 +1598,14 @@ If your terminal supports 24-bit colors, you can
specify:
[#jansi]
==== 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#log4j2.skipJansi[the `log4j2.skipJansi`
system property] to `false`.
-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 are
disabled by default in `cmd.exe` on Windows.
+To enable ANSI escape sequences, create a registry key named
`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 2bd4b6e75e..318c745e10 100644
--- a/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc
@@ -149,13 +149,6 @@
include::partial$manual/systemproperties/properties-configuration-factory.adoc[l
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-jmx]
=== JMX
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 6b58ac8c58..0000000000
---
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=log4j2.skipJansi]
-== `log4j2.skipJansi`
-
-[cols="1h,5"]
-|===
-| Env. variable | `LOG4J_SKIP_JANSI`
-| Type | `boolean`
-| Default value | `true`
-|===
-
-If the following conditions are satisfied:
-
-* Log4j runs on Windows,
-* this property is set to `false`,
-
-Log4j will use the JANSI library to color the output of the console appender.
\ No newline at end of file