*/
public class ConsoleAppenderNoAnsiStyleLayoutMain {
@@ -43,12 +43,11 @@ private static void logThrowableFromMethod() {
public static void main(final String[] args) {
final String config = args.length == 0 ? "target/test-classes/log4j2-console-style-no-ansi.xml" : args[0];
- test(args, config);
+ test(config);
}
- static void test(final String[] args, final String config) {
- // System.out.println(System.getProperty("java.class.path"));
- try (final LoggerContext ctx =
+ static void test(final String config) {
+ try (final LoggerContext ignored =
Configurator.initialize(ConsoleAppenderNoAnsiStyleLayoutMain.class.getName(), config)) {
LOG.fatal("Fatal message.");
LOG.error("Error message.");
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
index 5eba5acbd73..4e77e0c4331 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/ConsoleAppenderTest.java
@@ -33,9 +33,7 @@
import org.apache.logging.log4j.core.appender.ConsoleAppender.Target;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
import org.apache.logging.log4j.core.layout.PatternLayout;
-import org.apache.logging.log4j.core.test.TestConstants;
import org.apache.logging.log4j.message.SimpleMessage;
-import org.apache.logging.log4j.test.junit.SetTestProperty;
import org.apache.logging.log4j.util.Strings;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -44,7 +42,6 @@
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
-@SetTestProperty(key = TestConstants.CONSOLE_JANSI_ENABLED, value = "false")
public class ConsoleAppenderTest {
ByteArrayOutputStream baos;
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/JansiConsoleAppenderJira965.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/JansiConsoleAppenderJira965.java
deleted file mode 100644
index 8bdd3e13efe..00000000000
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/appender/JansiConsoleAppenderJira965.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to you under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.logging.log4j.core.appender;
-
-import org.slf4j.LoggerFactory;
-
-public class JansiConsoleAppenderJira965 {
-
- public static void main(final String[] args) {
- System.out.println("Able to print on Windows");
- LoggerFactory.getLogger(JansiConsoleAppenderJira965.class);
- System.out.println("Unable to print on Windows");
- }
-}
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
index 339c1b0e6d2..5323eace0ec 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptionsTest.java
@@ -28,7 +28,7 @@
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.AnsiTextRenderer;
import org.apache.logging.log4j.core.pattern.TextRenderer;
import org.apache.logging.log4j.util.Strings;
import org.junit.jupiter.api.Test;
@@ -131,9 +131,9 @@ void testFullAnsiEmptyConfig() {
private void testFullAnsiEmptyConfig(final ThrowableFormatOptions tfo) {
final TextRenderer textRenderer = tfo.getTextRenderer();
assertNotNull(textRenderer);
- assertInstanceOf(JAnsiTextRenderer.class, textRenderer);
- final JAnsiTextRenderer jansiRenderer = (JAnsiTextRenderer) textRenderer;
- final Map styleMap = jansiRenderer.getStyleMap();
+ assertInstanceOf(AnsiTextRenderer.class, textRenderer);
+ final AnsiTextRenderer ansiRenderer = (AnsiTextRenderer) textRenderer;
+ final Map styleMap = ansiRenderer.getStyleMap();
// We have defaults
assertFalse(styleMap.isEmpty());
assertNotNull(styleMap.get(toRootUpperCase("Name")));
@@ -148,9 +148,9 @@ void testFullAnsiWithCustomStyle() {
test(new String[] {"full", "ansi(Warning=red)"}, Integer.MAX_VALUE, Strings.LINE_SEPARATOR, null);
final TextRenderer textRenderer = tfo.getTextRenderer();
assertNotNull(textRenderer);
- assertInstanceOf(JAnsiTextRenderer.class, textRenderer);
- final JAnsiTextRenderer jansiRenderer = (JAnsiTextRenderer) textRenderer;
- final Map styleMap = jansiRenderer.getStyleMap();
+ assertInstanceOf(AnsiTextRenderer.class, textRenderer);
+ final AnsiTextRenderer ansiRenderer = (AnsiTextRenderer) textRenderer;
+ final Map styleMap = ansiRenderer.getStyleMap();
assertThat(styleMap.get(toRootUpperCase("Warning"))).isEqualTo(AnsiEscape.createSequence("RED"));
}
@@ -166,9 +166,9 @@ void testFullAnsiWithCustomStyles() {
null);
final TextRenderer textRenderer = tfo.getTextRenderer();
assertNotNull(textRenderer);
- assertInstanceOf(JAnsiTextRenderer.class, textRenderer);
- final JAnsiTextRenderer jansiRenderer = (JAnsiTextRenderer) textRenderer;
- final Map styleMap = jansiRenderer.getStyleMap();
+ assertInstanceOf(AnsiTextRenderer.class, textRenderer);
+ final AnsiTextRenderer ansiRenderer = (AnsiTextRenderer) textRenderer;
+ final Map styleMap = ansiRenderer.getStyleMap();
assertThat(styleMap.get(toRootUpperCase("Warning"))).isEqualTo(AnsiEscape.createSequence("RED"));
assertThat(styleMap.get(toRootUpperCase("Key"))).isEqualTo(AnsiEscape.createSequence("BLUE"));
assertThat(styleMap.get(toRootUpperCase("Value"))).isEqualTo(AnsiEscape.createSequence("CYAN"));
@@ -186,9 +186,9 @@ void testFullAnsiWithCustomComplexStyles() {
null);
final TextRenderer textRenderer = tfo.getTextRenderer();
assertNotNull(textRenderer);
- assertInstanceOf(JAnsiTextRenderer.class, textRenderer);
- final JAnsiTextRenderer jansiRenderer = (JAnsiTextRenderer) textRenderer;
- final Map styleMap = jansiRenderer.getStyleMap();
+ assertInstanceOf(AnsiTextRenderer.class, textRenderer);
+ final AnsiTextRenderer ansiRenderer = (AnsiTextRenderer) textRenderer;
+ final Map styleMap = ansiRenderer.getStyleMap();
assertThat(styleMap.get(toRootUpperCase("Warning"))).isEqualTo(AnsiEscape.createSequence("RED"));
assertThat(styleMap.get(toRootUpperCase("Key"))).isEqualTo(AnsiEscape.createSequence("BLUE", "BG_RED"));
assertThat(styleMap.get(toRootUpperCase("Value")))
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/AnsiTextRendererTest.java
similarity index 94%
rename from log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/JAnsiTextRendererTest.java
rename to log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/AnsiTextRendererTest.java
index 32a07d35f8f..17e590a86a2 100644
--- 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/AnsiTextRendererTest.java
@@ -25,7 +25,7 @@
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
-class JAnsiTextRendererTest {
+class AnsiTextRendererTest {
public static Stream testRendering() {
return Stream.of(
@@ -47,7 +47,7 @@ public static Stream testRendering() {
@ParameterizedTest
@MethodSource
void testRendering(final String format, final String text, final String expected) {
- final JAnsiTextRenderer renderer = new JAnsiTextRenderer(new String[] {"ansi", format}, Map.of());
+ final AnsiTextRenderer renderer = new AnsiTextRenderer(new String[] {"ansi", format}, Map.of());
final StringBuilder actual = new StringBuilder();
renderer.render(new StringBuilder(text), actual);
assertThat(actual.toString())
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageJansiConverterTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageAnsiConverterTest.java
similarity index 94%
rename from log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageJansiConverterTest.java
rename to log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageAnsiConverterTest.java
index 293db30ba99..670fefd097f 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageJansiConverterTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageAnsiConverterTest.java
@@ -31,7 +31,7 @@
import org.junit.jupiter.api.Test;
@LoggerContextSource("log4j-message-ansi.xml")
-public class MessageJansiConverterTest {
+public class MessageAnsiConverterTest {
private static final String EXPECTED =
"\u001B[31;1mWarning!\u001B[m Pants on \u001B[31mfire!\u001B[m" + Strings.LINE_SEPARATOR;
@@ -47,7 +47,7 @@ public void setUp(final LoggerContext context, @Named("List") final ListAppender
@Test
public void testReplacement() {
- // See org.fusesource.jansi.AnsiRenderer
+ // See https://www.javadoc.io/doc/org.jline/jline/latest/org/jline/jansi/AnsiRenderer.html
logger.error("@|red,bold Warning!|@ Pants on @|red fire!|@");
final List msgs = app.getMessages();
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageStyledConverterTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageStyledConverterTest.java
index 71fb6fbc77b..06ab681fedd 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageStyledConverterTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/MessageStyledConverterTest.java
@@ -47,7 +47,7 @@ public void setUp(final LoggerContext context, @Named("List") final ListAppender
@Test
public void testReplacement() {
- // See org.fusesource.jansi.AnsiRenderer
+ // See https://www.javadoc.io/doc/org.jline/jline/latest/org/jline/jansi/AnsiRenderer.html
logger.error("@|WarningStyle Warning!|@ Pants on @|WarningStyle fire!|@");
final List msgs = app.getMessages();
diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/StyleConverterTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/StyleConverterTest.java
index 6a5a77951fa..01b3f51d306 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/StyleConverterTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/StyleConverterTest.java
@@ -26,19 +26,16 @@
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.impl.Log4jLogEvent;
-import org.apache.logging.log4j.core.test.TestConstants;
import org.apache.logging.log4j.core.test.appender.ListAppender;
import org.apache.logging.log4j.core.test.junit.LoggerContextSource;
import org.apache.logging.log4j.core.test.junit.Named;
import org.apache.logging.log4j.test.ListStatusListener;
-import org.apache.logging.log4j.test.junit.SetTestProperty;
import org.apache.logging.log4j.test.junit.UsingStatusListener;
import org.apache.logging.log4j.util.Strings;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
-@SetTestProperty(key = TestConstants.CONSOLE_JANSI_ENABLED, value = "true")
public class StyleConverterTest {
private static final String EXPECTED =
diff --git a/log4j-core/pom.xml b/log4j-core/pom.xml
index 8819a023a93..b2b00b30d82 100644
--- a/log4j-core/pom.xml
+++ b/log4j-core/pom.xml
@@ -98,13 +98,6 @@
log4j-plugins
-
-
- org.fusesource.jansi
- jansi
- true
-
-
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
index f25c3924bdb..10e42356b03 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
@@ -54,7 +54,6 @@
public final class ConsoleAppender extends AbstractOutputStreamAppender {
public static final String PLUGIN_NAME = "Console";
- private static final String JANSI_CLASS = "org.fusesource.jansi.WindowsAnsiOutputStream";
private static final ConsoleManagerFactory factory = new ConsoleManagerFactory();
private static final Target DEFAULT_TARGET = Target.SYSTEM_OUT;
private static final AtomicInteger COUNT = new AtomicInteger();
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 34d02d68454..07a5d4ab249 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThrowableFormatOptions.java
@@ -19,7 +19,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
-import org.apache.logging.log4j.core.pattern.JAnsiTextRenderer;
+import org.apache.logging.log4j.core.pattern.AnsiTextRenderer;
import org.apache.logging.log4j.core.pattern.PlainTextRenderer;
import org.apache.logging.log4j.core.pattern.TextRenderer;
import org.apache.logging.log4j.core.util.Patterns;
@@ -290,8 +290,8 @@ public static ThrowableFormatOptions newInstance(String[] options) {
final String styleMapStr = option.equals("ansi")
? Strings.EMPTY
: option.substring("ansi(".length(), option.length() - 1);
- ansiRenderer = new JAnsiTextRenderer(
- new String[] {null, styleMapStr}, JAnsiTextRenderer.DEFAULT_EXCEPTION_STYLE_MAP);
+ ansiRenderer = new AnsiTextRenderer(
+ new String[] {null, styleMapStr}, AnsiTextRenderer.DEFAULT_EXCEPTION_STYLE_MAP);
} else if (option.startsWith("S(") && option.endsWith(")")) {
suffix = option.substring("S(".length(), option.length() - 1);
} else if (option.startsWith("suffix(") && option.endsWith(")")) {
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
index a0bb6b0a146..b9b3f9f7dc9 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/PatternLayout.java
@@ -644,8 +644,7 @@ public Builder setAlwaysWriteExceptions(final boolean alwaysWriteExceptions) {
/**
* @param disableAnsi
- * If {@code "true"} (default is value of system property `log4j.skipJansi`, or `true` if undefined),
- * do not output ANSI escape codes
+ * If {@code true}, do not output ANSI escape codes.
*/
public Builder setDisableAnsi(final boolean disableAnsi) {
this.disableAnsi = disableAnsi;
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/JAnsiTextRenderer.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiTextRenderer.java
similarity index 93%
rename from log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/JAnsiTextRenderer.java
rename to log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/AnsiTextRenderer.java
index e58a64de21e..84382815b5e 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/AnsiTextRenderer.java
@@ -33,7 +33,9 @@
/**
* Renders an input as ANSI escaped output.
*
- * Uses the JAnsi rendering syntax as the default to render a message into an ANSI escaped string.
+ * Uses the
+ * JLine AnsiRenderer syntax
+ * to render a message into an ANSI escaped string.
*
*
* The default syntax for embedded ANSI codes is:
@@ -72,10 +74,13 @@
* logger.info("@|KeyStyle {}|@ = @|ValueStyle {}|@", entry.getKey(), entry.getValue());
*
*
- * Note: This class originally copied and then heavily modified code from JAnsi's AnsiRenderer (which is licensed as
- * Apache 2.0.)
+ *
+ * Note: this class was originally copied and then heavily modified from
+ * JAnsi/JLine AnsiRenderer,
+ * licensed under an Apache Software License, version 2.0.
+ *
*/
-public final class JAnsiTextRenderer implements TextRenderer {
+public final class AnsiTextRenderer implements TextRenderer {
private static final Logger LOGGER = StatusLogger.getLogger();
@@ -165,7 +170,7 @@ private static Map.Entry entry(final String name, final AnsiEsca
private final int endTokenLen;
private final Map styleMap;
- public JAnsiTextRenderer(final String[] formats, final Map defaultStyleMap) {
+ public AnsiTextRenderer(final String[] formats, final Map defaultStyleMap) {
// The format string is a list of whitespace-separated expressions:
// Key=AnsiEscape(,AnsiEscape)*
if (formats.length > 1) {
@@ -283,7 +288,7 @@ public Map getStyleMap() {
@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 a53a4613656..f323dd93064 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MessagePatternConverter.java
@@ -52,7 +52,7 @@ private static TextRenderer loadMessageRenderer(final String[] options) {
for (final String option : options) {
switch (toRootUpperCase(option)) {
case "ANSI":
- return new JAnsiTextRenderer(options, JAnsiTextRenderer.DEFAULT_MESSAGE_STYLE_MAP);
+ return new AnsiTextRenderer(options, AnsiTextRenderer.DEFAULT_MESSAGE_STYLE_MAP);
case "HTML":
return new HtmlTextRenderer(options);
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
index 84667ce9483..2e86daf2ca3 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/Loader.java
@@ -275,26 +275,6 @@ public static T newInstanceOf(final Class clazz)
}
}
- /**
- * Determines if a named Class can be loaded or not.
- *
- * @param className The class name.
- * @return {@code true} if the class could be found or {@code false} otherwise.
- */
- public static boolean isClassAvailable(final String className) {
- final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
- try {
- Thread.currentThread().setContextClassLoader(getClassLoader());
- return LoaderUtil.isClassAvailable(className);
- } finally {
- Thread.currentThread().setContextClassLoader(contextClassLoader);
- }
- }
-
- public static boolean isJansiAvailable() {
- return isClassAvailable("org.fusesource.jansi.AnsiRenderer");
- }
-
/**
* Loads a class by name. This method respects the {@link LoaderProperties#ignoreTccl()} Log4j property. If this
* property is
diff --git a/log4j-core/src/main/resources/Log4j-config.xsd b/log4j-core/src/main/resources/Log4j-config.xsd
index c17d1c59e3f..3ff224097a0 100644
--- a/log4j-core/src/main/resources/Log4j-config.xsd
+++ b/log4j-core/src/main/resources/Log4j-config.xsd
@@ -696,7 +696,7 @@
Write directly to java.io.FileDescriptor and bypass java.lang.System.out/.err. Can give up to 10x performance boost when the
- output is redirected to file or other process. Cannot be used with Jansi on Windows. Cannot be used with follow.
+ output is redirected to file or other process. Cannot be used with follow.
@@ -704,7 +704,7 @@
Identifies whether the appender honors reassignments of System.out or System.err via System.setOut or System.setErr made after
- configuration. Note that the follow attribute cannot be used with Jansi on Windows. Cannot be used with direct.
+ configuration. Cannot be used with direct.
diff --git a/log4j-jansi/.log4j-plugin-processing-activator b/log4j-jansi/.log4j-plugin-processing-activator
deleted file mode 100644
index ba133f36961..00000000000
--- a/log4j-jansi/.log4j-plugin-processing-activator
+++ /dev/null
@@ -1 +0,0 @@
-This file is here to activate the `plugin-processing` Maven profile.
diff --git a/log4j-jansi/pom.xml b/log4j-jansi/pom.xml
deleted file mode 100644
index 3b6f0c8454c..00000000000
--- a/log4j-jansi/pom.xml
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
-
- 4.0.0
-
- org.apache.logging.log4j
- log4j
- ${revision}
- ../log4j-parent
-
-
- log4j-jansi
- Apache Log4j Core: JANSI support
- Support for JANSI library for Log4j Core.
-
-
- 3.26.3
-
-
-
-
-
- org.jline
- jansi-core
- ${jline.version}
-
-
-
-
-
-
-
- org.apache.logging.log4j
- log4j-core
-
-
-
- org.apache.logging.log4j
- log4j-kit
-
-
-
- org.apache.logging.log4j
- log4j-plugins
-
-
-
- org.jline
- jansi-core
-
-
-
- org.assertj
- assertj-core
- test
-
-
-
- org.junit.jupiter
- junit-jupiter-api
- test
-
-
-
- org.junit.jupiter
- junit-jupiter-engine
- test
-
-
-
- org.apache.logging.log4j
- log4j-core-test
- test
-
-
- org.hamcrest
- hamcrest
-
-
- junit
- junit
-
-
- org.junit.vintage
- junit-vintage-engine
-
-
-
-
-
-
diff --git a/log4j-jansi/src/main/java/org/apache/logging/log4j/jansi/JansiConsoleStreamSupplier.java b/log4j-jansi/src/main/java/org/apache/logging/log4j/jansi/JansiConsoleStreamSupplier.java
deleted file mode 100644
index c00313e3f43..00000000000
--- a/log4j-jansi/src/main/java/org/apache/logging/log4j/jansi/JansiConsoleStreamSupplier.java
+++ /dev/null
@@ -1,56 +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.jansi;
-
-import java.io.OutputStream;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.appender.ConsoleAppender;
-import org.apache.logging.log4j.core.util.CloseShieldOutputStream;
-import org.apache.logging.log4j.kit.env.PropertyEnvironment;
-import org.apache.logging.log4j.plugins.Namespace;
-import org.apache.logging.log4j.plugins.Ordered;
-import org.apache.logging.log4j.plugins.Plugin;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.jline.jansi.AnsiConsole;
-import org.jspecify.annotations.Nullable;
-
-/**
- * Uses the JAnsi library to provide standard output and error.
- */
-@Plugin
-@Namespace(ConsoleAppender.ConsoleStreamSupplier.NAMESPACE)
-@Ordered(0)
-public class JansiConsoleStreamSupplier implements ConsoleAppender.ConsoleStreamSupplier {
-
- private static final Logger LOGGER = StatusLogger.getLogger();
-
- @Override
- public @Nullable OutputStream getOutputStream(
- boolean follow, boolean direct, ConsoleAppender.Target target, PropertyEnvironment properties) {
- if (properties.getProperty(JansiProperties.class).jansiEnabled()) {
- if (follow || direct) {
- LOGGER.error(
- "Can not use neither `follow` nor `direct` on ConsoleAppender, since JAnsi library is used.");
- return null;
- }
- return new CloseShieldOutputStream(
- target == ConsoleAppender.Target.SYSTEM_ERR ? AnsiConsole.err() : AnsiConsole.out());
- }
- LOGGER.debug("Ignoring JAnsi library since configuration property `log4j.console.jansiEnabled` is false.");
- return null;
- }
-}
diff --git a/log4j-jansi/src/main/java/org/apache/logging/log4j/jansi/JansiProperties.java b/log4j-jansi/src/main/java/org/apache/logging/log4j/jansi/JansiProperties.java
deleted file mode 100644
index 8a48b1d8a55..00000000000
--- a/log4j-jansi/src/main/java/org/apache/logging/log4j/jansi/JansiProperties.java
+++ /dev/null
@@ -1,27 +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.jansi;
-
-import org.apache.logging.log4j.kit.env.Log4jProperty;
-
-/**
- * Properties to tune console output.
- *
- * @param jansiEnabled If {@code true}, the JAnsi library will be used whenever available.
- */
-@Log4jProperty(name = "console")
-public record JansiProperties(@Log4jProperty(defaultValue = "true") boolean jansiEnabled) {}
diff --git a/log4j-jansi/src/main/java/org/apache/logging/log4j/jansi/package-info.java b/log4j-jansi/src/main/java/org/apache/logging/log4j/jansi/package-info.java
deleted file mode 100644
index cc1d9000c6f..00000000000
--- a/log4j-jansi/src/main/java/org/apache/logging/log4j/jansi/package-info.java
+++ /dev/null
@@ -1,22 +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.
- */
-@Export
-@Version("3.0.0")
-package org.apache.logging.log4j.jansi;
-
-import org.osgi.annotation.bundle.Export;
-import org.osgi.annotation.versioning.Version;
diff --git a/log4j-jansi/src/test/java/org/apache/logging/log4j/jansi/ConsoleAppenderJAnsiMessageMain.java b/log4j-jansi/src/test/java/org/apache/logging/log4j/jansi/ConsoleAppenderJAnsiMessageMain.java
deleted file mode 100644
index cbb20094f97..00000000000
--- a/log4j-jansi/src/test/java/org/apache/logging/log4j/jansi/ConsoleAppenderJAnsiMessageMain.java
+++ /dev/null
@@ -1,66 +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.jansi;
-
-import static org.jline.jansi.Ansi.Color.CYAN;
-import static org.jline.jansi.Ansi.Color.RED;
-import static org.jline.jansi.Ansi.ansi;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-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.util.NetUtils;
-
-/**
- * Shows how to use ANSI escape codes to color messages. Each message is printed to the console in color, but the rest
- * of the log entry (time stamp for example) is in the default color for that console.
- *
- * Running from a Windows command line from the root of the project:
- *
- */
-public class ConsoleAppenderJAnsiMessageMain {
-
- public static void main(final String[] args) throws URISyntaxException {
- new ConsoleAppenderJAnsiMessageMain().test(args);
- }
-
- public void test(final String[] args) throws URISyntaxException {
- final URI config = args == null || args.length == 0
- ? ConsoleAppenderJAnsiMessageMain.class
- .getResource("/ConsoleAppenderJAnsiMessageMain.xml")
- .toURI()
- : NetUtils.toURI(args[0]);
- try (final LoggerContext ctx =
- Configurator.initialize(getClass().getName(), getClass().getClassLoader(), config)) {
- final Logger logger = LogManager.getLogger();
- logger.info(ansi().fg(RED).a("Hello").fg(CYAN).a(" World").reset());
- // JAnsi format:
- // logger.info("@|red Hello|@ @|cyan World|@");
- for (final Entry
-
- org.apache.logging.log4j
- log4j-jansi
- ${project.version}
-
-
org.apache.logging.log4jlog4j-jctools
@@ -823,12 +815,6 @@
${site-flume.version}
-
- org.fusesource.jansi
- jansi
- ${site-jansi.version}
-
-
com.sleepycatje
diff --git a/src/changelog/.3.x.x/1736_split_jansi_support.xml b/src/changelog/.3.x.x/1736_split_jansi_support.xml
index 2220a452047..1005cb42a05 100644
--- a/src/changelog/.3.x.x/1736_split_jansi_support.xml
+++ b/src/changelog/.3.x.x/1736_split_jansi_support.xml
@@ -4,5 +4,5 @@
xsi:schemaLocation="https://logging.apache.org/xml/ns https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
type="changed">
- Move JAnsi support to a new `log4j-jansi` module and upgrade to version 2.x of the library.
+ Remove JAnsi library support, since Windows console supports ANSI escapes now.
diff --git a/src/site/antora/antora.tmpl.yml b/src/site/antora/antora.tmpl.yml
index 632124c8676..b568da3457c 100644
--- a/src/site/antora/antora.tmpl.yml
+++ b/src/site/antora/antora.tmpl.yml
@@ -59,7 +59,6 @@ asciidoc:
disruptor-version: "${site-disruptor.version}"
flume-version: "${site-flume.version}"
jackson-version: "${site-jackson.version}"
- jansi-version: "${site-jansi.version}"
je-version: "${site-je.version}"
log4j-api-version: "${log4j-api.version}"
log4j-core-version: "${site-log4j-core.version}"
diff --git a/src/site/antora/antora.yml b/src/site/antora/antora.yml
index 9fbdd43fcac..e4d86990b46 100644
--- a/src/site/antora/antora.yml
+++ b/src/site/antora/antora.yml
@@ -59,7 +59,6 @@ asciidoc:
disruptor-version: "1.2.3-disruptor"
flume-version: "1.2.3-flume"
jackson-version: "1.2.3-jackson"
- jansi-version: "1.2.3-jansi"
je-version: "1.2.3-je"
log4j-api-version: "1.2.3-api"
log4j-core-version: "1.2.3-core"
diff --git a/src/site/antora/modules/ROOT/pages/components.adoc b/src/site/antora/modules/ROOT/pages/components.adoc
index 1f01a3f47e4..cbc79d63be6 100644
--- a/src/site/antora/modules/ROOT/pages/components.adoc
+++ b/src/site/antora/modules/ROOT/pages/components.adoc
@@ -216,24 +216,6 @@ for more information.
include::partial$components/log4j-flume-ng.adoc[]
-[#log4j-jansi]
-== `log4j-jansi`
-
-|===
-| JPMS module
-| `org.apache.logging.log4j.jansi`
-|===
-
-The `log4j-jansi` artifact contains an extension for the
-xref:manual/appenders.adoc#ConsoleAppender[Console Appender]
-that uses the
-https://fusesource.github.io/jansi/[JAnsi library]
-to handle ANSI escapes.
-
-See xref:manual/systemproperties.adoc#log4j.console.jansiEnabled[`log4j.console.jansiEnabled`] for more details.
-
-include::partial$components/log4j-jansi.adoc[]
-
[#log4j-jctools]
== `log4j-jctools`
diff --git a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
index 28fa1dd8c9b..aee25f66224 100644
--- a/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/appenders.adoc
@@ -214,7 +214,7 @@ They are documented in separate pages based on their target resource:
=== Console Appender
As one might expect, the Console Appender writes its output to either the standard output or standard error output.
-The appender supports four different ways to access the output streams:
+The appender supports three different ways to access the output streams:
`direct`::
This mode gives the best performance.
@@ -234,39 +234,6 @@ This setting might be useful in multi-application environments.
Some application servers modify `System.out` and `System.err` to always point to the currently running application.
====
-[#ConsoleAppender-jansi]
-`JANSI`::
-If the
-xref:components.adoc#log4j-jansi[`log4j-jansi` extension]
-is available, the Console appender will use the
-https://fusesource.github.io/jansi/[JAnsi library]
-to handle ANSI escapes.
-The library:
-+
---
-* Implement ANSI escape handling on old Windows consoles.
-* Strips ANSI escape codes if process output is being redirected and not attached to a terminal
---
-+
-See https://github.com/fusesource/jansi?tab=readme-ov-file#features[Features of JAnsi] for more details.
-+
-[TIP]
-====
-Support for ANSI escape sequences was added to Windows 10 console around 2017.
-See
-https://superuser.com/questions/413073/windows-console-with-ansi-colors-handling[Windows console with ANSI colors handling]
-for more details.
-====
-+
-The `JANSI` mode can be disabled by setting the
-xref:manual/systemproperties.adoc#log4j.console.jansiEnabled[`log4j.console.jansiEnabled`]
-configuration attribute to `false`.
-Additional runtime dependencies are required to use JAnsi:
-+
---
-include::partial$components/log4j-jansi.adoc[]
---
-
[#ConsoleAppender-attributes]
.Console Appender configuration attributes
[cols="1m,1,1,5"]
@@ -311,9 +278,7 @@ If other logging backends or the application itself uses `System.out/System.err`
====
This setting is incompatible with the
-<>
-and
-xref:manual/systemproperties.adoc#log4j.console.jansiEnabled[JANSI support].
+<>.
| [[ConsoleAppender-attr-follow]]
follow
@@ -328,9 +293,7 @@ https://docs.oracle.com/javase/8/docs/api/java/lang/System.html#setOut-java.io.P
Otherwise, the value of `System.out` (resp. `System.err`) at configuration time will be used.
This setting is incompatible with the
-<>
-and
-xref:manual/systemproperties.adoc#log4j.console.jansiEnabled[JANSI support].
+<>.
| [[ConsoleAppender-attr-ignoreExceptions]]
ignoreExceptions
diff --git a/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc b/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
index a4300d30462..57c29d892f8 100644
--- a/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/pattern-layout.adoc
@@ -211,12 +211,6 @@ The optional footer to include at the bottom of each log file
If `true`, do not output ANSI escape codes.
-[NOTE]
-====
-If you use a Console Appender in xref:manual/appenders.adoc#ConsoleAppender-jansi[`JANSI` mode], you should keep this setting at its default `false` value.
-The JAnsi library will take care of stripping ANSI Escape if the output of the console is not a terminal.
-====
-
[#plugin-attr-noConsoleNoAnsi]
==== `noConsoleNoAnsi`
@@ -226,7 +220,7 @@ The JAnsi library will take care of stripping ANSI Escape if the output of the c
|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
@@ -745,7 +739,7 @@ fqcn
==== Highlight
Adds ANSI colors to the result of the enclosed pattern based on the current event's {log4j2-url}/manual/customloglevels.html[logging level].
-Windows users should refer to <>.
+Windows users should refer to <>.
.link:../javadoc/log4j-core/org/apache/logging/log4j/core/pattern/HighlightConverter.html[`HighlightConverter`] specifier grammar
[source,text]
@@ -1047,7 +1041,7 @@ message{lookups}{ansi}
----
Add `\{ansi}` to render messages with ANSI escape codes.
-Windows users should refer to <>.
+Windows users should refer to <>.
The default syntax for embedded ANSI codes is:
@@ -1241,7 +1235,7 @@ The counter is a static variable, so will only be unique within applications tha
Use ANSI escape sequences to style the result of the enclosed pattern.
The syntax of the `style_expression` parameter is described in <>.
-Windows users should also refer to <>.
+Windows users should also refer to <>.
.link:../javadoc/log4j-core/org/apache/logging/log4j/core/pattern/StyleConverter.html[`StyleConverter`] specifier grammar
[source,text]
@@ -1591,22 +1585,17 @@ If your terminal supports 24-bit colors, you can specify:
* the text color using the `#rrggbb` syntax, e.g. `#dc143c` will color your text crimson,
* the background color using the `bg_#rrggbb` syntax, e.g. `bg_#87ceeb` will use a sky blue background.
-[#jansi]
+[#ansi-windows]
==== ANSI styling on Windows
-ANSI escape sequences are supported natively on many platforms, but not by default on Windows.
-To enable ANSI support add the
-http://fusesource.github.io/jansi/[Jansi]
-dependency to your application, and set xref:manual/systemproperties.adoc#log4j.console.jansiEnabled[the `log4j.console.jansiEnabled` system property] to `true`.
-This allows Log4j to use Jansi to add ANSI escape codes when writing to the console.
+ANSI escape sequences are supported natively on many platforms, but is disabled by default in `cmd.exe` on Windows.
+To enable ANSI escape sequences, create a registry key of name `HKEY_CURRENT_USER\Console\VirtualTerminalLevel` of type `DWORD` and set its value to `0x1`.
-[NOTE]
-====
-Before Log4j 2.10, Jansi was enabled by default.
-The fact that Jansi requires native code means that Jansi can only be loaded by a single class loader.
-For web applications, this means the Jansi jar has to be in the web container's classpath.
-To avoid causing problems for web applications, Log4j no longer automatically tries to load Jansi without explicit configuration from Log4j 2.10 onward.
-====
+See
+https://devblogs.microsoft.com/commandline/understanding-windows-console-host-settings/[Understanding Windows Console Host Settings]
+and
+https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences[Console Virtual Terminal Sequences]
+Microsoft documentation for more details.
[#garbage-free]
=== Garbage-free configuration
diff --git a/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc b/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc
index 941748710c3..ebbe0f2174d 100644
--- a/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc
+++ b/src/site/antora/modules/ROOT/pages/manual/systemproperties.adoc
@@ -170,13 +170,6 @@ include::partial$manual/systemproperties/properties-log-event.adoc[leveloffset=+
include::partial$manual/systemproperties/properties-garbage-collection.adoc[leveloffset=+2]
-[id=properties-jansi]
-=== JANSI
-
-If the https://fusesource.github.io/jansi/[JANSI] library is on the runtime classpath of the application, the following property can be used to control its usage:
-
-include::partial$manual/systemproperties/properties-jansi.adoc[leveloffset=+2]
-
[id=properties-log4j-core-thread-context]
=== Thread context
diff --git a/src/site/antora/modules/ROOT/partials/components/log4j-jansi.adoc b/src/site/antora/modules/ROOT/partials/components/log4j-jansi.adoc
deleted file mode 100644
index d7864aff767..00000000000
--- a/src/site/antora/modules/ROOT/partials/components/log4j-jansi.adoc
+++ /dev/null
@@ -1,41 +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.
-////
-
-[tabs]
-====
-Maven::
-+
-We assume you use xref:components.adoc#log4j-bom[`log4j-bom`] for dependency management.
-+
-[source,xml]
-----
-
- org.apache.logging.log4j
- log4j-jansi
- runtime
-
-----
-
-Gradle::
-+
-We assume you use xref:components.adoc#log4j-bom[`log4j-bom`] for dependency management.
-+
-[source,groovy]
-----
-runtimeOnly 'org.apache.logging.log4j:log4j-jansi'
-----
-====
\ No newline at end of file
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 ca43e6bc296..00000000000
--- a/src/site/antora/modules/ROOT/partials/manual/systemproperties/properties-jansi.adoc
+++ /dev/null
@@ -1,33 +0,0 @@
-////
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-////
-[id=log4j.console.jansiEnabled]
-== `log4j.console.jansiEnabled`
-
-[cols="1h,5"]
-|===
-| Env. variable | `LOG4J_CONSOLE_JANSI_ENABLED`
-| Type | `boolean`
-| Default value | `true`
-|===
-
-If the
-xref:components.adoc#log4j-jansi[`log4j-jansi`]
-extension is available and this value is `true`, the
-xref:manual/appenders.adoc#ConsoleAppender[Console Appender]
-will use the
-https://fusesource.github.io/jansi/[JAnsi library]
-to handle ANSI escapes.
From 0f2a1684c3e8494721ba4e96cb81e4ec275cadde Mon Sep 17 00:00:00 2001
From: "Piotr P. Karwasz"
Date: Mon, 7 Oct 2024 10:28:34 +0200
Subject: [PATCH 7/7] Remove `ConsoleStreamSupplier` interface
---
.../log4j/core/appender/ConsoleAppender.java | 136 +++++++++++------
.../DefaultConsoleStreamSupplier.java | 139 ------------------
2 files changed, 87 insertions(+), 188 deletions(-)
delete mode 100644 log4j-core/src/main/java/org/apache/logging/log4j/core/appender/internal/DefaultConsoleStreamSupplier.java
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 10e42356b03..4e6dbb47ae0 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
@@ -16,28 +16,23 @@
*/
package org.apache.logging.log4j.core.appender;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
-import java.util.List;
-import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
-import org.apache.logging.log4j.core.appender.internal.DefaultConsoleStreamSupplier;
-import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.util.CloseShieldOutputStream;
-import org.apache.logging.log4j.kit.env.PropertyEnvironment;
import org.apache.logging.log4j.plugins.Configurable;
-import org.apache.logging.log4j.plugins.Namespace;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.plugins.PluginFactory;
-import org.apache.logging.log4j.plugins.di.Key;
import org.apache.logging.log4j.plugins.validation.constraints.Required;
-import org.jspecify.annotations.Nullable;
/**
* Appends log events to System.out or System.err using a layout specified by the user. The
@@ -166,30 +161,15 @@ public B setDirect(final boolean shouldDirect) {
@Override
public ConsoleAppender build() {
- final Layout layout = getOrCreateLayout(target.getDefaultCharset());
-
- final Configuration configuration = getConfiguration();
- final PropertyEnvironment propertyEnvironment;
- final List suppliers;
- if (configuration != null) {
- propertyEnvironment = configuration.getLoggerContext() != null
- ? configuration.getLoggerContext().getEnvironment()
- : PropertyEnvironment.getGlobal();
-
- suppliers = configuration.getComponent(new @Namespace(ConsoleStreamSupplier.NAMESPACE) Key<>() {});
- } else {
- propertyEnvironment = PropertyEnvironment.getGlobal();
- suppliers = List.of(new DefaultConsoleStreamSupplier());
+ if (direct && follow) {
+ LOGGER.error("Cannot use both `direct` and `follow` on ConsoleAppender.");
+ return null;
}
+ final Layout layout = getOrCreateLayout(target.getDefaultCharset());
- final OutputStream stream = suppliers.stream()
- .map(s -> s.getOutputStream(follow, direct, target, propertyEnvironment))
- .filter(Objects::nonNull)
- .findFirst()
- .orElse(null);
- if (stream == null) {
- LOGGER.warn("No output stream found for target {}", target);
- }
+ OutputStream stream = direct
+ ? getDirectOutputStream(target)
+ : follow ? getFollowOutputStream(target) : getDefaultOutputStream(target);
final String managerName = target.name() + '.' + follow + '.' + direct;
final OutputStreamManager manager =
@@ -207,6 +187,83 @@ private static OutputStreamManager getDefaultManager(final Layout layout) {
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 getDirectOutputStream(Target target) {
+ return new CloseShieldOutputStream(
+ new FileOutputStream(target == Target.SYSTEM_OUT ? FileDescriptor.out : FileDescriptor.err));
+ }
+
+ private static OutputStream getFollowOutputStream(Target target) {
+ return target == Target.SYSTEM_OUT ? new SystemOutStream() : new SystemErrStream();
+ }
+
+ /**
+ * An implementation of OutputStream that redirects to the current System.err.
+ */
+ private static class SystemErrStream extends OutputStream {
+ public SystemErrStream() {}
+
+ @Override
+ public void close() {
+ // do not close sys err!
+ }
+
+ @Override
+ public void flush() {
+ System.err.flush();
+ }
+
+ @Override
+ public void write(final byte[] b) throws IOException {
+ System.err.write(b);
+ }
+
+ @Override
+ public void write(final byte[] b, final int off, final int len) throws IOException {
+ System.err.write(b, off, len);
+ }
+
+ @Override
+ public void write(final int b) {
+ System.err.write(b);
+ }
+ }
+
+ /**
+ * An implementation of OutputStream that redirects to the current System.out.
+ */
+ private static class SystemOutStream extends OutputStream {
+ public SystemOutStream() {}
+
+ @Override
+ public void close() {
+ // do not close sys out!
+ }
+
+ @Override
+ public void flush() {
+ System.out.flush();
+ }
+
+ @Override
+ public void write(final byte[] b) throws IOException {
+ System.out.write(b);
+ }
+
+ @Override
+ public void write(final byte[] b, final int off, final int len) throws IOException {
+ System.out.write(b, off, len);
+ }
+
+ @Override
+ public void write(final int b) throws IOException {
+ System.out.write(b);
+ }
+ }
+
/**
* Data to pass to factory method.Unable to instantiate
*/
@@ -250,23 +307,4 @@ public OutputStreamManager createManager(final String name, final FactoryData da
public Target getTarget() {
return target;
}
-
- /**
- * Abstracts the various ways `System.out` can be accessed.
- *
- * @since 3.0.0
- */
- public interface ConsoleStreamSupplier {
-
- /**
- * The Log4j plugin namespace of plugins implementing this interface.
- */
- String NAMESPACE = "Console";
-
- /**
- * @return Selects the output stream to use or {@code null} in case of error.
- */
- @Nullable
- OutputStream getOutputStream(boolean follow, boolean direct, Target target, PropertyEnvironment properties);
- }
}
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/internal/DefaultConsoleStreamSupplier.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/internal/DefaultConsoleStreamSupplier.java
deleted file mode 100644
index 858233c0f80..00000000000
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/internal/DefaultConsoleStreamSupplier.java
+++ /dev/null
@@ -1,139 +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.internal;
-
-import java.io.FileDescriptor;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.appender.ConsoleAppender;
-import org.apache.logging.log4j.core.util.CloseShieldOutputStream;
-import org.apache.logging.log4j.kit.env.PropertyEnvironment;
-import org.apache.logging.log4j.plugins.Namespace;
-import org.apache.logging.log4j.plugins.Ordered;
-import org.apache.logging.log4j.plugins.Plugin;
-import org.apache.logging.log4j.status.StatusLogger;
-import org.jspecify.annotations.NullMarked;
-import org.jspecify.annotations.Nullable;
-
-@Plugin
-@Namespace(ConsoleAppender.ConsoleStreamSupplier.NAMESPACE)
-@Ordered(Ordered.LAST)
-@NullMarked
-public class DefaultConsoleStreamSupplier implements ConsoleAppender.ConsoleStreamSupplier {
-
- private static final Logger LOGGER = StatusLogger.getLogger();
-
- @Override
- @Nullable
- public OutputStream getOutputStream(
- boolean follow, boolean direct, ConsoleAppender.Target target, PropertyEnvironment properties) {
- if (follow && direct) {
- LOGGER.error("Cannot use both `follow` and `direct` on ConsoleAppender.");
- return null;
- }
- return switch (target) {
- case SYSTEM_ERR -> getErr(follow, direct);
- case SYSTEM_OUT -> getOut(follow, direct);
- };
- }
-
- private OutputStream getErr(final boolean follow, final boolean direct) {
- if (direct) {
- return new CloseShieldOutputStream(new FileOutputStream(FileDescriptor.err));
- }
- if (follow) {
- return new SystemErrStream();
- }
- return new CloseShieldOutputStream(System.err);
- }
-
- private OutputStream getOut(final boolean follow, final boolean direct) {
- if (direct) {
- return new CloseShieldOutputStream(new FileOutputStream(FileDescriptor.out));
- }
- if (follow) {
- return new SystemOutStream();
- }
- return new CloseShieldOutputStream(System.out);
- }
-
- /**
- * An implementation of OutputStream that redirects to the current System.err.
- */
- private static class SystemErrStream extends OutputStream {
- public SystemErrStream() {}
-
- @Override
- public void close() {
- // do not close sys err!
- }
-
- @Override
- public void flush() {
- System.err.flush();
- }
-
- @Override
- public void write(final byte[] b) throws IOException {
- System.err.write(b);
- }
-
- @Override
- public void write(final byte[] b, final int off, final int len) {
- System.err.write(b, off, len);
- }
-
- @Override
- public void write(final int b) {
- System.err.write(b);
- }
- }
-
- /**
- * An implementation of OutputStream that redirects to the current System.out.
- */
- private static class SystemOutStream extends OutputStream {
- public SystemOutStream() {}
-
- @Override
- public void close() {
- // do not close sys out!
- }
-
- @Override
- public void flush() {
- System.out.flush();
- }
-
- @Override
- public void write(final byte[] b) throws IOException {
- System.out.write(b);
- }
-
- @Override
- public void write(final byte[] b, final int off, final int len) {
- System.out.write(b, off, len);
- }
-
- @Override
- public void write(final int b) {
- System.out.write(b);
- }
- }
-}