Logging with Java


When writing applications in Java it is incredibly useful to print out information as you go a long so that you can track what your application is doing and the state of various different variables.

One method of doing this is to use print statements, however, when it comes time to package your code into an application, you have to track down and delete/comment out all of these print statements. This is a long and arduous process when it could be solved by changing one line in your application.

Begin the Java logging module. In all my projects I use a class that contains 2 methods for creating a logger, one for logging to the console and another to log to a file.

Logger LOGGER = Logger.getLogger(name);
Handler ch = new ConsoleHandler();
Formatter fm = getFormatter();
LOGGER.addHandler(ch);
ch.setLevel(l);
ch.setFormatter(fm);
LOGGER.setLevel(l);
LOGGER.setUseParentHandlers(false);

The above code creates a new logger that logs to the console. It requires a “name” argument; this will be the name of this specific logger. The second argument, “l”, is the level at which to log (severe, warning, info, fine, all …) . This dictates what messages you will see on the console and which you won’t. For example, “all” will display all log messages generated by your program. Here is some example output of the program when you call the logger:

16:22:23 30/12/2018 - [Main] - [INFO] - Running Main.run()

The full code for the class can be found below as well as example usage of the class.

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.*;

public class LoggerFactory
{
    private final static DateFormat df = new SimpleDateFormat("hh:mm:ss dd/MM/yyyy");

    public static Logger getConsoleLogger(String name, Level l)
    {
        Logger LOGGER = Logger.getLogger(name);
        Handler ch = new ConsoleHandler();
        Formatter fm = getFormatter();
        LOGGER.addHandler(ch);
        ch.setLevel(l);
        ch.setFormatter(fm);
        LOGGER.setLevel(l);
        LOGGER.setUseParentHandlers(false);

        return LOGGER;
    }

    public static Logger getFileLogger(String name, Level l, String filename)
    {
        Logger LOGGER = Logger.getLogger(name);
        Formatter fm = getFormatter();
        try {
            FileHandler fh = new FileHandler(filename);
            fh.setFormatter(fm);
            fh.setLevel(l);
            LOGGER.addHandler(fh);
        } catch (IOException e) {
            System.err.println("Error opening log file: " + e.getMessage());
            ConsoleHandler ch = new ConsoleHandler();
            ch.setFormatter(fm);
            ch.setLevel(l);
            LOGGER.addHandler(ch);
        }
        LOGGER.setLevel(l);
        LOGGER.setUseParentHandlers(false);

        return LOGGER;
    }


    private static Formatter getFormatter()
    {
        Formatter fm = new Formatter()
        {
            @Override
            public String format(LogRecord record)
            {
                StringBuilder builder = new StringBuilder(1000);
                builder.append(df.format(new Date(record.getMillis()))).append(" - ");
                builder.append("[").append(record.getSourceClassName()).append("] - ");
                builder.append("[").append(record.getLevel()).append("] - ");
                builder.append(formatMessage(record));
                builder.append("\n");
                return builder.toString();
            }
        };
        return fm;
    }
}