When I work on personal Java projects, I like to have a way of nicely logging text to console. I generally make some public static class for this to handle prefixing and applying a timestamp to the message so I can omit the usage of System.out.println(“Text”); .
This is a class I wrote a while ago and I tend to reuse it on different projects because I really like the way it formats the text:
import java.text.SimpleDateFormat;
import java.util.Date;
public class Log {
public static final int LEVEL_INFO = 0;
public static final int LEVEL_WARNING = 1;
public static final int LEVEL_ERROR = 2;
private static SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
/**
* Used instead of System.out.println for consistent formatting.
*
* @param messageToPrefix Message that you want to send to print.
* @param errorLevel Type of message you want to send.
*/
public static void print(String messageToPrefix, int errorLevel) {
StringBuilder message = new StringBuilder();
message.append("[").append(df.format(new Date())).append("] ");
switch(errorLevel) {
case LEVEL_INFO:
message.append("[Info] ");
break;
case LEVEL_WARNING:
message.append("[Warning] ");
break;
case LEVEL_ERROR:
message.append("[Error] ");
break;
}
message.append(messageToPrefix);
System.out.println(message.toString());
}
}
This is all works as expected but there is a small problem I noticed a while ago: this way of creating a timestamp is very resource intensive! Calling this requires the code I want to log to halt until the timestamp has been made and written to console. This just seems inefficient to me (even tho we are talking about several milliseconds here). I came to this conclusion when I compared the runtime of this logging method to one that used System.currentTimeMillis() which does not format it to a nice timestamp but shows the runtime in ms if used like this:
public class Log {
private static final long startTime = System.currentTimeMillis();
public static final int LOG_LEVEL_INFO = 0;
public static final int LOG_LEVEL_WARNING = 1;
public static final int LOG_LEVEL_ERROR = 2;
public static final int LOG_LEVEL_UNKNOWN = 3;
/**
* Used instead of System.out.println for consistent formatting.
*
* @param msg Message that you want to send to log.
* @param importance How important is the message?
*/
public static void print(String msg, int importance) {
StringBuilder finalMsg = new StringBuilder();
finalMsg.append("[").append(System.currentTimeMillis() - startTime).append(" ms] ");
switch (importance) {
case 0:
finalMsg.append("[INFO] ");
break;
case 1:
finalMsg.append("[WARNING] ");
break;
case 2:
finalMsg.append("[ERROR] ");
break;
default:
finalMsg.append("[UNKNOWN] ");
break;
}
finalMsg.append(msg);
System.out.println(finalMsg);
}
}
This way proved to be way faster even on a small scale like 50 messages over approx. 50 seconds of running time.
This got me thinking about several questions: Is there a better way for creating timestamps like this? Is there a way to not wait for the logging code to complete? Would starting a thread for this be a good idea? Or am I on a completely wrong track altogether?
I would like to not use any extra libraries for this to keep it small and simple.
Any advice would be much appreciated!