Logger
We create a logger object using the getLogger static method. We can log messages at different levels.
import java.util.logging.Level;
import java.util.logging.Logger;
class LoggerApp {
public static void main(String[] args) {
final Logger LOGGER =
Logger.getLogger(LoggerApp.class.getName()); // {}
LOGGER.info("Logger name: " + LOGGER.getName());
int[] numbers = {1, 2, 3};
try {
int current = numbers[4];
} catch(ArrayIndexOutOfBoundsException ex) {
LOGGER.log(Level.SEVERE, "Exception: ", ex);
}
}
}
/*
Jun 22, 2021 10:55:46 AM LoggerApp main
INFO: Logger name: LoggerApp
Jun 22, 2021 10:55:46 AM LoggerApp main
SEVERE: Exception:
java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 3
at LoggerApp.main(LoggerApp.java:15)
*/
HANDLER
The handler is responsible for printing the log message. This example generates a xml log file and console messages.
import java.io.IOException;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
class LoggerApp {
public static void main(String[] args) throws IOException {
final Logger LOGGER =
Logger.getLogger(LoggerApp.class.getName()); // {}
Handler handler1 = new ConsoleHandler();
Handler handler2 = new FileHandler("./LogerApp.log");
LOGGER.addHandler(handler1);
LOGGER.addHandler(handler2);
handler1.setLevel(Level.ALL);
handler2.setLevel(Level.ALL);
LOGGER.setLevel(Level.ALL);
LOGGER.config("Loggger configuration done");
}
}
/*
-- LoggerApp.log --
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
<date>2021-06-22T08:19:39.914918Z</date>
<millis>1624349979914</millis>
<nanos>918000</nanos>
<sequence>0</sequence>
<logger>LoggerApp</logger>
<level>CONFIG</level>
<class>LoggerApp</class>
<method>main</method>
<thread>1</thread>
<message>Loggger configuration done</message>
</record>
</log>
*/
FORMATER
A Formater is used to format the log. Java provides two built-in formaters SimpleFormat and XMLFormat.
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
class LoggerApp {
public static void main(String[] args) throws IOException {
final Logger LOGGER =
Logger.getLogger(LoggerApp.class.getName()); // {}
Handler h = new FileHandler("./LogerApp.formatter.log");
LOGGER.addHandler(h);
LOGGER.setLevel(Level.ALL);
Formatter f = new SimpleFormatter();
h.setFormatter(f);
h.setLevel(Level.ALL);
LOGGER.info("My simple message");
}
}
/*
-- LogerApp.formatter.log --
Jun 22, 2021 12:18:17 PM LoggerApp main
INFO: My simple message
*/
CONFIG
You can provide a configuration properties file. This helps to remove the configuration from code.
import java.io.FileInputStream;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.LogManager;
import java.util.logging.Logger;
class LoggerApp {
public static void main(String[] args) throws IOException {
final Logger LOGGER = Logger.getLogger("myLogger");
final LogManager MANAGER = LogManager.getLogManager();
MANAGER.readConfiguration(
new FileInputStream("LoggerApp.properties")
);
Handler h = new FileHandler("./LogerApp.log");
LOGGER.addHandler(h);
LOGGER.log(Level.INFO, "My simple message");
}
}
/*
-- LoggerApp.properties --
handlers=java.util.logging.FileHandler
.level=ALL
java.util.logging.FileHandler.level=ALL
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
myLogger.level=ALL
-- LoggerApp.log --
Jun 22, 2021 1:11:50 PM LoggerApp main
INFO: My simple message
*/
SEQUENCE
Create an instance of FileHandler with 5 files sequence. Set a specific size for each file + append flag set to true.
import java.io.FileInputStream;
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.LogManager;
import java.util.logging.Logger;
class LoggerApp {
public static void main(String[] args) throws IOException {
Logger LOGGER = Logger.getLogger("myLogger");
LogManager MANAGER = LogManager.getLogManager();
MANAGER.readConfiguration(
new FileInputStream("LoggerApp.properties")
);
final int FILE_SIZE = 1024; // default 1000000 (1 MB)
final int LIMIT = 5;
Handler h =
new FileHandler("./app.log", FILE_SIZE, LIMIT, true);
LOGGER.addHandler(h);
for(int i=0; i<30; i++) { // loop to generate 2 files
LOGGER.info("My log message");
}
}
}
/*
-- Gemerates 2 log files (from maximum 5 permitted) --
app.log.0
app.log.1
*/
Log4j
The logging framework is something you don't want to be bundled with the JVM. Java default logger isn't well suited for multiple applications in the same JVM. Also, log4j is thread-safe and optimize for speed.
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
class LoggerApp {
public static void main(String[] args) {
PropertyConfigurator.configure("./log4j.properties");
Logger logger = Logger.getLogger("myLogger");
logger.debug("My debug message");
logger.info("My info message");
}
}
/*
-- logs/myapp.log --
My debug message
My info message
*/
# log4j.properties
log4j.rootLogger = DEBUG, FILE
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=./logs/myapp.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
You can change the root logger level.
Logging can be redirected to both console and file.
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
class LoggerApp {
public static void main(String[] args) {
PropertyConfigurator.configure("./log4j.properties");
Logger logger = Logger.getLogger("myLogger");
logger.debug("My debug message"); // this will be ignored
logger.info("My info message");
}
}
/*
-- logs/myapp.log --
My info message
*/
# log4j.properties
log4j.rootLogger = INFO, FILE, stdout
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=./logs/myapp.log
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
Last update: 455 days ago