JEP 264: Platform Logging API and Service
Summary
Define a minimal logging API which platform classes can use to log messages, together with a service interface for consumers of those messages. A library or application can provide an implementation of this service in order to route platform log messages to the logging framework of its choice. If no implementation is provided then a default implementation based upon the java.util.logging
API is used.
Goals
-
Defined and used in the
java.base
module, hence it cannot depend upon thejava.util.logging
API. -
Be easily adoptable by applications which use external logging framework, such as SLF4J or Log4J.
-
Reduce dependences on the
java.logging
module in order to simplify the JDK module graph. -
Deals with bootstrap issues, so that platform classes can log messages before the log consumer is initialized.
-
By default, log messages via the
java.util.logging
API when thejava.logging
module is present.
Non-Goals
-
It is not a goal to define a general-purpose interface for logging. The service interface contains only the minimal set of methods that the JDK needs for its own usage.
-
It is not a goal to support programmatic logging configuration (setting levels, destination files, etc...) via the API.
-
It is not a goal to convert all classes in the JDK to log via this new API.
Motivation
Compared to the java.util.logging
API, most modern logging frameworks (e.g., Log4J 2.0, Logback) are separated into a facade and an implementation. An application that logs through such an external framework should create loggers and perform logging through the facade provided, or supported, by that framework.
The proposed service enables applications to configure the JDK to use the same logging framework as the application: It would only need to provide an implementation of the service that returns platform loggers that wrap the loggers of the preferred logging framework.
The application would continue to use the facade provided by the logging framework it is using. The LoggerFinder
service makes it possible to configure the JDK to use that same framework.
Description
Using the java.util.ServiceLoader
API, a system-wide LoggerFinder
implementation is located and loaded using the system class loader. If no concrete implementation is found, the JDK internal default implementation of the LoggerFinder
service is used. The default implementation of the service uses java.util.logging
as a backend when the java.logging
module is present so that, by default, log messages are routed to java.util.logging.Logger
as before. However, the LoggerFinder
service makes it possible for an application/framework to plug in its own external logging backend, without needing to configure both java.util.logging
and that backend.
An implementation of the LoggerFinder
service should make it possible to distinguish system loggers (used by system classes from the Bootstrap Class Loader (BCL)) and application loggers (created by an application for its own usage). This distinction is important for platform security. The creator of a logger can pass the class or module for which the logger is created to the LoggerFinder
so that the LoggerFinder
can figure out which kind of logger to return.
Classes in the JDK obtain loggers created from the LoggerFinder
by invoking factory methods of the System
class:
package java.lang;
...
public class System {
System.Logger getLogger(String name) { ... }
System.Logger getLogger(String name, ResourceBundle bundle) { ... }
}
The JDK-internal sun.util.logging.PlatformLogger
API will be revised to emit log messages via the system loggers returned by these methods.
Testing
New tests will be added to test both the LoggerFinder
service and the mapping to the default java.util.logging
backend. We will also need to verify that plugging in an existing external framework is working, especially with respect to potential bootstrap issues.
Risks and Assumptions
When java.util.logging
is the backend, JDK classes that have been converted to use the system loggers should still be configurable via java.util.logging
as before and, if possible, log messages and levels should not be altered.
Some Java SE APIs currently expose java.util.logging
types in their public signatures. This may be an obstacle in converting those APIs to log via the system loggers.