【问题标题】:Subclassing java.util.logging.Formatter doesn't work子类化 java.util.logging.Formatter 不起作用
【发布时间】:2013-04-16 06:52:45
【问题描述】:

我正在使用java.util.logging 进行日志记录(我不想使用 log4j 或其他任何东西)。

这是我完整的私有 logging.properties:

handlers= java.util.logging.FileHandler
.level= INFO
java.util.logging.FileHandler.pattern = my.log
java.util.logging.FileHandler.limit = 500000
java.util.logging.FileHandler.count = 40
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

这是我程序中的代码:

public static Logger log = Logger.getLogger(MyClass.class.getName());
// Is there anything else to be init'ed here? 
// I don't. I just start using log directly in the code.

log.severe("something");
log.info("something else");

由于这将每条日志消息分为 2 行,所以我尝试了这个

How do I get java logging output to appear on a single line?

完全复制了第一个回复中的 LogFormatter 类。

在我的 logging.properties 中更改了一行

java.util.logging.FileHandler.formatter = com.mycomp.myproj.LogFormatter;

现在我的日志已经开始出现在 XML 中。我有一种强烈的感觉,FileHandler 不喜欢我的com.mycomp.myproj.LogFormatter,因此默认为默认的XMLFormatter。我如何弄清楚为什么 FileHandler 没有使用我的 LogFormatter 类?

【问题讨论】:

    标签: java logging


    【解决方案1】:

    您可以在 FileHandler 实例上的代码本身中设置格式化程序。

    import java.util.logging.FileHandler;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    
    // please change name of your own choice
    Logger log = Logger.getLogger("CustomLogger"); 
    log.setUseParentHandlers(false);
    log.setLevel(Level.ALL);
    
    FileHandler handler = new FileHandler("[log_file_location]");
    handler.setFormatter(new CustomFormatter()); // set formatter
    log.addHandler(handler);
    
    log.info("test message");
    
    handler.close(); // close the handler at some later point in your application.
    

    CustomFormatter 类定义如下。

    import java.util.logging.Formatter;
    import java.util.logging.LogRecord;
    
    public class CustomFormatter extends Formatter {
    
        @Override
        public String format(LogRecord record) {
            StringBuffer buffer = new StringBuffer();
            buffer.append(record.getMessage());
            return buffer.toString();
        }
    
    }
    

    您可以在 CustomFormatter 中编码,以您想要的任何格式输出消息。希望这会有所帮助。

    【讨论】:

    • 我会试试这个 - 但我的问题更多是关于为什么现有设置不起作用。我做错了什么?
    • log.setLevel(Level.ALL); - 这是必要的 - 我想使用我的 logging.properties 文件中指定的任何级别?
    • 还有 log_file_location - 我想使用 logging.properties 中指定的位置。
    • 试过了 - 没有 setLevel 和 log_file_location 一切正常。赞成。但是,仍然试图弄清楚为什么在 logging.properties 中设置处理程序不起作用。
    • 指定外部属性文件时必须在运行程序时指定它例如 java -Djava.util.logging.config.file=C:\logger.properties myProgram.class
    【解决方案2】:

    我如何找出 FileHandler 不使用我的 LogFormatter 类的原因?

    在调试器中启动程序并逐步执行代码。在LogManager.getLogger() 和/或LogManager.readConfiguration() 中设置断点

    或者忘记java.util.logging 并使用像logback 这样易于配置的框架,并在出现问题时为您提供有用的错误消息。

    【讨论】:

      【解决方案3】:

      好吧,这个也让我很生气,让我发疯,我不停地检查拼写,做谷歌搜索等 - 这就是我到达这里的方式 - 我知道这已经一岁了,但你会踢自己.我很确定这是您的答案。

      对于:

      java.util.logging.FileHandler.formatter = com.mycomp.myproj.LogFormatter;
      

      应该是:

      java.util.logging.FileHandler.formatter = com.mycomp.myproj.LogFormatter
      

      删除训练“;”。似乎需要将 exactly 与我看到其他人抱怨他们有尾随空格字符的类名匹配 - 这就是我的问题。更好的错误消息会有所帮助。

      干杯 - 马克

      【讨论】:

      • 为什么不能给1000分。我的尾随空间
      【解决方案4】:

      com.mycomp.myproj.LogFormatter 不在您的系统类路径中。

      LogManager 将执行以下调用来加载您的类:

      Formatter getFormatterProperty(String name, Formatter defaultValue) {
              String val = getProperty(name);
              try {
                  if (val != null) {
                      Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(val);
                      return (Formatter) clz.newInstance();
                  }
              } catch (Exception ex) {
                  // We got one of a variety of exceptions in creating the
                  // class or creating an instance.
                  // Drop through.
              }
              // We got an exception.  Return the defaultValue.
              return defaultValue;
      }
      

      您需要确保您的类 LogFormatter 在系统的类路径中。

      【讨论】:

        【解决方案5】:

        我发现除非您通过配置设置格式,否则它不会应用格式化程序。我在 JDK 11 上对此进行了测试。

        handlers= java.util.logging.FileHandler
        .level= INFO
        java.util.logging.FileHandler.pattern = my.log
        java.util.logging.FileHandler.limit = 500000
        java.util.logging.FileHandler.count = 40
        java.util.logging.FileHandler.formatter = com.mycomp.myproj.LogFormatter
        com.mycomp.myproj.LogFormatter.format = %n
        

        即添加最后一行com.mycomp.myproj.LogFormatter.format = %n

        【讨论】:

          【解决方案6】:

          可能这在这一点上不相关,但最近我发现了一个问题,格式中的 $ 给我带来了问题,它无法解析并回退为默认格式。原来我有

          [%1$tF %1$tT] [%4$-7s] %5$s %n
          

          logging.properties 文件中没有按预期工作,但是

          [%1\$tF %1\$tT] [%4\$-7s] %5\$s %n
          

          这与\$ 完美配合。将来可能会对其他人有所帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-06-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-04-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多