Thursday, April 29, 2010

Power of Log4j

Recently, while working on a client project I came across following factual power of log4j:

1. Log4j has its own class loaders for loading its Appenders.

2. To avoid the log statements mix-in for scenarios when a servlet is serving more than one clients at the same time [NOTE: This would be especially tedious to trace and debug if any processing error occurred in servlet life cycle]; log4j provides an excellent way called as MDC or Mapped Diagnostic Context.

So, how do we make MDC to differentiate logging statements from multiple clients? Simple: Before starting any business process in your code, get the user name (for our Servlet, we can get it from request object) and put that into MDC. Now the user name will be available to the further processing. In your log4j.properties while defining the ‘conversionPattern’, add a pattern %X{key} to retrieve the values that are present in the MDC. The key will be ‘userName’ in our example. It's like getting a value from a Session object.

3. Each log statement throws-up an event called as LoggingEvent which is listened by the registered listeners and/or appenders.

4. NDC vs MDC - Which one should I use?
=> a. NDC has been part of the log4j framework longer than MDC.
b. NDC implements a "stack" onto which context information can be pushed and popped (ie "nested") while MDC implements a "map" into which key/value pair information can be stored.
c. NDC would work even with JDK1.1 but MDC requires JDK 1.2 or later. Under JDK 1.1 the MDC will always return empty values but otherwise will not affect or harm your application.
d. NDC use can lead to memory leaks if you do not periodically call the NDC.remove() method.
e. The MDC is managed on a per thread basis. A child thread automatically inherits a copy of the mapped diagnostic context of its parent.

... there are few more which I will add to this post shortly - So!! Keep Watching!!