You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ra...@apache.org on 2026/10/01 17:50:51 UTC
(logging-log4j2) 22/33: Fix predefined ANSI styles in JAnsiTextRenderer (#4259)
This is an automated email from the ASF dual-hosted git repository.
ramanathan1504 pushed a commit to branch port/2.27.0-fixes-to-2.26.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 3ecdaf25ea59af27c75a0e5eaba4920cb7281f67
Author: Burak Kalaycı <ka...@gmail.com>
AuthorDate: Thu Sep 17 12:37:01 2026 +0300
Fix predefined ANSI styles in JAnsiTextRenderer (#4259)
Signed-off-by: Burak KALAYCI <ka...@gmail.com>
(cherry picked from commit 89db25a2b7a231795da6209667ab5a162d987bb5)
---
.../log4j/core/pattern/JAnsiTextRendererTest.java | 8 +++++++-
.../logging/log4j/core/pattern/AnsiEscape.java | 3 +++
.../log4j/core/pattern/JAnsiTextRenderer.java | 20 ++++++++++----------
.../.2.x.x/4254_fix_predefined_ansi_styles.xml | 13 +++++++++++++
4 files changed, 33 insertions(+), 11 deletions(-)
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
index 0595f68533..bbdc7a3c02 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/JAnsiTextRendererTest.java
@@ -41,7 +41,13 @@ class JAnsiTextRendererTest {
"\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!"));
+ Arguments.of("", "Hello @|world!", "Hello @|world!"),
+ // Predefined Style=Spock: Name is BG_RED + WHITE
+ Arguments.of("Style=Spock", "@|Name XYZ|@", "\u001b[41;37mXYZ\u001b[m"),
+ // Predefined Style=Kirk: Name is BG_RED + YELLOW + BOLD
+ Arguments.of("Style=Kirk", "@|Name XYZ|@", "\u001b[41;33;1mXYZ\u001b[m"),
+ // User-supplied ANSI names still work when a predefined style is selected
+ Arguments.of("Style=Spock", "@|bg_red,white XYZ|@", "\u001b[41;37mXYZ\u001b[m"));
}
@ParameterizedTest
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 34213373df..a2fb515571 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
@@ -427,6 +427,9 @@ public enum AnsiEscape {
static Map<String, String> createMap(
final String[] values, final String[] dontEscapeKeys, final String separatorRegex) {
final String[] sortedIgnoreKeys = dontEscapeKeys != null ? dontEscapeKeys.clone() : Strings.EMPTY_ARRAY;
+ for (int i = 0; i < sortedIgnoreKeys.length; i++) {
+ sortedIgnoreKeys[i] = toRootUpperCase(sortedIgnoreKeys[i]);
+ }
Arrays.sort(sortedIgnoreKeys);
final Map<String, String> map = new HashMap<>();
for (final String string : values) {
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 072dfeb87f..88e38781d8 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
@@ -95,11 +95,11 @@ public final class JAnsiTextRenderer implements TextRenderer {
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());
+ final String[] names = new String[codes.length];
+ for (int i = 0; i < codes.length; i++) {
+ names[i] = codes[i].name();
}
- return new AbstractMap.SimpleImmutableEntry<>(name, sb.toString());
+ return new AbstractMap.SimpleImmutableEntry<>(name, AnsiEscape.createSequence(names));
}
@SafeVarargs
@@ -201,12 +201,12 @@ public final class JAnsiTextRenderer implements TextRenderer {
if (formats.length > 1) {
final String stylesStr = formats[1];
final Map<String, String> map = AnsiEscape.createMap(
- stylesStr.split("\\s", -1), new String[] {"BeginToken", "EndToken", "Style"}, ",");
+ 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");
+ // Handle the special tokens. createMap stores keys in root upper-case.
+ 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());
@@ -214,7 +214,7 @@ public final class JAnsiTextRenderer implements TextRenderer {
if (predefinedStyle != null) {
final Map<String, String> predefinedMap = PREFEDINED_STYLE_MAPS.get(predefinedStyle);
if (predefinedMap != null) {
- map.putAll(predefinedMap);
+ predefinedMap.forEach((k, v) -> map.put(toRootUpperCase(k), v));
} else {
LOGGER.warn(
"Unknown predefined map name {}, pick one of {}",
diff --git a/src/changelog/.2.x.x/4254_fix_predefined_ansi_styles.xml b/src/changelog/.2.x.x/4254_fix_predefined_ansi_styles.xml
new file mode 100644
index 0000000000..8a99ea2cb0
--- /dev/null
+++ b/src/changelog/.2.x.x/4254_fix_predefined_ansi_styles.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
+ type="fixed">
+ <issue id="4254" link="https://github.com/apache/logging-log4j2/issues/4254"/>
+ <issue id="4259" link="https://github.com/apache/logging-log4j2/pull/4259"/>
+ <description format="asciidoc">
+ Apply predefined ANSI styles (`Style=Spock`, `Style=Kirk`) in `JAnsiTextRenderer` and emit valid SGR sequences for those styles.
+ </description>
+</entry>