Background
Since JDK 1.4 there is a default Logging API in Java. The entire Logging API is contained in the package java.util.logging.
Reference: https://docs.oracle.com/javase/8/docs/technotes/guides/logging/overview.html
Usage
import java.util.logging.Level;
import java.util.logging.Logger;
public class LoggerTest {
private static final Logger log = Logger.getLogger(LoggerTest.class.getName());
public void something() throws Exception {
if (log.isLoggable(Level.FINEST)) {
log.finest("Enter something()...");
}
log.info("Logging result");
log.warning("Another logging result");
log.log(Level.SEVERE, "Nullpoint here", new NullPointerException("divide by zero"));
if (log.isLoggable(Level.FINEST)) {
log.finest("Exit something()");
}
}
}
Default Logging Configuration
Java comes with a default logging configuration file, that only contains a ConsoleHandler and writes to standard error.
$JAVA_HOME/lib/logging.properties
handlers= java.util.logging.ConsoleHandler
.level= INFO
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
com.xyz.foo.level = SEVERE
Configuration
To change default configuration, create a new configuration file and add a system property java.util.logging.config.file to you java process, which point to yours configuration file. Example:
java ... -Djava.util.logging.config.file=/tmp/logging.properties ...
The available handlers/appenders and their configuration are:
handlers = java.util.logging.FileHandler, java.util.logging.ConsoleHandler
.level = INFO
java.util.logging.FileHandler.level = ALL
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.FileHandler.encoding = UTF-8
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 10
java.util.logging.FileHandler.pattern = %h/java-%g.log
java.util.logging.FileHandler.append = true
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.encoding = UTF-8
java.util.logging.StreamHandler.level = ALL
java.util.logging.StreamHandler.encoding = UTF-8
java.util.logging.SocketHandler.level = ALL
java.util.logging.SocketHandler.encoding = UTF-8
java.util.logging.SocketHandler.host =
java.util.logging.SocketHandler.port =
java.util.logging.MemoryHandler.level = ALL
java.util.logging.MemoryHandler.size =
java.util.logging.MemoryHandler.push =
java.util.logging.MemoryHandler.target =
java.util.logging.SimpleFormatter.format = %1$tF'T'%1$tT.%1$tL%1$tz [%4$s] %2$s - %5$s %6$s%n
se.magnuskkarlsson.examples.lambda.level = FINEST
Log Levels
Java Logging API has the following levels: OFF, SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL
You define a global log level with .level, then if you need specific configuration you add: <package>[.class].level=<level>
NOTE: ConsoleHandler is special, for that you need to set ConsoleHandler.level for others you don't!
Log Formatter
There exists only two formatter and you typically want to use the SimpleFormatter.
NOTE: Most handlers uses the SimpleFormatter as default, but some do not. For them you need to set the formatter configuration.
Configure java.util.logging.SimpleFormatter
The default format is quite odd, so you want to change that.
The configuration is done with java.util.logging.SimpleFormatter.format. And the value is for the java call in java.util.logging.SimpleFormatter.format(LogRecord)
return String.format(format,
dat,
source,
record.getLoggerName(),
record.getLevel().getLocalizedLevelName(),
message,
throwable);
To understand the java.lang.String.format(String, Object...) syntax, read https://docs.oracle.com/javase/8/docs/api/java/util/Formatter.html#syntax.