即使关闭,日志记录也会产生大量开销吗?

时间:2017-09-29 20:01:25

标签: java logging

我想在我的代码中使用fine / fine / finest添加详细的日志记录信息,以帮助我调试代码。使用logger而不是System.out.println()的一个好处(也许是整点)是我可以灵活地改变我想要看到的信息的级别。最后,一旦我完成调试,我可以将我的日志记录设置为OFF或SEVERE。

但令我担心的是,即使我将日志设置为OFF,广泛使用日志消息也可能会影响我的应用程序在生产时的性能。这是一个值得关注的问题吗?或者java日志记录的设计方式是,通过将日志记录级别设置为OFF,日志记录的所有开销都消失了?

请注意,即使我们没有为日志消息连接字符串,如果我们经常使用它,我们仍可能面临性能开销。

由于

2 个答案:

答案 0 :(得分:3)

不,没有明显的开销。

您在评论中提到您正在使用Java SE的日志记录包。来自java.util.logging.Logger documentation

  

在每次日志记录调用时,Logger最初会根据记录器的有效日志级别对请求级别(例如,SEVERE或FINE)执行廉价检查。如果请求级别低于日志级别,则日志记录调用立即返回。

换句话说,如果级别不是可记录级别,则log方法都会立即返回。仅仅调用返回如此快速的方法的“开销”将以纳秒为单位进行测量,如果它可以测量的话。

不必要的字符串连接,而不是正确的参数化日志记录,可以创建性能问题,但您似乎已经意识到这一点。 (我在其他可能不知道这个问题的读者中提到它。)

答案 1 :(得分:-1)

Logging的一个很好的实现是:

interface ILogger { void fine(String s); void finer(String s); void finest(String s); }
class Logger {
  public static ILogger logger;
  public static fine(String s){ logger.fine(s); }
  public static finer(String s){ logger.finer(s); }
  public static finest(String s){ logger.finest(s); }
}
class FineLogger implements ILogger {
  public fine(String s){ System.out.println(s); }
  public finer(String s){ }
  public finest(String s){ }
}
class FinerLogger implements ILogger {
  public fine(String s){ System.out.println(s); }
  public finer(String s){ System.out.println(s); }
  public finest(String s){ }
}
class FinestLogger implements ILogger {
  public fine(String s){ System.out.println(s); }
  public finer(String s){ System.out.println(s); }
  public finest(String s){ System.out.println(s); }
}

所以在配置方法中你只需设置Logger.logger = new FinestLogger();或其他级别和任何地方使用Logger.fine / r / st方法。

要通过配置启用它,您可以从包含这样一行logger_level的file.properties中读取:在main方法上为fine。

main(String...args) {
   Properties props = new Properties();
   props.load(new FileInputStream(new File("C:/project/mysystem.properties");
   switch(props.get("logger_level) {
      case "fine":
Logger.logger = new FineLogger(); break;
      case "finer":
Logger.logger = new FinerLogger(); break;
      case "finest":
Logger.logger = new FinestLogger(); break;
}
Logger.fine("Fine");
Logger.finer("Finer");
Logger.finest("Finest");

如果你的logger_level很好,那么只打印世界'Fine',其他的将被忽略。

这样你就可以完全避免检查布尔值或枚举或常量。

请注意,pattern可以创建新的实现,如FileLogger等。