Share this page 

Log information efficiently (with Log4J)Tag(s): Environment


In production code, a good practice is to only log what is necessary in the context.

With Log4J, you can have different levels of message written into your log.

public class MyClass {
   
 /**
 * Logger log4j
 */
 static Logger logger = Logger.getLogger(MyClass.class.getName());

...
logger.debug("I'm here");
logger.info(e.getMessage());
logger.warning("something wrong " + e.getMessage());
logger.error("omg " + e.getMessage());
...

While you can set the level in your code with something like

logger.setLevel(Level.WARN);
it's more flexible to do it from the Log4J properties file
; can be OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL
log4j.threshold=WARN
You put the properties file in the classpath and then from your code
URL url = ClassLoader.getSystemResource("log4j.props");
PropertyConfigurator.configure(url);

Logging activities have a cost. Even if you set the level at DEBUG level, the logger.debug(...) is interpreted. Consider this line :

logger.setLevel(Level.DEBUG);
logger.debug("something wrong with the value of " + myValue.toString());
the toString() method will be called and the result concatened to a String even if the DEBUG level is disabled.

The best practice is to check if the level is enabled or not.

logger.setLevel(Level.DEBUG);
if (logger.isDebugEnabled()) {
  logger.debug("something wrong with the value of " + myValue.toString());
}
This way you will not incur the cost of parameter construction if debugging is disabled for logger.

You can even remove the unwanted logging operation from the bytecode! See this HowTo.

Finally it's a good idea to design a robust toString() method for your class like this one :

public String toString(){
   StringBuffer sb = new StringBuffer();
   sb.append(getClass().getName())
   sb.append(" myValue=[").append(this.myValue).append("]");
   sb.append(" anotherValue=[").append(this.anotherProperty).append("]");
   return sb.toString();
}
even if myValue is null, this toString() method will display "null" as the value and not throw a NullPointerExeception.

See also this HowTo and this one