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 2022/06/19 07:31:03 UTC

[logging-log4j2] branch release-2.x updated: 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 release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git


The following commit(s) were added to refs/heads/release-2.x by this push:
     new f70802305a LOG4J2-3538 Added support for 24 colors in highlighting (#933)
f70802305a is described below

commit f70802305aab9479b94b236e535a9b4177e14e09
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`.
---
 .../logging/log4j/core/pattern/AnsiEscape.java     | 37 ++++++++++++++++++++--
 .../log4j/core/pattern/HighlightConverterTest.java | 32 ++++++++++++++++++-
 src/changes/changes.xml                            |  3 ++
 src/site/xdoc/manual/layouts.xml.vm                |  9 ++++++
 4 files changed, 77 insertions(+), 4 deletions(-)

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 64ea554b54..3f2be36524 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
@@ -22,6 +22,7 @@ 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;
 
@@ -320,14 +321,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());
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/HighlightConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/HighlightConverterTest.java
index d03c09ba72..71d9425cb3 100644
--- a/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/HighlightConverterTest.java
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/pattern/HighlightConverterTest.java
@@ -76,6 +76,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() {
         final String colorName = "blue";
@@ -96,7 +126,7 @@ public class HighlightConverterTest {
                 toFormattedCharSeq(converter, Level.forName("CUSTOM1", 412)).toString().getBytes());
         assertArrayEquals(new byte[] { 'C', 'U', 'S', 'T', 'O', 'M', '2' },
                 toFormattedCharSeq(converter, Level.forName("CUSTOM2", 512)).toString().getBytes());
-    }    
+    }
 
     @Test
     public void testLevelNamesNone() {
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index e30252b3ad..05957cc177 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -160,6 +160,9 @@
       <action issue="LOG4J2-3531" dev="pkarwasz" type="fix" due-to="Simo Nikula, Piotr P. Karwasz">
         Fix parsing error, when XInclude is disabled.
       </action>
+      <action issue="LOG4J2-3538" dev="pavel_k" type="add" due-to="Pavel_K">
+        Add support for 24 colors in highlighting
+      </action>      
     </release>
     <release version="2.17.2" date="2022-02-23" description="GA Release 2.17.2">
       <!-- FIXES -->
diff --git a/src/site/xdoc/manual/layouts.xml.vm b/src/site/xdoc/manual/layouts.xml.vm
index 5942ae6e65..bb37312d8a 100644
--- a/src/site/xdoc/manual/layouts.xml.vm
+++ b/src/site/xdoc/manual/layouts.xml.vm
@@ -1338,6 +1338,15 @@ WARN  [main]: Message 2</pre>
                  <pre>%highlight{%d [%t] %-5level: %msg%n%throwable}{FATAL=white, ERROR=red, WARN=blue, INFO=black, DEBUG=green, TRACE=blue}</pre>
  #end
                 </p>
+                <p>At the same time it is possible to use true colors (24 bit). For example:
+ #if ($isPDF)
+                 <pre>%highlight{%d [%t] %-5level: %msg%n%throwable}
+   {FATAL=white, ERROR=red, WARN=bg_#5792e6 fg_#eef26b bold, INFO=black,
+    DEBUG=#3fe0a8, TRACE=blue}</pre>
+ #else
+                 <pre>%highlight{%d [%t] %-5level: %msg%n%throwable}{FATAL=white, ERROR=red, WARN=bg_#5792e6 fg_#eef26b bold, INFO=black, DEBUG=#3fe0a8, TRACE=blue}</pre>
+ #end
+                </p>                
                 <p>You can highlight only the a portion of the log event:
                  <pre>%d [%t] %highlight{%-5level: %msg%n%throwable}</pre>
                 </p>