为什么在 System.Logger 中使用 log(DEBUG, msg) 而不是 debug(msg)?

Pav*_*l_K 3 java logging java-9

我正在阅读 Java 9 中引入的 System.Logger API。我不明白他们为什么开发这样的strangeAPI:

System.Logger {
  public default void log(Level level, String msg){...}
}
Run Code Online (Sandbox Code Playgroud)

我调用它strange是因为所有流行的日志框架(我知道)都不将级别作为参数,而是按级别名称命名调用方法。例如:

//Log4j
logger.error("This is error : " + parameter);
//SLF4J
logger.debug("Printing variable value: {}", variable);
//apache.commons.logging
log.debug(Object message);
//and even sun.util.logging.PlatformLogger
logger.warning(String msg)
Run Code Online (Sandbox Code Playgroud)

怎么解释?

Rea*_*tic 5

关于开发人员意图的问题本质上很难回答,除非您是开发人员。

话虽如此,我们确实可以访问此功能的原始提案 - JEP 264

摘要:

定义一个最小的日志 API,平台类可以使用它来记录消息,以及为这些消息的使用者提供服务接口。库或应用程序可以提供此服务的实现,以便将平台日志消息路由到其选择的日志记录框架。如果未提供实现,则使用基于 java.util.logging API 的默认实现。

从目标来看:

易于被使用外部日志框架的应用程序采用,例如 SLF4J 或 Log4J。

从非目标:

定义用于日志记录的通用接口不是目标。服务接口仅包含 JDK 自身使用所需的最少方法集。

所以我们这里所拥有的不是像 SLF4J、Log4J 等那样的“又一个日志框架”。我们拥有的是一个接口,它允许您告诉 JVM 使用与您在应用程序中使用的类相同的日志工具,用于记录自己的东西。

典型的使用场景是一个应用程序,它在 SLF4J 中进行了复杂的设置,记录到控制台、文件、数据库或向手机发送文本。您希望 JVM 类使用相同的系统。所以你编写了一个适配器——一个实现System.Logger接口的类,使用你的 SLF4J 设置。

并不是说您不能使用当前的系统记录器进行日志记录 - 您可以 - 但这不是它的创建目的。它是为您实现和设置系统记录器而创建的,以便它调用您选择的日志记录框架。

在目前的形式下,当你实现时,你只需要实现四个方法:

  • getName()
  • isLoggable(System.Logger.Level)
  • log(System.Logger.Level, ResourceBundle, String, Object...)
  • log?(System.Logger.Level, ResourceBundle, String, Throwable)

现在,System.Logger.Level有七个级别。想象一下,如果不是必须实现两个日志记录方法,而是必须实现 14 个日志记录方法?通常情况下,这些实现看起来完全一样,只是名称稍有变化。这并不明智。

就目前而言,几乎每个现有的日志记录框架都有一个log(level,...)方法,然后System.Logger's的实现log(...)通常可以简单地通过从 映射System.Logger.Level到框架的 Level 定义来完成。


如果你想记录一条消息?

好吧,如果您使用复杂的日志记录平台,您可以直接在那里记录您的消息,而无需通过系统记录器。如果您坚持使用它 - 您需要使用级别作为参数或编写自己的包装器。这根本不是开发人员想到的用例。