Log4J

Logging in Java

Why we need logging in Java

This is pretty basic java logging question and everybody argue that if we JavaSystem.out.println() for printing messages then whey we use logging. Everybody who starts java starts with System.out.println() for printing message in java console. But this is not at all powerful as compared to advanced Java logging API like log4j and java.util.logging. If you are writing a java application server then only way to know what your server is doing is by seeing log file of your server. suppose you don’t write anything in your java log file then nobody knows what your sever is doing, it becomes increasingly important if your application is connected to upstream and downstream like in many stock trading systems or electronic trading system and get input from upstream , transforms and normalize it and send down to downstream. In case of any issue without java logs you won’t be able to figure out what went wrong. That’s why logging in java is most important while writing any Java server application. Logging in Java is not by choice it’s must to understand.

What are different logging level in Java

 

Anybody who is using logging in java must be familiar with basic java logging level e.g. DEBUG, INFO, WARN and ERROR.

DEBUG is the lowest restricted java logging level and we should write everything we need to debug an application, this java logging mode should only be used on Development and Testing environment and must not be used in production environment.

INFO is more restricted than DEBUG java logging level and we should log messages which are informative purpose like Server has been started, Incoming messages, outgoing messages etc in INFO level logging in Java.

WARN is more restricted than INFO java logging level and used to log warning sort of messages e.g. Connection lost between client and server. Database connection lost, Socket reaching to its limit. These messages and java logging level are almost important becauseyou can setup alert on these logging messages in Java and let your support team monitor health of your java application and react on this warning messages. In Summary WARN level is used to log warning message for logging in Java.

ERROR is the more restricted java logging level than WARN and used to log Errors and Exception, you can also setup alert on this java logging level and alert monitoring team to react on this messages. ERROR is serious for logging in Java and you should always print it.

FATAL java logging level designates very severe error events that will presumably lead the application to abort. After this mostly your application crashes and stopped.

OFF java logging level has the highest possible rank and is intended to turn off logging in Java.

These java logging levels are based on log4j logging level and little bit different than java.util.logging API which provides some more logging level like SEVERE, FINER, FINEST, FATAL etc. as name suggest based upon criticality of your logging message you can choose any of this level for logging in Java.

How logging in Java affects performance

Java logging severely affects performance of your application. Its quite common sense that more you log, more you perform file IO which slows down your application. That’s why choosing correct java logging level for every single message is quite important. Since having no java logging is not a choice you have to have logging in java application, what you can control is logging level and logging messages on that level. So always log DEBUG messages inside isDebugEnabled() block as shown in below example of debug mode in java.
if(logger.isDebugEnabled()){   logger.debug(“java logging level is DEBUG Enabled”);}

                Uses either WARN ERROR or FINER, FINEST java logging level in production environment. Never use DEBUG level logging in java in production, I have seen sometime production running very slow and found that some one has put the java log on DEBUG mode.

10 tips on logging in Java

1) Use isDebugEnabled() for putting debug log in Java , it will save lot of string concatenation activity if your code run in production environment with production logging level instead of DEBUG logging level.

2) Carefully choose which kind of message should go to which level for logging in Java, It become extremely important if you are writing server application in core java and only way to see what happening is Java logs. If you log too much information your performance will be affected and same time if you don’t log important information like incoming messages and outgoing messages in java logs then it would become extremely difficult to identify what happened in case of any issue or error because nothing would be in java logs.

3) Use either log4j or java.util.logging for logging in Java, I would recommend log4j because I have used it a lot and found it very flexible. It allows changing logging level in java without restarting your application which is very important in production or controlled environment. To do this you can have log4j watchdog which continuously look for log4j.xml in a particular directory and if founds loads it and reset logging in java.

4) By using log4j.xml you can have different logger configuration for different Java classes as well. You can have some classes in INFO mode, some in WARN mode or ERROR mode. It’s quite flexible to do this to customize java logging.

5) Another important point to remember is format of java logging, this you specify in logger. Properties file in case of java.util.logging API for logging to use which java logging Formatter. Don’t forget to include Thread Name and fully qualified java class Name while printing logs because it would be impossible to find sequence of events if your code is executed by multiple threads without having thread name on it. In my opinion this is the most important tips you consider for logging in Java.

6) By carefully choosing format of  java logging at logger level and format of writing log you can have generate reports from your java log files. Be consistent while logging messages, be informative while logging message, print data with message wherever required.

7) While writing message for logging in Java try to use some kind of prefix to indicate which part of your code is printing log e.g. client side , Database site or session side, later you can use this prefix to do a “grep” or “find” in Unix and have related logs at once place. Believe me I have used this technique and it helped a lot while debugging or investigating any issues and your log file is quite large. For example you can put all Database level log with a prefix “DB_LOG:” and put all session level log with prefix “SESSION_LOG:”

8) If a given logger is not assigned a level, then it inherits one from its closest ancestor. That’s why we always assign log level to root logger in configuration file log4j.rootLogger=DEBUG.

9) Both no logging and excessive logging is bad so carefully planned what to log and on which level you log that messages so that you can run fast in production environment and at same time able to identify any issue in QA and TEST environment.

10) I found that for improving logging its important you look through your log and monitor your log by yourself and tune it wherever necessary. It’s also important to log in simple English and it should make sense and human readable since support team may wan to put alert on some logging message and they may want to monitory your application in production.

11) if you are using SLFJ for logging in java use parametrized version of various log methods they are faster as compared to normal method.

logger.debug(“No of Orders ” + noOfOrder + ” for client : ” + client); // slower 

logger.debug(“No of Executions {} for clients:{}”, noOfOrder , client); // faster
These tips and examples on logging in java is based on my experience and how I use logging in Java and by no means complete, I would love to hear some more tips from you guys and how you guys are using and customizing java logging. I would recommend reading detailed and official documentation for both java.util.logging and log4j to get complete and detailed information on java logging as well.

Why prefer Log4j over System.out.println

Many Java programmers have their own reason for using a logging framework like Log4j,java.util.Logger, SL4j or even Apache Commons logging, but they all are better than using the System.out.println().  Though my advice is to prefer SLF4j over Log4j for logging in Java as discussed in that article.

Anyway, here are some of the reasons, which I think are enough to stop you usingSystem.out.println() statements in production code:

1) Any logging framework including Log4j, SL4J, logback, and java.util.logger allows you to log debugging information with a log level, later you can use that level as filtering criteria, i.e. you can disable message belongs to one particular log level e.g. you would be more concerned to see WARN messages than DEBUG messages in production.

2) The second point, which is related to the previous one is that logging framework allows you to suppress message from another log level, for example, you can run your application in DEBUG mode in the test environment, but on ERROR mode in a production environment. This will not only generates fewer logs but also improves the performance of your application because of less logging, see 10 tips on logging in Java to learn more about this.

This is not possible with System.out.println() statements which can not be controlled by any configuration or dynamically at runtime using JMX or any watchdog facility.

On the other hand, you can change the log level for log4j based logger without restarting your application by using a watchdog thread, which monitors a location for updatedlog4j.xml, the configuration file for Apache Log4j. The java.util.Logger also allows you to change logging level using JMX without restarting the server.

3) By using a Logging framework, you can produce better outputs and metadata, which will help during troubleshooting and debug. Most logging framework e.g. Log4j allows you to print formatted output by specifying a formatting pattern by using PatterLayout, which can include a timestamp, name of the class, the Thread which is executing code etc.

All of this information can be really useful while debugging concurrent applications where the output from multiple threads is overlapping. You don’t get this facilities when you use the System.out.println() statements for logging messages. What more, eve Joshua Bloch has also suggested using a properly logging facility e.g. java.util.Logger for logging in his classic book Effective Java, one of the must-read books for experienced Java programmers.
Using System.out or System.err rather than a dedicated logging facility makes it difficult to monitor the behavior of the program.

While most programmers go on to learn many nuances and subtleties about Java, a surprising number hang on to this first lesson and never give up on writing messages to standard output using System.out.println() statement. Well, this is Ok if you are writing small test programs but it certainly not right if you coding on a production system live with millions of users or trades.