First, we need to create a Formatter to tell Java how to output the log entries. In this example, we will create a simple class LogFormatter and tell it that we want it formatted with the date, time, level (importance of message), and then the message.
public class LoggerTest {
private static class LogFormatter extends Formatter {
private DateFormat dateFormat =
new SimpleDateFormat("MM/dd/yyyy HH:mm");
new SimpleDateFormat("MM/dd/yyyy HH:mm");
public String format(LogRecord record) {
StringBuffer sb = new StringBuffer();
//Get date from record
//and append to StringBuffer
//and append to StringBuffer
Date date = new Date(record.getMillis());
sb.append(dateFormat.format(date));
sb.append(" ");
// Get level and append to StringBuffer
sb.append(record.getLevel().getName());
sb.append(": ");
// format message and append to StringBuffer,
// then add new line
// then add new line
sb.append(formatMessage(record));
sb.append("\n");
return sb.toString();
}
}
}
The StringBuffer will hold the String that we will build and return in the format method. First, the date is retrieved from the record and formatted by our SimpleDateFormat. Next, the level name is retrieved and appended onto the String. Finally, the message is formatted by the default Formatter guidelines, and appended onto the string. The String is then returned.
Now that we have a Formatter to format each of our entries, it's time to create our Logger. We will create a Logger data field and initialize it in the constructor for the LoggerTest class. This is demonstrated below. The code is to be included in the LoggerTest class:
private Logger captainsLog = null;
public LoggerTest() {
try {
//create file
FileHandler textLog =
new FileHandler("Captain's-Log.txt");
new FileHandler("Captain's-Log.txt");
//set formatter
textLog.setFormatter(new LogFormatter());
//set levels which will be recorded in log
textLog.setLevel(Level.ALL);
//get logger
captainsLog = Logger.getLogger("Captain's Log");
//attach FileHandler
captainsLog.addHandler(textLog);
//set Logger level
captainsLog.setLevel(Level.ALL);
} catch (SecurityException | IOException e) {
// TODO Auto-generated catch block
System.out.println("Log creation failed!");
e.printStackTrace();
}
//log an info level message
captainsLog.info("Initializing Captain's Log");
//log a FINE level message
captainsLog.log(Level.FINE, "First entry successful!");
}
The constructor creates the file we will be writing to and then tells it to use the Formatter we created above. The setLevel call tells the file what importance level to record. The Level.ALL says that we want to record all messages in this file. If the FileHandler receives a message which is below the FileHandler's level, it will ignore the message.
Next, we create the Logger. the Logger.getLogger() method creates a new Logger with the given name. If a Logger already exists with the given name, it returns the already created Logger. Once we have the Logger, we add our handler to it so that it knows where to write to. Next, we set what level of messages will be reported by this Logger. The Logger may have multiple Handlers and will send its messages to all of them simultaneously. This is a way to filter what messages you want sent to any of the Handlers. This could be useful if you wanted multiple Handlers for different levels. You could have the Logger send all messages, and then the individual Handlers could filter which they want to record.
Next, we create the Logger. the Logger.getLogger() method creates a new Logger with the given name. If a Logger already exists with the given name, it returns the already created Logger. Once we have the Logger, we add our handler to it so that it knows where to write to. Next, we set what level of messages will be reported by this Logger. The Logger may have multiple Handlers and will send its messages to all of them simultaneously. This is a way to filter what messages you want sent to any of the Handlers. This could be useful if you wanted multiple Handlers for different levels. You could have the Logger send all messages, and then the individual Handlers could filter which they want to record.
The final two lines log initial statements saying that the log has been initialized.
There are two quick steps left. The first is to create a main method in our LoggerTest class so that we can run it, and then to add a few methods to demonstrate using the Logger in separate methods.
First, we will create the main method. The main method is the method which will be run whenever you select to run the Java application. Our main method is as follows:
public static void main(String[] args) {
LoggerTest myTester = new LoggerTest();
}
This is currently very simple. Right now it just creates an object of type LoggerTest; but since the constructor initializes the Logger and creates the log file, this is enough to ensure that everything is working correctly so far. Now when you run this file, a "Captain's Log.txt" file should appear in the same directory, and should contain the text:
01/13/2014 18:16 INFO: Initializing Captain's Log
01/13/2014 18:16 FINE: First entry successful!
Now that we see our log file is working successfully, the final step is to update the log in several different methods so that we can ensure that our log works across the whole file. After all, a log which only works in the constructor isn't much help!
Now that we see our log file is working successfully, the final step is to update the log in several different methods so that we can ensure that our log works across the whole file. After all, a log which only works in the constructor isn't much help!
We will create two quick methods: foo and bar. They will be in the LoggerTest class as follows:
public void bar() {
captainsLog.log(Level.FINE, "In bar method!");
captainsLog.info("Exiting bar...");
}
public void foo() {
captainsLog.log(Level.FINE, "In foo method!");
captainsLog.info("Exiting foo...");
}
Next, we will add a call to these methods in the main method. Add these lines in after the creation of myTester in the main method:
myTester.foo();
myTester.bar();
Now when you save and run the file, you will see the "Captain's Log.txt" file in the same directory, and its contents will be:
01/13/2014 18:30 INFO: Initializing Captain's Log
01/13/2014 18:30 FINE: First entry successful!
01/13/2014 18:30 FINE: In foo method!
01/13/2014 18:30 INFO: Exiting foo...
01/13/2014 18:30 FINE: In bar method!
01/13/2014 18:30 INFO: Exiting bar...
There you have it! Creating simple text log files in Java. Feel free to email me for the full source code.
-Dan
No comments:
Post a Comment