Why in System.Logger is log(DEBUG, msg) used instead of debug(msg)?

Pavel_K :

I am reading System.Logger API that was introduced in Java 9. And I can't understand why they developed so strange API:

System.Logger {
  public default void log(Level level, String msg){...}
}

I call it strange because all popular logging frameworks (I know) don't put level as argument, but name the calling method by level name. For example:

//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)

How to explain it?

RealSkeptic :

Questions about the intentions of developers are inherently difficult to answer, unless you are the developer.

That being said, we do have access to the original proposal for this feature - JEP 264.

The 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.

From the goals:

Be easily adoptable by applications which use external logging framework, such as SLF4J or Log4J.

From the 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.

So what we have here is not "Yet another logging framework" like SLF4J, Log4J, etc. What we have is an interface that allows you to tell the JVM to use the same logging tool that you are using for the classes in your application, for logging its own stuff.

The typical usage scenario would be an application which has a complex setup in, say, SLF4J, logging to console, files, databases, or sending text to phones. You want the JVM classes to use the same system. So you write an adapter - a class that implements the System.Logger interface, using your SLF4J setup.

It's not that you can't use the current system logger for logging - you can - but that's not what it was created for. It was created for you to implement and set the system logger so that it calls your logging framework of choice.

In its current form, when you implement, you only need to implement four methods:

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

Now, System.Logger.Level has seven levels. Imagine if instead of having to implement two logging methods, you had to implement 14 logging methods? And more often than not, those implementation would look exactly the same, with one little name change. This is not wise.

As it stands, almost every existing logging framework has a log(level,...) method, and then the implementation of System.Logger's log(...) can usually be done simply by mapping from the System.Logger.Level to your framework's definition of Level.


And if you want to log a message?

Well, if you are using a complex logging platform, you log your message there directly, you don't need to go through the system logger. If you insist on using it - you'll need to use the levels as arguments or write your own wrappers. This is simply not the use case the developers had in mind.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=95598&siteId=1