Log4j guidelines for logger priority use

I have used log4j before but to be honest, I normally only use the error logger level for error conditions and info for all other statements. I was curious how others used the 5 different priority levels.

Debug
Info
Warn
Error
Fatal

Are there standards you use for when to use which level?

Any feedback is appreciated since I am curious how others use log4j.

I typically only use debug, warn and error, once in a while I’ll use info, I don’t think I’ve ever used fatal. I use debug everywhere as a tracing mechanism during dev time.

Serious errors, mostly exceptions will be at error level, any error that I can recover from I’ll usually stick a warn level message.

Standard? Depends on the environment. For us, we use DEBUG for development and use INFO for production.

I have a mix feeling for log4j even though I use them but I can’t get away from System.out.println. The only reason is that you end up with many DEBUG messages that you do not care to see. For example, looping over 100 objects to display name and your output gets lost somewhere in the middle. So, time to time I turn off log4j and use system print. What do you guys do?

There are actually 6 levels of debugging with log4j now:

Trace
Debug
Info
Warn
Error
Fatal

We use Trace for following the flow of the application between methods and classes.

Debug is used for printing out state information about different classes. The attributes of an Email that is send.

Info is used when something interesting occurs in the application. Email is Send, Database connection created, contacted another external service, etc…

Warn, haven’t used much.

Error, for when errors and exceptions occur that can be recovered from.

Fatal, for when errors and exceptions occur that CAN NOT be recovered from.

Log4j javadocs have a good explanation of when to use each level:
org.apache.log4j.Level

We also use if statements around all our trace, debug, and info statements to check if we’re actually logging those values. If not, we do not produce the String that goes into the log method. In some case it is possible to create some pretty large strings that it would just be best not to produce if we don’t have too.


...
if(logger.isEnabledFor(Level.DEBUG)) {
  // the toString() method of the Person class in this instance will print
  // out all its attributes and if that attribute is an Object its toString()
  // method will be called, etc...  So this string can be quite expensive
  // to create.
  logger.debug("Person: " + person);
}
...

There is actually an interesting article about this subject on Coding Horror…

http://www.codinghorror.com/blog/archives/001192.html

My approach is to use:

debug - just that, for debugging code, if a particular debug statement seems useful, it gets left in, otherwise I clean up after solving the problem. Loggers with debug level configs never go into production.

info - rarely used, for important events eg: such and such successfully started/initialized

error - for ‘bad’ things, whenever an exception is thrown (I never write exception reliant code, so these should not be occurring and need to be addressed)


try {
  for( int i = 0; ; ++i ) {
    doing something with array[i]
  }
} catch( IndexOutOfBoundsException e ) {
  //do nothing
}

is an example of exception reliant code (that I have actually seen in use, lame!)

Less is more (useful).

Coding Horror posted another nice blog entry about logging:

http://www.codemonkeyism.com/archives/2008/12/16/7-good-rules-to-log-exceptions/

While working w/ 5+ developers aren’t you guys afraid to turn DEBUG on? before it even gets to my part, it prints zillion logs before it gets to my part. Only way is to do a global search with specific characters like “sg707:here i am”, which got quite annoying. So, what I do is turn off log4j, do everything through system print, then when I’m done, I replace each sys print w/ appropriate level like debug/info/warn/error. Maybe it’s just me who works like this.

Not at all.

I do two things differently:

  • In the logs print out the class that is being logged and its package.
  • In the log4j properties file or xml file you can define which package you want to log.

Those should help you out a bit.

Yes and No. Yes I can configure to that single class but those got debug from other devs too… I always see a huge loop of logs to print out a name or something out of a list over and over again… then my stuff gets sandwidched in the middle… I’m guessing there’s no way around this then my own solution. Still, it does help but nothing beats turning off log4j and use sys print…lol

You can configure by package which is a lot better than doing it by single classes. Just set the root logger to ERROR and the package with classes you’re working on to DEBUG. That’s what I do.

Sorry so late in responding… there is some good information here. As for using System.out.println… I really do not see a need. If your logs are really getting that flooded… trying separating your logging into different logging files. There has to be logic breaking points in your application so set up log files for each portion. This way, the logging can still be somewhat useful.

I also found a good explanation of the logging levels at this link.

http://www.scribd.com/doc/7679064/Log4j-Tutorial