You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2023/01/20 06:54:43 UTC

[logging-log4j2] 01/05: LOG4J2-3538 Added support for 24 colors in highlighting (#933)

This is an automated email from the ASF dual-hosted git repository.

pkarwasz pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 4d34d2f85631e9025e723dc99d9fe6b6c950735d
Author: PashaTurok <oo...@mail.ru>
AuthorDate: Sun Jun 19 10:30:55 2022 +0300

    LOG4J2-3538 Added support for 24 colors in highlighting (#933)
    
    Adds support for 24-bit colors in `HighlightConverter`.
---
 .../log4j/core/pattern/HighlightConverterTest.java | 33 ++++++++++++++++-
 .../logging/log4j/core/pattern/AnsiEscape.java     | 41 +++++++++++++++++++---
 2 files changed, 69 insertions(+), 5 deletions(-)

diff --git a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/HighlightConverterTest.java b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/HighlightConverterTest.java
index c62889543a..a704d44c6a 100644
--- a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/HighlightConverterTest.java
+++ b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/pattern/HighlightConverterTest.java
@@ -1,4 +1,4 @@
-package org.apache.logging.log4j.core.pattern;/*
+/*
  * 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.
@@ -14,6 +14,7 @@ package org.apache.logging.log4j.core.pattern;/*
  * See the license for the specific language governing permissions and
  * limitations under the license.
  */
+package org.apache.logging.log4j.core.pattern;
 
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.core.LogEvent;
@@ -76,6 +77,36 @@ public class HighlightConverterTest {
         assertEquals(AnsiEscape.createSequence(colorName), converter.getLevelStyle(Level.DEBUG));
     }
 
+    @Test
+    public void testLevelNamesHexShort() {
+        final String colorName = "#1cd42b";
+        final String[] options = {"%-5level: %msg", PatternParser.NO_CONSOLE_NO_ANSI + "=false, "
+                + PatternParser.DISABLE_ANSI + "=false, " + "INFO=" + colorName};
+        final HighlightConverter converter = HighlightConverter.newInstance(null, options);
+        assertNotNull(converter);
+
+        final LogEvent event = Log4jLogEvent.newBuilder().setLevel(Level.INFO).setLoggerName("a.b.c").setMessage(
+                new SimpleMessage("")).build();
+        final StringBuilder buffer = new StringBuilder();
+        converter.format(event, buffer);
+        assertEquals("\u001B[38;2;28;212;43mINFO : \u001B[m", buffer.toString());
+    }
+
+    @Test
+    public void testLevelNamesHexFull() {
+        final String colorName = "FG_#1cd42b BG_#000000";
+        final String[] options = {"%-5level: %msg", PatternParser.NO_CONSOLE_NO_ANSI + "=false, "
+                + PatternParser.DISABLE_ANSI + "=false, " + "INFO=" + colorName};
+        final HighlightConverter converter = HighlightConverter.newInstance(null, options);
+        assertNotNull(converter);
+
+        final LogEvent event = Log4jLogEvent.newBuilder().setLevel(Level.INFO).setLoggerName("a.b.c").setMessage(
+                new SimpleMessage("")).build();
+        final StringBuilder buffer = new StringBuilder();
+        converter.format(event, buffer);
+        assertEquals("\u001B[38;2;28;212;43;48;2;0;0;0mINFO : \u001B[m", buffer.toString());
+    }
+
     @Test
     public void testLevelNamesUnknown() {
         String colorName = "blue";
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 c83123453e..b7f703fa63 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
@@ -16,13 +16,16 @@
  */
 package org.apache.logging.log4j.core.pattern;
 
+import java.awt.datatransfer.StringSelection;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Locale;
 import java.util.Map;
 
 import org.apache.logging.log4j.core.util.Patterns;
+import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.EnglishEnums;
+import org.apache.logging.log4j.util.Strings;
 
 /**
  * Converts text into ANSI escape sequences.
@@ -289,7 +292,7 @@ public enum AnsiEscape {
      * @return a new map
      */
     public static Map<String, String> createMap(final String[] values, final String[] dontEscapeKeys) {
-        final String[] sortedIgnoreKeys = dontEscapeKeys != null ? dontEscapeKeys.clone() : new String[0];
+        final String[] sortedIgnoreKeys = dontEscapeKeys != null ? dontEscapeKeys.clone() : Strings.EMPTY_ARRAY;
         Arrays.sort(sortedIgnoreKeys);
         final Map<String, String> map = new HashMap<>();
         for (final String string : values) {
@@ -319,14 +322,44 @@ public enum AnsiEscape {
         boolean first = true;
         for (final String name : names) {
             try {
-                final AnsiEscape escape = EnglishEnums.valueOf(AnsiEscape.class, name.trim());
                 if (!first) {
                     sb.append(AnsiEscape.SEPARATOR.getCode());
                 }
                 first = false;
-                sb.append(escape.getCode());
+                String hexColor = null;
+                final String trimmedName = name.trim().toUpperCase(Locale.ENGLISH);
+                if (trimmedName.startsWith("#")) {
+                    sb.append("38");
+                    sb.append(SEPARATOR.getCode());
+                    sb.append("2");
+                    sb.append(SEPARATOR.getCode());
+                    hexColor = trimmedName;
+                } else if (trimmedName.startsWith("FG_#")) {
+                    sb.append("38");
+                    sb.append(SEPARATOR.getCode());
+                    sb.append("2");
+                    sb.append(SEPARATOR.getCode());
+                    hexColor = trimmedName.substring(3);
+                } else if (trimmedName.startsWith("BG_#")) {
+                    sb.append("48");
+                    sb.append(SEPARATOR.getCode());
+                    sb.append("2");
+                    sb.append(SEPARATOR.getCode());
+                    hexColor = trimmedName.substring(3);
+                }
+                if (hexColor != null) {
+                    sb.append(Integer.valueOf(hexColor.substring(1, 3), 16));//r
+                    sb.append(SEPARATOR.getCode());
+                    sb.append(Integer.valueOf(hexColor.substring(3, 5), 16));//g
+                    sb.append(SEPARATOR.getCode());
+                    sb.append(Integer.valueOf(hexColor.substring(5, 7), 16));//b
+                    //no separator at the end
+                } else {
+                    final AnsiEscape escape = EnglishEnums.valueOf(AnsiEscape.class, trimmedName);
+                    sb.append(escape.getCode());
+                }
             } catch (final Exception ex) {
-                // Ignore the error.
+                StatusLogger.getLogger().warn("The style attribute {} is incorrect.", name, ex);
             }
         }
         sb.append(AnsiEscape.SUFFIX.getCode());