Monday, August 06, 2012

Setting up Log4j

Setting up Log4j for Java Web Applications 

Content of log4j.properties file would be as follows:
# Define the root logger with appender file
log = /usr/home/log4j
log4j.rootLogger = DEBUG, FILE

# Define the file appender
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=${log}/log.out

# Define the layout for file appender
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.conversionPattern=%m%n

Using log4j in Java Program:

The following Java class is a very simple example that initializes, and then uses, the Log4J logging library for Java applications.
import org.apache.log4j.Logger;

import java.io.*;
import java.sql.SQLException;
import java.util.*;

public class log4jExample{
  /* Get actual class name to be printed on */
  static Logger log = Logger.getLogger(log4jExample
.class);

  public static void main(String[] args)
                throws IOException,SQLException{
   
     log.debug("Hello this is an debug message");
     log.info("Hello this is an info message");
  }
}

  Setting up Log4j for Java Web Applications 


There are different ways to setup log4j for you web application.


log4j.logger.<appname>logger=DEBUG, C, fileappender
log4j.additivity.<appname>logger=false
log4j.appender.C=org.apache.log4j.ConsoleAppender
log4j.appender.C.layout=org.apache.log4j.PatternLayout
#basic pattern
log4j.appender.C.layout.ConversionPattern=[%c] [%d{dd MMM yyyy - hh:mm:ss}] %5p - %m %n
#advanced pattern (slow)
#log4j.appender.C.layout.ConversionPattern=[%c] [%d{dd MMM yyyy - hh:mm:ss}] %5p - %m - in %M() at line %L of class %C %n

log4j.appender.fileappender=org.apache.log4j.RollingFileAppender
log4j.appender.fileappender.File=${appRootPath}WEB-INF/logs/<appname>.log
log4j.appender.fileappender.MaxFileSize=500KB

## Keep one backup file
log4j.appender.fileappender.MaxBackupIndex=3
log4j.appender.fileappender.layout=org.apache.log4j.PatternLayout
log4j.appender.fileappender.layout.ConversionPattern=%p %t %c - %m%n
#log4j.appender.C.layout.ConversionPattern=[%c] [%d{dd MMM yyyy - hh:mm:ss}] %5p - %m %n
Now use one of the methods below to add and enable Log4J in your web application

Method 1: Use Servlet to initialize log4j

Step 1: Put log4j.properties file in the right place

  • Place 'log4j.properties' into the root of your classpath. See an example web application layout hereTip: when web application is deployed it should be in /WEB-INF/classes/log4j.properties.
  • If using eclipse place 'log4j.properties' under your project_name/src directory

Step 2: Define the servlet mapping in web.xml

Add the following code to WEB-INF/web.xml
?
1
2
3
4
5
6
7
8
9
<servlet>
     <servlet-name>log4j-init</servlet-name>
     <servlet-class>com.FunkyWebapp.servlets.Log4jInit</servlet-class>
     <init-param>
       <param-name>log4j-init-file</param-name>
       <param-value>WEB-INF/classes/log4j.properties</param-value>
     </init-param>
     <load-on-startup>1</load-on-startup>
</servlet>
Make sure to change the java class file path to be relevant to your project. 'com.FunkyWebapp.servlets.Log4jInit'

Step 3: Add the servlet you mapped in Step 2 to your application

Add the following servlet to your project

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import javax.servlet.http.HttpServlet;
import org.apache.log4j.PropertyConfigurator;
 
public class Log4jInit extends HttpServlet {
 
 public void init()
 {
     String prefix =  getServletContext().getRealPath("/");
     String file = getInitParameter("log4j-init-file");
  
     // if the log4j-init-file context parameter is not set, then no point in trying
     if(file != null){
      PropertyConfigurator.configure(prefix+file);
      System.out.println("Log4J Logging started: " + prefix+file);
     }
     else{
      System.out.println("Log4J Is not configured for your Application: " + prefix + file);
     }    
 }
}
Make sure the <servlet-class> element in Step 2 matches the fully qualified name of your servlet. And make sure it's in the right package.

Step 4: Initialize the logger and start logging from other servlets in your web application

?
1
2
3
4
5
6
7
8
9
public class MyServlet extends HttpServlet {
...
private Logger log = Logger.getLogger("<appname>logger");
.
.
.
log.debug("Some string to print out");
 
}
Make sure the <appname> part matches with the line
log4j.logger.<appname>logger in the log4j.properties file
Notes:
When you initialize log4j in a servlet you will only be able to log from classes which are loaded after the servlet (eg. other servlets). You won't be able to do logging from a ServletContextListener for example.

Method 2: Initialize log4j in a ServletContextListener

Step 1: Put properties file in the right place

  • Place 'log4j.properties' into the root of your classpath. See an example web application layout hereTip: when web application is deployed it should be in /WEB-INF/classes/log4j.properties.
  • If using eclipse place 'log4j.properties' under your project_name/src directory

Step 2: Define a listener mapping in web.xml

Add the following servlet listener mapping in web.xml:
?
1
2
3
4
5
<listener>
  <listener-class>
   com.package.listeners.ApplicationServletContextListener
  </listener-class>
</listener>

Step 3: Add the SerlvetContextListener class to the application

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class ApplicationServletContextListener implements ServletContextListener
{
 public void contextInitialized(ServletContextEvent event)
 {
     ServletContext ctx = e.getServletContext();
    
  String prefix =  ctx.getRealPath("/");    
  String file = "WEB-INF"+System.getProperty("file.separator")+"classes"+System.getProperty("file.separator")+"log4j.properties";
           
     if(file != null) {
       PropertyConfigurator.configure(prefix+file);
       System.out.println("Log4J Logging started for application: " + prefix+file);
     }
     else
     {
      System.out.println("Log4J Is not configured for application Application: " + prefix+file);
     }
        
      
 }
 
 public void contextDestroyed(ServletContextEvent event)
 {
   
 }
 
}

Step 4: Define the logger and start logging from other servlets in your applications

?
1
2
3
4
5
6
7
8
9
public class MyServlet extends HttpServlet {
...
private Logger log = Logger.getLogger("<appname>logger");
.
.
.
log.debug("Some string to print out");
 
}
Notes:
  • Easier to implement that Method 1
  • All web application now has access to log4j (including listeners)
  • Placing log4j initialization in a ServletContextListener allows initialization of log4j when your web application is loaded for the first time.

1 comment:

ManjunathCBhat said...

Perfect Anup! This will surely help lot us who are looking for using Logger for their application.