A Brief Introduction of Using Java Logger

Posted by Hank Lee on Friday, May 8, 2020

9 Minutes Read

Table of Contents

Recently, I am asked to record some information about how my server runs. So, I decide to use java.util.logging.Logger to implement the logging process. Also this article will give you a sample code of how to use the basic function of java.util.logging.Logger.

Brief Introduction

java.util.logging.Logger is a class object used to log information in systems or applications. You don’t need to use lots of System.out.println("WHATEVER MESSAGE YOU PRINT") to print in the console, and also with java.util.logging.Logger, you can easily print the log into a file, which make you much more convenient to maintain you log files.

There are different levels you can use in java.util.logging.Logger. Those levels are delcared in java.util.logging.Level. The levels are:

  • SEVERE (highest value)
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST (lowest value)

Besides, there is a level “OFF” which can be used to turn off logging, and a level “ALL” to enable to log all the messages.

A Simple Example

  1. Use Java Logger in code There is a very simple example of using java.util.logging.Logger.
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Hank Lee
 * Shared in InformisTry -- https://jumperc2p.github.io/InformisTry/
 *
 */
public class MyLogger {

	public static void main(String[] args) {
		
		// use the method "getLogger(String name)" in Logger class to get a Logger object
		Logger logger = Logger.getLogger("MyLogger"); 
		
		// set the level of the logger as INFO
		logger.setLevel(Level.INFO);
		
		// use java.util.Random to receive a random number
		Random random = new Random();
		
		//setup a range to random number
		int range = 50;
		
		while (true) {
			// get a random number
			int number = random.nextInt(range);
			
			logger.log(Level.INFO, "The random number is :" + number);
			
			// when the remainder of random number divided 7 is 0 , stop the while loop.
			if (number % 7 == 0) {
				break;
			}
		}
	}
}

In this sample, I just call the method getLogger(String name) in java.util.logging.Logger to get a Logger object, and set the level of logger is INFO. Then, I use a while loop to log the random number until the remainder of the random number divided 7 is 0. After executing the MyLogger.java, the messages are printed in console (shown as below).

May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :31
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :39
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :17
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :13
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :5
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :32
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :39
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :39
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :41
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :8
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :18
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :39
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :43
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :5
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :9
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :36
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :38
May 04, 2020 11:02:26 PM logging_example.MyLogger main
INFO: The random number is :28

The logging_example in the message is my package, and main is the method where call Logger object to log messages.

  1. Use Java Logger to Print Messages Into A File Now, you know how to use java.util.logging.Logger, but what if you need to write log messages into a file?😖 Don’t wory. It’s very easy to achieve the goal by using java.util.logging.Logger with java.util.logging.FileHandler. The sample code is as below.
package logging_example;

import java.io.IOException;
import java.util.Random;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

/**
 * @author Hank Lee
 * Shared in InformisTry -- https://jumperc2p.github.io/InformisTry/
 *
 */
public class MyLoggerWithFileOutput {

	public static void main(String[] args) {
		
		// use the method "getLogger(String name)" in Logger class to get a Logger object
		Logger logger = Logger.getLogger("MyLogger"); 
		
		// Declare a FileHandler variable.
		FileHandler fh;
		
		// set the level of the logger as INFO
		logger.setLevel(Level.INFO);
		
		try {
			// create a new FileHandler object with the log file path
			fh = new FileHandler(System.getProperty("user.dir")+"/informistry.log");
			
			// create a SimpleFormatter object to setup the format of log
			SimpleFormatter formatterFH = new SimpleFormatter();  
			// set the SimpleFormatter to the FileHandler
			fh.setFormatter(formatterFH); 
			
			// add the FileHandler to the logger
			logger.addHandler(fh);
			
			// use java.util.Random to receive a random number
			Random random = new Random();
			
			//setup a range to random number
			int range = 50;
			
			while (true) {
				// get a random number
				int number = random.nextInt(range);
				
				logger.log(Level.INFO, "The random number is :" + number);
				
				// when the remainder of random number divided 7 is 0 , stop the while loop.
				if (number % 7 == 0) {
					break;
				}
			}
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}  
	}
}

There are the other class I used to write log messages to a file: java.util.logging.FileHandler and java.util.logging.SimpleFormatter. The fronter is used to declare where and which file to write log messages, and the latter is used to format the log messages. After running the program, it generates a log file named informistry.log at the root, and it contains:

May 04, 2020 11:16:48 PM logging_example.MyLoggerWithFileOutput main
INFO: The random number is :32
May 04, 2020 11:16:48 PM logging_example.MyLoggerWithFileOutput main
INFO: The random number is :21

Not that hard, right?!👍

Extra Example - Use Java Logger in Different Threads with java.util.Socket

Bouns Time🤣: How to combine Java Logger with java.util.Socket in different threads. The socket program code I used is mentioned in my another article. If you want to know how to implement a socket program which can handle multiple threas, take a look at A Combination of TimerTask and Timer. Here, I just add the logging part into the socket program. So, in the sample code, I just add a Logger class MyLoggerWithFileOutput.java and call the MyLogger.java in other java files.

The sample code of MyLoggerWithFileOutput.java is shown as below. I make it as a singleton object as I want all the threads to use the same Logger object and write log messages into the same file.

import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

/**
 * @author Hank Lee
 * Shared in InformisTry -- https://jumperc2p.github.io/InformisTry/
 * Singleton Object
 */
public class MyLoggerWithFileOutput {
	
	private static  Logger logger;
	
	public static  Logger getLogger() {
		
		if(logger == null) {
			
			logger = Logger.getLogger("MyLoggerWithFileOutput"); 
			
			// use the method "getLogger(String name)" in Logger class to get a Logger object
			logger = Logger.getLogger("MyLogger"); 
			
			// Declare a FileHandler variable.
			FileHandler fh;
			
			// set the level of the logger as INFO
			logger.setLevel(Level.INFO);
			
			try {
				// create a new FileHandler object with the log file path
				fh = new FileHandler(System.getProperty("user.dir")+"/informistry.log");
				
				// create a SimpleFormatter object to setup the format of log
				SimpleFormatter formatterFH = new SimpleFormatter();  
				// set the SimpleFormatter to the FileHandler
				fh.setFormatter(formatterFH); 
				
				// add the FileHandler to the logger
				logger.addHandler(fh);
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}  
		}
		 
		 return logger;
	}
}

The sample code of adding the Logger in Server.java and ClientThreadHandler.java:

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Hank Lee
 * Shared in InformisTry -- https://jumperc2p.github.io/InformisTry/
 *
 */
public class Server {
	
	private final int PORT = 61023;
	private Socket connection;
	private static Logger MyLogger = MyLoggerWithFileOutput.getLogger();
	
	public Server() {
		
		 ServerSocket server = null;
		 List<ClientThreadHandler> clients = new ArrayList<>();
		 
		 try{
			 
			// create a new socket
            server = new ServerSocket(PORT);
            MyLogger.log(Level.INFO, "Starts the server");
            System.out.println("Starts the server");

            while (true) {
                MyLogger.log(Level.INFO, "Waiting for new connections...");
                System.out.println("Waiting for new connections...");
                // accept connections from client
                connection = server.accept();
                clients.add(new ClientThreadHandler(connection));
                MyLogger.log(Level.INFO, "Connection accepted");
                MyLogger.log(Level.INFO, "Start the thread.");
                System.out.println("Connection accepted");
                System.out.println("Start the thread.");
                clients.get(clients.size()-1).start();
               
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                server.close();
            } catch (IOException e) { }
        }
	}

	public static void main(String[] args) {
		new Server();
	}

}
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.NoSuchElementException;
import java.util.Scanner;
import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Hank Lee
 * Shared in InformisTry -- https://jumperc2p.github.io/InformisTry/
 *
 */
public class ClientThreadHandler extends Thread {
	
	private Scanner inputFromClient;
    private PrintWriter outputToClient;
    private static Logger MyLogger = MyLoggerWithFileOutput.getLogger();
	
	public ClientThreadHandler(Socket connection) {
		
		// get the OutputStream and InputStream from connection
        try {
			outputToClient = new PrintWriter(connection.getOutputStream(),true);
			inputFromClient = new Scanner(connection.getInputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public void run() {
		
		  try {
          	
          	while (true) {
          		// send messages to client.
          		outputToClient.println("Send messages to server. Or if you want to end the connection, please enter \"q\":");
          		
          		// create new Timer to schedule TimerTask and start its schedule.
          		Timer timer = new Timer("ServerTaskTimer");
          		// use delay to let the timer start after 3 seconds.
          		long delay = 3000;
          		long period = 3000;
          		timer.scheduleAtFixedRate(new ServerTask(outputToClient), delay, period);
          		// take input from client
          		String clientMessage = inputFromClient.nextLine();
          		// Once it receive the message from client, cancel the timer.
          		timer.cancel();
          		System.out.println("Client says: " + clientMessage);
          		MyLogger.log(Level.INFO, ("Client says: " + clientMessage));
          		// check if the client wants to end the connection.
          		if ("q".equals(clientMessage)) {
          			MyLogger.log(Level.INFO, "Client ends the connection.");
          			break;
          		}
          	}
          }catch (NoSuchElementException ne) {
        	  MyLogger.log(Level.INFO, "Client quits the game.");
          }
	}
}

After running the multi-thread socket program, the log file is generated at the root path.

May 05, 2020 12:22:29 AM logging_example_multithread.Server <init>
INFO: Starts the server
May 05, 2020 12:22:29 AM logging_example_multithread.Server <init>
INFO: Waiting for new connections...
May 05, 2020 12:22:48 AM logging_example_multithread.Server <init>
INFO: Connection accepted
May 05, 2020 12:22:48 AM logging_example_multithread.Server <init>
INFO: Start the thread.
May 05, 2020 12:22:48 AM logging_example_multithread.Server <init>
INFO: Waiting for new connections...
May 05, 2020 12:23:03 AM logging_example_multithread.Server <init>
INFO: Connection accepted
May 05, 2020 12:23:03 AM logging_example_multithread.Server <init>
INFO: Start the thread.
May 05, 2020 12:23:03 AM logging_example_multithread.Server <init>
INFO: Waiting for new connections...
May 05, 2020 12:23:19 AM logging_example_multithread.ClientThreadHandler run
INFO: Client says: Hi, I'm here.
May 05, 2020 12:23:23 AM logging_example_multithread.ClientThreadHandler run
INFO: Client says: Hello
May 05, 2020 12:23:25 AM logging_example_multithread.ClientThreadHandler run
INFO: Client quits the game.
May 05, 2020 12:23:26 AM logging_example_multithread.ClientThreadHandler run
INFO: Client says: q
May 05, 2020 12:23:26 AM logging_example_multithread.ClientThreadHandler run
INFO: Client ends the connection.

java.util.logging.Logger is much more complex than I mentioned here. In the article, I just point out a simple way to use java.util.logging.Logger to achieve the logging process. If you want to learn more knowledge about java.util.logging.Logger, please take a look at Java 8 API - Logger. Hope the article can help you figure out how to fix the problem you face in.

Sample Code

The sample code can be downloaded here:

  • Simple example is in the package of logging_example.
  • Extra example is in the package of logging_example_multithread.

If you would like to use the code provided here, please indicate the source.

References

  1. Java 8 API - Logger
  2. Java 8 API - Level
  3. Java 8 API - FileHandler
  4. Java 8 API - SimpleFormatter
  5. Java Logging API - Tutorial