JEP 264:平台日志记录 API 和服务
概括
定义平台类可用于记录消息的最小日志记录 API,以及这些消息的使用者的服务接口。库或应用程序可以提供此服务的实现,以便将平台日志消息路由到其选择的日志框架。如果未提供实现,则java.util.logging
使用基于 API 的默认实现。
目标
-
在模块中定义和使用
java.base
,因此它不能依赖于java.util.logging
API。 -
易于被使用外部日志框架(例如SLF4J或Log4J)的应用程序采用。
-
减少对模块的依赖
java.logging
,以简化 JDK 模块图。 -
处理引导问题,以便平台类可以在日志使用者初始化之前记录消息。
-
java.util.logging
默认情况下,当java.logging
模块存在时通过 API 记录消息。
非目标
-
定义通用的日志记录接口并不是我们的目标。服务接口仅包含 JDK 自身使用所需的最小方法集。
-
通过 API 支持编程式日志记录配置(设置级别、目标文件等)并不是目标。
-
我们的目标并不是将 JDK 中的所 有类转换为通过这个新 API 进行日志记录。
动机
与 API 相比java.util.logging
,大多数现代日志框架(例如 Log4J 2.0、Logback)都分为外观和实现。通过此类外部框架进行日志记录的应用程序应创建记录器并通过该框架提供或支持的外观执行日志记录。
建议的服务使应用程序能够将 JDK 配置为使用与应用程序相同的日志记录框架:它只需要提供返回包装首选日志记录框架记录器的平台记录器的服务实现。
应用程序将继续使用它正在使用的日志框架提供的外观。该LoggerFinder
服务使得配置 JDK 以使用相同的框架成为可能。
描述
使用java.util.ServiceLoader
API,LoggerFinder
可以使用系统类加载器定位并加载系统范围的实现。如果没有找到具体的实现,LoggerFinder
则使用该服务的 JDK 内部默认实现。当模块存在时,服务的默认实现用作java.util.logging
后端,因此默认情况下,日志消息会像以前一样路由到。但是,该服务使应用程序/框架可以插入其自己的外部日志记录后端,而无需同时配置该后端。java.logging``java.util.logging.Logger``LoggerFinder``java.util.logging
该服务的实现LoggerFinder
应该能够区分系统记录器(由引导类加载器 (BCL) 中的系统类使用)和应用程序记录器(由应用程序创建供其自身使用)。这种区别对于平台安全很重要。记录器的创建者可以将为其创建记录器的类或模块传递给 ,LoggerFinder
以便能够LoggerFinder
确定要返回哪种类型的记录器。
JDK中的类通过LoggerFinder
调用类的工厂方法来获取创建的记录器System
:
package java.lang;
...
public class System {
System.Logger getLogger(String name) { ... }
System.Logger getLogger(String name, ResourceBundle bundle) { ... }
}
JDK 内部sun.util.logging.PlatformLogger
API 将被修改为通过这些方法返回的系统记录器发出日志消息。
测试
将添加新的测试来测试LoggerFinder
服务和到默认后端的映射java.util.logging
。我们还需要验证插入现有外部框架是否正常工作,特别是在潜在的引导问题方面。
风险和假设
当java.util.logging
是后端时,已转换为使用系统记录器的 JDK 类仍应java.util.logging
像以前一样可通过配置,并且如果可能,不应更改日志消息和级别。
目前,一些 Java SE APIjava.util.logging
在其公共签名中公开类型。这可能是通过系统记录器将这些 API 转换为日志的障碍。