Configuring log4j logging in a web application

Objective:
To configure logging in a web application running in Tomcat using log4j.

Explanation:
Requirement is to create two log files, one for logging logs from the entire application and other from logging the log from a specific file. So the following example covers how to separate log of a specific class or package.

Prerequisite:
– Tomcat 6 up and running.
– A well structured web application.
(I have used eclipse for that and created a dynamic wed application.)
– Create an XML file under WEB-INF\classes folder named, log4j.xml.
– Grab the log4j jar (log4j-1.2.13.jar in my case) and place that in WEB-INF\lib

LET US START:

1. Copy paste the following in the log4j.xml and google to understand that well.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">


<appender name="FIRST">
<param name="File" value="${catalina.home}/logs/techmusings1.log" />
<param name="Append" value="true" />
<layout>
<param name="ConversionPattern" value="%d{dd MMM yyy HH:mm:ss}, %-6p %C:%M:%L %m %n" />
</layout>
</appender>


<appender name="SECOND">
<param name="File" value="${catalina.home}/logs/techmusings2.log" />
<param name="Append" value="true" />
<layout>
<param name="ConversionPattern" value="%d{dd MMM yyy HH:mm:ss}, %-10p %m %n" />
</layout>
</appender>
<!-- Configure the root appender -->
<root>
<appender-ref ref="FIRST"/>
</root>
<!-- Configure the category and log level for A -->
<category name="com.samples.technicalmusings">
<priority value="DEBUG" />
<appender-ref ref="FIRST" />
</category>
<!-- Configure the category and log level for B -->
<category name="com.samples.technicalmusings.logging.B">
<priority value="INFO" />
<appender-ref ref="SECOND" />
</category>
</log4j:configuration>

*You can also use log4j.properties as an alternative but the XML approach is more flexible.

2. Create following classes to put loggers in them:

public class A {
private static final Logger logger = Logger.getLogger(A.class);
public void log(){
logger.info("class A is logging info message.");
if(logger.isDebugEnabled()){
logger.debug("class A is logging debug message.");
}
}
}

public class B {
private static final Logger logger = Logger.getLogger(B.class);
public void log(){
logger.info("class B is logging info message.");
if(logger.isDebugEnabled()){
logger.debug("class B is logging debug message.");
}
}
}

3. Create a listener to call the above classes to fulfill their purpose when the server is initialized.

public class LoggingListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent arg0) {
// TODO Auto-generated method stub
}
public void contextInitialized(ServletContextEvent arg0) {
A a = new A(); a.log();
B b = new B(); b.log();
}
}

4. Configure the listener in web.xml by adding the following

<listener>
<listener-class>com.samples.technicalmusings.logging.LoggingListener</listener-class>
</listener>

5. Deploy the application in tomcat and start tomcat.

6. In $TOMCAT_HOME/logs directory you will find techmusings1.log and techmusings2.log

Output:

techmusings1.log

26 Sep 09 15:12:37, INFO   com.samples.technicalmusings.logging.A:log:10 class A is logging info message.
26 Sep 09 15:12:37, INFO   com.samples.technicalmusings.logging.A:log:10 class A is logging info message.
26 Sep 09 15:12:37, DEBUG  com.samples.technicalmusings.logging.A:log:12 class A is logging debug message.
26 Sep 09 15:12:37, DEBUG  com.samples.technicalmusings.logging.A:log:12 class A is logging debug message.
26 Sep 09 15:12:37, INFO   com.samples.technicalmusings.logging.B:log:10 class B is logging info message.
26 Sep 09 15:12:37, INFO   com.samples.technicalmusings.logging.B:log:10 class B is logging info message.

techmusings2.log

26 Sep 09 15:12:37, INFO       class B is logging info message.

Here you will see that in techmusings2.log only messages corresponding to class B have been printed. Also note that the debug level log is absent in techmusings2.log file. Find the reason for this in log4j.xml OR set the debug=”true” in log4j:configuration element in log4j.xml and monitor the logs of tomcat to know more.

You can download the above code from the following location:

http://technicalmusings.googlecode.com/svn/trunk/java/examples/logme

Enjoy Learning,

Kamlesh

Advertisements

Finding information about a JAR file

No no! I am not going to tell you what a jar file is and neither I am going to tell you how to make a jar file and use it properly. Actually there is a very small piece of information every jar carries with itself which I want to share with you all. I assume most of you might be knowing this already but I was not knowing this unless I discovered it myself in one of my mission critical moments in work. Actually there were same jar files compiled on different versions of java and I needed to differentiate between them. And for some time I just kept thinking about amazing ways to do that, never mind :).  So coming to the point, if you want to know about similar information about a jar file viz. compiler version, product version et cetera you can peep into *.jar/META-INF/MANIFEST.MF file. META-INF is a special sub directory of the jar file.

The manifest file contains the information about the jar file and it’s contents in form of name value pair. The contents of the manifest are group into sections and the first section is called the main section. The entries in the main section are global to the jar file. Different sections in the manifest are separated by blank lines. Some of the attributes you may often see are Manifest-Version, Created-By, Implementation-Vendor, Implementation-URL et cetera.

To add/edit an update entries into the manifest file in a jar the cfm and ufm options of jar command can be used respectively.

For more information on jar and manifest visit http://java.sun.com/javase/6/docs/technotes/guides/jar

Cheers,
Kamlesh

Scala: A New Programming Language

While surfing different Java Forums I today came across, Scala. My first impression was what is it, yet another programming language! But when I read about it in some blogs and visited its site I really could not stop welcoming Scala on my blog space.

Let’s see what Scala says about itself:

Scala is a general purpose programming language designed to express common programming patterns in a concise, elegant, and type-safe way. It smoothly integrates features of object-oriented and functional languages, enabling Java and other programmers to be more productive. Code sizes are typically reduced by a factor of two to three when compared to an equivalent Java application.

Many existing companies who depend on Java for business critical applications are turning to Scala to boost their development productivity, applications scalability and overall reliability.

Some of the key features of Scala are:

  • It offers seamless integration with Java. Scala program runs on JVM as they get converted into bytecode (.class files) after compilation. Java and Scala are interoperable and hence can be easily integrated.
  • IDEs like Eclipse, NetBeans and Intellij support Scala.
  • Scala also supports .NET Framework.

Some of the companies who have chosen Scala are Twitter, Reaktor, Siemens.

Hope to post my first experience with Scala soon,

Kamlesh