Java:
Logging
How to:
Here’s a simple way to get started with logging in Java using the built-in java.util.logging
package.
import java.util.logging.Logger;
import java.util.logging.Level;
public class AppLogging {
private final static Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
public static void main(String[] args) {
LOGGER.info("Logging an INFO-level message");
try {
int division = 10 / 0;
} catch (ArithmeticException e) {
LOGGER.log(Level.SEVERE, "Exception occur", e);
}
}
}
This would produce output along the lines of:
Jul 03, 2023 2:00:00 PM AppLogging main
INFO: Logging an INFO-level message
Jul 03, 2023 2:00:00 PM AppLogging main
SEVERE: Exception occur
java.lang.ArithmeticException: / by zero
at AppLogging.main(AppLogging.java:10)
Deep Dive
Logging in Java has evolved quite a bit. Historically, logging was more ad-hoc with system outputs and self-written mechanisms. However, the need for standardization led to logging APIs like Log4j
and SLF4J
. The java.util.logging
package itself was introduced in JDK 1.4, providing a standardized way to log messages.
Alternatives to java.util.logging
(JUL) include Log4j 2 and SLF4J. While JUL is built into Java and thus doesn’t require additional dependencies, both Log4j 2 and SLF4J offer more advanced features like more granular control over logging configuration, asynchronous logging, and better performance.
Implementation-wise, logging can either be synchronous, where each log message is processed in the thread that generated it, or asynchronous, where messages are handed off to a separate thread. Asynchronous logging can improve performance but introduces complexity as one must handle concurrency and ensure that log messages are not lost on application crash.