Logging is much useful for any software application and that helps to find out the execution of the project at multiple scenarios. In Java, java.util package is having the logging utility and the following imports are much necessary for logging.
import java.util.logging.ConsoleHandler; import java.util.logging.FileHandler; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.Logger;
Specification of log message display via properties file:
In a project, we can specify a properties file, and they keep track of maintaining logging functionality. Among that, “java.util.logging.ConsoleHandler.formatter” specifies the name of a Formatter class to use and the default setting is java.util.logging.SimpleFormatter, which is nothing but displaying log entries in the plain text.
Java
// Specification of SimpleFormatter in .properties file java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter // Following are the different set of formats // that are possible to give in the file We // need to specify the format in a single line // either like java.util.logging.SimpleFormatter.format = [ % 1 $tF % 1 $tT ][% 4 $ - 7s] % 5 $s % n // or java.util.logging.SimpleFormatter.format = "%1$tc %2$s%n%4$s: %5$s%6$s%n" |
Features of SimpleFormatter:
- Only via plain text messages, SimpleFormatter displays log messages
- From Java 7 onwards, SimpleFormatter can be configured using a system property.
- As it is a plain text display, anybody can understand it easily. Basic information is displayed.
- ConsoleHandler uses this formatter class and in console, it prints log messages.
Implementation:
Example 1: Sample mylogging.properties
Java
/* * Configuration: By default each ConsoleHandler * is initialized using the following LogManager * configuration properties. If properties are not * defined (or have invalid values) then the specified * default values are used. * #"java.util.logging.ConsoleHandler.formatter" * specifies the name of a Formatter class to use * and the default setting is java.util.logging.SimpleFormatter, * which is nothing but displaying log entries in the plain * text.java.util.logging.ConsoleHandler.formatter * = java.util.logging.SimpleFormatter * java.util.logging.SimpleFormatter.format * =[%1$tF %1$tT] [%4$-7s] %5$s %n * #java.util.logging.SimpleFormatter.format * ="%1$tc %2$s%n%4$s: %5$s%6$s%n" * #java.util.logging.ConsoleHandler.level * specifies the default level for the Handler * (defaults to Level.INFO). * #java.util.logging.ConsoleHandler.filter * specifies the name of a Filter class to use * (defaults to no Filter). * #java.util.logging.ConsoleHandler.encoding * the name of the character set encoding to use * (defaults to the default platform encoding). * #handlers= java.util.logging.ConsoleHandler * #.level= FINE * # default file output is in user's home directory. * #Below specified are the other set of information for logging */ java.util.logging.FileHandler.pattern = %h/java%u.log java.util.logging.FileHandler.limit = 50000 java.util.logging.FileHandler.count = 1 java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter java.util.logging.ConsoleHandler.level = INFO |
Example 2: Sample Java file that uses mylogging.properties which in turn displays the log messages in plain text
Java
// SimpleFormatter in Java Logging API import java.io.FileInputStream; 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.LogManager; import java.util.logging.Logger; public class SimpleFormatterLoggingExample { // create static logger object static Logger loggerInformation = Logger.getLogger( SimpleFormatterLoggingExample. class .getName()); public static void main(String[] args) { try { // In mylogging.properties, necessary // logging messages settings are given. // First it has to be read LogManager.getLogManager().readConfiguration( new FileInputStream( "mylogging.properties" )); } catch (SecurityException | IOException e1) { System.out.println( "SecurityException message ,, " + e1.getMessage()); } // There are different levels of setting // loggerInformation default level is INFO if the // value is not specified, for our example we have // kept as INFO other available levels are ALL - // 1,FINEST - 2,FINER - 3,FINE - 4,CONFIG - 5,INFO - // 6,WARNING - 7,SEVERE - 8,OFF - 9 loggerInformation.setLevel(Level.FINE); loggerInformation.addHandler( new ConsoleHandler()); // adding custom handler loggerInformation.addHandler( new MyHandler()); try { // FileHandler file name with max size and // number of log files limit Handler fileHandler = new FileHandler( "logger.log" , 2000 , 3 ); fileHandler.setFormatter( new MyFormatter()); // setting custom filter for FileHandler fileHandler.setFilter( new MyFilter()); loggerInformation.addHandler(fileHandler); for ( int i = 0 ; i < 5 ; i++) { // logging messages loggerInformation.log( Level.INFO, "Printing logger information " + i); } loggerInformation.log(Level.CONFIG, "Config data is set" ); } catch (SecurityException | IOException e) { System.out.println( "SecurityException message ,, " + e.getMessage()); } } } |
As java.util.logging.SimpleFormatter.format=[%1$tF %1$tT] [%4$-7s] %5$s %n is set in “mylogging.properties” file,
Output:
At the same time, java.util.logging.SimpleFormatter.format=”%1$tc %2$s%n%4$s: %5$s%6$s%n”
Output can be:
Other example formats :
1. java.util.logging.SimpleFormatter.format=”%4$s: %5$s [%1$tc]%n”. Displays a line with the log level (4$), the log message (5$) and the timestamp (1$) in a square bracket.
Example:
WARNING: A general warning message in terms of security [Thu Jan 28 13:11:31 IST 2021]
2. java.util.logging.SimpleFormatter.format=”%1$tc %2$s%n%4$s: %5$s%6$s%n”. Displays 2 lines and in that first line includes the timestamp (1$) and the source (2$), whereas the second line includes the log level (4$) and the log message (5$) followed with the throwable and its backtrace (6$), in case if they are present.
Example:
Thu Jan 28 13:11:31 IST 2021 <your class name> fatal SEVERE: Exception raised and hence several messages are thrown with an exception java.lang.IllegalArgumentException: invalid argument
3. java.util.logging.SimpleFormatter.format=”%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n%4$s: %5$s%n”. Displays 2 lines similar to the example as seen above but different date/time formatting is displayed. One important difference is it does not display the throwable and its backtrace.
Example:
Thu Jan 28 13:11:31 IST 2021 <your class name> fatal SEVERE: Exception raised and hence several messages are thrown with an exception
By overriding in a subclass. The method can be overridden. Via Formatter.formatMessage(java.util.logging.LogRecord), one can localize and format the message field.
Using system property also, we can do the formatting
Java
// SimpleFormatter in Java Logging API import java.util.logging.Logger; public class SimpleFormatterUsingSystemProperty { // Create static logger object with Null private static Logger LOGGER = null ; // Static block static { System.setProperty( "java.util.logging.SimpleFormatter.format" , "[%1$tF %1$tT] [%4$-7s] %5$s %n" ); // Logger to get logs LOGGER = Logger.getLogger( SimpleFormatterUsingSystemProperty . class .getName()); } // Driver code public static void main(String[] args) { // Log information LOGGER.info( "Inside main method of SimpleFormatterUsingSystemProperty" ); // Log warning LOGGER.warning( "a general warning message for the security" ); } } |
Output :
Programmatic way of setting format:
Java
// SimpleFormatter in Java Logging API import java.util.Date; import java.util.logging.ConsoleHandler; import java.util.logging.LogRecord; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; public class SimpleFormatterUsingProgramaticway { // create static logger object with null value private static Logger LOGGERINFORMATION = null ; // static block static { Logger mainLogger = Logger.getLogger( "com.journaldev" ); mainLogger.setUseParentHandlers( false ); ConsoleHandler handler = new ConsoleHandler(); // setting the required format to // the ConsoleHandler object handler.setFormatter( new SimpleFormatter() { private static final String format = "[%1$tF %1$tT] [%2$-7s] %3$s %n" ; // Override format method @Override public synchronized String format( LogRecord logRecord) { return String.format( format, new Date(logRecord.getMillis()), logRecord.getLevel().getLocalizedName(), logRecord.getMessage()); } }); // addHandler method with handler // passed as parameter mainLogger.addHandler(handler); LOGGERINFORMATION = Logger.getLogger( SimpleFormatterUsingProgramaticway . class .getName()); } public static void main(String[] args) { // log information LOGGERINFORMATION.info( "in SimpleFormatterUsingProgramaticway" ); // Log warnings LOGGERINFORMATION.warning( "a general warning" ); } } |
Output :
Conclusion:
SimpleFormatter is an easier way to understand log messages in human-readable ways with a timestamp, level of log messages like INFO, WARNING, etc., and the log messages. Exception-raised messages also displayed which is easier to track the entire flow of the project. Another format namely XMLFormatter is also available, but it displays the messages in the XML way. So, SimpleFormatter is much useful even to novice users and for common users too.