【问题标题】:How to change the Util.Logging.Logger printing colour in logging.properties如何更改 logging.properties 中的 Util.Logging.Logger 打印颜色
【发布时间】:2019-02-27 16:09:00
【问题描述】:

目前,我所有的 INFO、SEVERE 和 FINE 日志都以红色打印。我想将 INFO 和 FINE 日志更改为白色。

我发现很多文章通过创建一个新的 Fommater 来改变颜色。我想知道如何通过修改 logging.properties 来更改打印颜色?

我正在使用 Java 默认日志库Util.Logging.Logger

环境:

  • Ecipse 2018-12 (4.10.0)
  • Windows 10

【问题讨论】:

    标签: java.util.logging


    【解决方案1】:

    问题在于 Eclipse 总是以相同的颜色(在本例中为红色)显示 stderr 输出。它可以在设置中进行配置,但对于所有 stderr 流总是相同的。

    我的解决方案是为控制台处理程序使用自定义格式化程序,并根据其级别在每条消息之前注入 ANSI 颜色代码。所以我根据JDK8中的原始SimpleFormatter.java做了那个。代码如下:

    import java.io.PrintWriter;
    import java.io.StringWriter;
    import java.util.Date;
    import java.util.logging.Formatter;
    import java.util.logging.LogRecord;
    
    public class CustomFormatter extends Formatter {
    
        public static final String ANSI_RESET = "\u001B[0m";
        public static final String ANSI_RED = "\u001B[31m";
        public static final String ANSI_YELLOW = "\u001B[33m";
        public static final String ANSI_CYAN = "\u001B[36m";
    
        private final Date dat = new Date();
        private static final String format = "%1$s %2$tb %2$td, %2$tY %2$tl:%2$tM:%2$tS %2$Tp %3$s%n%5$s: %6$s%7$s%n";
    
        @Override
        public String format(LogRecord record) {
            dat.setTime(record.getMillis());
            String source;
            if (record.getSourceClassName() != null) {
                source = record.getSourceClassName();
                if (record.getSourceMethodName() != null) {
                    source += " " + record.getSourceMethodName();
                }
            } else {
                source = record.getLoggerName();
            }
            String message = formatMessage(record);
            String throwable = "";
            if (record.getThrown() != null) {
                StringWriter sw = new StringWriter();
                PrintWriter pw = new PrintWriter(sw);
                pw.println();
                record.getThrown().printStackTrace(pw);
                pw.close();
                throwable = sw.toString();
            }
    
            switch (record.getLevel().toString()) {
                case "INFO":
                    return String.format(format, ANSI_CYAN, dat, source, record.getLoggerName(),
                            record.getLevel().getLocalizedName(), message + ANSI_RESET, throwable);
                case "WARNING":
                    return String.format(format, ANSI_YELLOW, dat, source, record.getLoggerName(),
                            record.getLevel().getLocalizedName(), message + ANSI_RESET, throwable);
                case "SEVERE":
                    return String.format(format, ANSI_RED, dat, source, record.getLoggerName(),
                            record.getLevel().getLocalizedName(), message + ANSI_RESET, throwable);
                default:
                    return String.format(format, dat, source, record.getLoggerName(),
                            record.getLevel().getLocalizedName(), message, throwable);
            }
        }
    }
    

    先决条件

    • ANSI Escape in Console plugin 用于 Eclipse。您将需要它,以便 Eclipse 控制台可以解释 ANSI Escape 代码。 安装并重启 Eclipse

    • 上面的代码编译并压缩成.jar文件

      1. 将上面的代码另存为CustomFormatter.java
      2. javac CustomFormatter.java编译它
      3. 使用jar cfv CustomFormatter.jar CustomFormatter.class 创建一个包含类文件的 JAR 文件,并将其保存在您想要的任何文件夹中(例如,C:\java\CustomFormatter

    说明

    • 转到Window --> Preferences --> Ansi Console 并检查Try using the standard error color setting for stderr output,然后检查Apply and Close
    • 编辑 logging.properties 文件,该文件位于 JRE 的 lib 文件夹中。您的计算机中可能有多个,您应该编辑与 Eclipse 正在使用的 JRE 版本相对应的一个。您可以通过阅读 Eclipse 中的“控制台”选项卡下方的内容来了解​​正在使用哪一个:

      1. 使用文本编辑器打开logging.properties。就我而言,我将编辑C:\Program Files\Java\jre1.8.0_231\lib\logging.properties
      2. 您应该更改 java.util.logging.ConsoleHandler.formatter 的值(在我的例子中是第 44 行),使其等于 CustomFormatter完全像这样:java.util.logging.ConsoleHandler.formatter = CustomFormatter。确保保存更改。
    • 在 Eclipse 中添加 CustomFormatter.jar 作为 JRE 系统库

      1. 转到Window --> Preferences --> Java --> Installed JREs
      2. 选择你正在使用的JRE,点击EditAdd External JARs...
      3. 转到您保存CustomFormatter.jar 的文件夹并选择它。
      4. 确保它在系统库列表中,然后单击FinishApply and Close
      5. 就是这样。现在每个 Logger 级别应该有不同的颜色。青色表示信息,黄色表示警告,红色表示严重。您可以通过使用corresponding ANSI Color code 修改上面的代码将其更改为您想要的任何颜色。它适用于 java 8 和 Eclipse 2019-12:

    注意:如果标准输出文本显示为蓝色、红色或黄色,请尝试在Window --> Preferences --> Run/Debug --> Console 中禁用Limit console output

    【讨论】:

      【解决方案2】:

      目前,我所有的 INFO、SEVERE 和 FINE 日志都以红色打印。

      这取决于消耗System.err 的进程。 Since the output is red I assume you are using an IDE。您使用的是哪个 IDE?也许它具有修改控制台输出呈现方式的设置。对于日食,您可以:

      1. 更改Standard Out/Standard Error text color,使标准输出为白色,标准错误为红色。
      2. 创建一个设置为 WARNING 级别的常规 ConsoleHandler。这会将所有警告及以上警告指向红色的 ERR 流。
      3. 创建一个特殊的Handler to print to Standard OUT 并将级别设置为ALL。
      4. 创建一个java.util.logging.Filter 以过滤掉标准 OUT 处理程序的大于 INFO 的消息,并将其安装在该处理程序上。
      5. 将控制台处理程序 (ERR) 和 OUT 处理程序附加到根记录器。

      我想知道如何通过修改 logging.properties 来改变打印颜色?

      您可以从 logging.properties 做的唯一事情是安装一种新类型的格式化程序或第三方处理程序,它们可能能够更改输出颜色,但这取决于所使用的控制台输出流的呈现方式(例如 HTML与 BASH 终端)。

      【讨论】:

      • 我正在使用 Eclipse。好的,也许我必须创建一个自定义格式化程序。
      • 感谢您的解决方案!但是我会转移到其他日志框架,因为Java detault日志框架有很多问题。
      • @Spider 如果您想创建自定义格式化程序,请查看我的答案。我是根据原来的SimpleFormatter.java 做的,它有效!我使用了 ANSI 颜色代码,所以 INFO 级别是青色,WARNING 级别是黄色,SEVERE 级别是红色
      【解决方案3】:

      jajube 的好回答。我使用netbeans 8.2。它的控制台具有默认的红色文本,但处理 ANSI 代码。我修改了他对下面格式化程序的回答

      package net.sf.jaer.util;
      
      import java.io.PrintWriter;
      import java.io.StringWriter;
      import java.util.Date;
      import java.util.logging.Formatter;
      import java.util.logging.LogRecord;
      
      /**
       * Based on
       * https://stackoverflow.com/questions/54909752/how-to-change-the-util-logging-logger-printing-colour-in-logging-properties
       * with ANSI codes from
       * https://stackoverflow.com/questions/5762491/how-to-print-color-in-console-using-system-out-println
       *
       * @author tobid Jan 2021
       */
      public class LoggingAnsiColorConsoleFormatter extends Formatter {
      
          public static final String ANSI_RESET = "\u001B[0m";
          public static final String ANSI_BLACK = "\u001B[30m";
          public static final String ANSI_RED = "\u001B[31m";
          public static final String ANSI_GREEN = "\u001B[32m";
          public static final String ANSI_YELLOW = "\u001B[33m";
          public static final String ANSI_BLUE = "\u001B[34m";
          public static final String ANSI_PURPLE = "\u001B[35m";
          public static final String ANSI_CYAN = "\u001B[36m";
          public static final String ANSI_WHITE = "\u001B[37m";
          public static final String ANSI_BLACK_BACKGROUND = "\u001B[40m";
          public static final String ANSI_RED_BACKGROUND = "\u001B[41m";
          public static final String ANSI_GREEN_BACKGROUND = "\u001B[42m";
          public static final String ANSI_YELLOW_BACKGROUND = "\u001B[43m";
          public static final String ANSI_BLUE_BACKGROUND = "\u001B[44m";
          public static final String ANSI_PURPLE_BACKGROUND = "\u001B[45m";
          public static final String ANSI_CYAN_BACKGROUND = "\u001B[46m";
          public static final String ANSI_WHITE_BACKGROUND = "\u001B[47m";
      
          private final Date date = new Date();
          // FORMAT uses e.g. 2$ which refers to 2nd argument of String.format
          // It has two lines: Line 1 is the date and class/method. Line 2 is the LEVEL and message
          // Lines are separated by the format spec %n which makes newline
          // This format puts date and class/method in CYAN, followed by newline with level colored, followed by default message color
          private static final String FORMAT = ANSI_CYAN+"%2$tb %2$td, %2$tY %2$tl:%2$tM:%2$tS %2$Tp %3$s%n%1$s%5$s:" + ANSI_RESET + " %6$s%7$s%n";
          // args to String.format
          // 1 ansi code
          // 2 date 
          // 3 source (class/method) 
          // 4 logger name 
          // 5 level 
          // 6 message, 
          // 7 throwable
          // output example
          // Jan 05, 2021 7:09:55 AM net.sf.jaer.eventprocessing.filter.BackgroundActivityFilter resetFilter
          //INFO: resetting BackgroundActivityFilter
      
          @Override
          public String format(LogRecord record) {
              date.setTime(record.getMillis());
              String source;
              if (record.getSourceClassName() != null) {
                  source = record.getSourceClassName();
                  if (record.getSourceMethodName() != null) {
                      source += " " + record.getSourceMethodName();
                  }
              } else {
                  source = record.getLoggerName();
              }
              String message = formatMessage(record);
              String throwable = "";
              if (record.getThrown() != null) {
                  StringWriter sw = new StringWriter();
                  PrintWriter pw = new PrintWriter(sw);
                  pw.println();
                  record.getThrown().printStackTrace(pw);
                  pw.close();
                  throwable = sw.toString();
              }
      
              switch (record.getLevel().toString()) {
                  case "INFO":
                      return String.format(FORMAT, ANSI_GREEN_BACKGROUND+ANSI_BLACK, date, source, record.getLoggerName(),
                              record.getLevel().getLocalizedName(), message + ANSI_RESET, throwable);
                  case "WARNING":
                      return String.format(FORMAT, ANSI_YELLOW_BACKGROUND+ANSI_BLACK, date, source, record.getLoggerName(),
                              record.getLevel().getLocalizedName(), message + ANSI_RESET, throwable);
                  case "SEVERE":
                      return String.format(FORMAT, ANSI_RED_BACKGROUND + ANSI_WHITE, date, source, record.getLoggerName(),
                              record.getLevel().getLocalizedName(), message + ANSI_RESET, throwable);
                  default:
                      return String.format(FORMAT, date, source, record.getLoggerName(),
                              record.getLevel().getLocalizedName(), message, throwable);
              }
          }
      }
      

      它在我在启动时指定的 Logging.properties 中实例化

      -Djava.util.logging.config.file=conf/Logging.properties
      

      Logging.properties 有这一行

      java.util.logging.ConsoleHandler.formatter = net.sf.jaer.util.LoggingAnsiColorConsoleFormatter
      

      输出如下所示

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-07-14
        • 2019-11-23
        • 2017-07-14
        • 1970-01-01
        • 2013-11-12
        • 1970-01-01
        • 1970-01-01
        • 2011-07-03
        相关资源
        最近更新 更多