-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
-
15
-
generic
-
generic
A DESCRIPTION OF THE PROBLEM :
Despite JEP 264 having added the "Platform Logging API and Service" (JDK-8046565) and the existance of logging API facades such as SLF4J and the Log4j 2 API, often libraries still use `java.util.logging` for logging.
This creates the need to be able to bridge from `java.util.logging` to the logging framework used by a project, e.g. Logback or Log4j 2.
However, at the moment a custom `java.util.logging.LogManager` can only be specified through the System property `java.util.logging.manager`, and once the `LogManager` has been initialized it cannot be replaced anymore. This is a huge pain point for other logging frameworks which try to redirect `java.util.logging`.
Logback / SLF4J and Log4j 2 chose different implementations, but both have disadvantages:
# Logback / SLF4J:
Is implemented as a JUL Handler: http://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html
Disadvantages:
- Has to be explicitly installed, either through code (see SLF4JBridgeHandler doc), or by reading LogManager configuration file
- Re-reading of configuration file (possibly in unrelated project on classpath) uninstalls handler
- Installation of handler has to happen at every entry point (configuration through `conf/logging.properties` often not viable / possible); this is especially a problem when the project is used as library and has a large amount of possible entry points
- JUL still sits in between logging calls and SLF4J, therefore changing SLF4J level (especially lowering it to DEBUG) has no effect on JUL, need to add additional configuration such as Logback's LevelChangePropagator
# Log4j 2
Is implemented as LogManager subclass https://logging.apache.org/log4j/2.x/log4j-jul/index.html
Disadvantages:
- Has to be specified using System property
- Because it is hard / impossible to control when LogManager is loaded, System property needs to be set on startup
This is impossible when the project is used as library, e.g. here for `child-project`:
parent-project
- child-project
- log4j-jul
- external-lib-using-jul
- log4j
Requiring all dependent projects to set a System property on startup is extremely error prone (and maybe not even possible in all situations).
To clarify, this is not supposed to show flaws in SLF4J or Log4j 2, but shows which difficulties they are facing when implementing different approaches of redirecting `java.util.logging`.
The underlying problem is that a custom `java.util.logging.LogManager` can only be specified through a System property.
This could be solved by having LogManager additionally use ServiceLoader to locate LogManager implementations in case the System property is not set, and similar to LoggerFinderLoader report an error if multiple providers are found. This would solve all the disadvantages listed above and would allow bridging `java.util.logging` to a different logging framework by merely including a 'bridge' library on the classpath which has the respective provider configuration file.
Despite JEP 264 having added the "Platform Logging API and Service" (
This creates the need to be able to bridge from `java.util.logging` to the logging framework used by a project, e.g. Logback or Log4j 2.
However, at the moment a custom `java.util.logging.LogManager` can only be specified through the System property `java.util.logging.manager`, and once the `LogManager` has been initialized it cannot be replaced anymore. This is a huge pain point for other logging frameworks which try to redirect `java.util.logging`.
Logback / SLF4J and Log4j 2 chose different implementations, but both have disadvantages:
# Logback / SLF4J:
Is implemented as a JUL Handler: http://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html
Disadvantages:
- Has to be explicitly installed, either through code (see SLF4JBridgeHandler doc), or by reading LogManager configuration file
- Re-reading of configuration file (possibly in unrelated project on classpath) uninstalls handler
- Installation of handler has to happen at every entry point (configuration through `conf/logging.properties` often not viable / possible); this is especially a problem when the project is used as library and has a large amount of possible entry points
- JUL still sits in between logging calls and SLF4J, therefore changing SLF4J level (especially lowering it to DEBUG) has no effect on JUL, need to add additional configuration such as Logback's LevelChangePropagator
# Log4j 2
Is implemented as LogManager subclass https://logging.apache.org/log4j/2.x/log4j-jul/index.html
Disadvantages:
- Has to be specified using System property
- Because it is hard / impossible to control when LogManager is loaded, System property needs to be set on startup
This is impossible when the project is used as library, e.g. here for `child-project`:
parent-project
- child-project
- log4j-jul
- external-lib-using-jul
- log4j
Requiring all dependent projects to set a System property on startup is extremely error prone (and maybe not even possible in all situations).
To clarify, this is not supposed to show flaws in SLF4J or Log4j 2, but shows which difficulties they are facing when implementing different approaches of redirecting `java.util.logging`.
The underlying problem is that a custom `java.util.logging.LogManager` can only be specified through a System property.
This could be solved by having LogManager additionally use ServiceLoader to locate LogManager implementations in case the System property is not set, and similar to LoggerFinderLoader report an error if multiple providers are found. This would solve all the disadvantages listed above and would allow bridging `java.util.logging` to a different logging framework by merely including a 'bridge' library on the classpath which has the respective provider configuration file.