Tuesday, 25 February 2014

Logging in Spring Framework using Log4j

LOG4J is most commonly used framework for logging in Java applications. LOG4J is a open source logging framework from apache software foundation. LOG4J can be used in any Java program to provide easy, fast and customizable logging.

While using LOG4J with spring a programmer can manage and control logging nature and flow from an external configuration file i.e. log.xml or log4j.properties. The external property file can be used to set the log format and the level of logging.

LOG4J Architecture


LOG4J with spring consists of a layered architecture, it has three main components :

1) Logger
2) Appender
3) Layout



1. Logger in Log4


Logger is the core of LOG4J framework, it is responsible to capture logging information on the basis of defined log levels.


Log levels in LOG4J

There are 6 normal log levels defined in LOG4J framework.

TRACE Level
This has been recently introduced in version 1.2 and adds more information to debug level logs.

DEBUG Level
You can use them a lot for debugging the application at development time. Each and every log message will come to log files once this level is set. It basically belongs to developers.

INFO Level
Important business process has finished and good news is “as expected”. In real time, system administrators will watch the info logs to ensure what’s happening on system right now, and if there is any problem in normal flow.

WARN Level
It suggest that the application might be continued, but you should take extra caution. The application can tolerate warning messages, but they should always be justified and examined so that they did not prove hidden crackers in application waiting to fire.

ERROR Level
It shouts at you that something had gone terribly wrong, and you must investigate immediately. It simply means that your application has met really undesired state. For example database unavailability or unexpected formatted input etc.

FATAL Level
You will not feel their presence very much in normal day, but once they appear, it signals very bad news, even the application death.

Other than these, there are two special levels as well

ALL : This level is used to turn on all levels of logging. Once this is configured and the levels are not considered at all. All appenders will start pouring the log events in log files.

OFF : It turns off all levels.

Important notes about levels using LOG4J in spring

A ) LOG4J level hierarchy and preferences
LOG4J logger levels have a preference order, whenever a logger code line is found the execution checks for logger property file to decide if the activity needs to be recorded in log or not. A logger will only output messages that are of a level greater than or equal to it and skipped all other entries those are lower than the logger.


 







B) What if a logger is not assigned a level
If a logger is not assigned a level in this case it will inherit the level of  parent upwards in the hierarchy. As if we have a package com.beingjavaguys.logging and we didn’t assigned a level to it than  it will inherit level from its parent i.e. level of com.beingjavaguys … and what if even com.beingjavaguys is not having a level than it will inherit a level from com …and if all upwards parent are exhausted and no one is assigned a level than LOG4J’s root logger is assigned that is ‘DEBUG’.

2) Appender in LOG4J

LOG4J can represent the logs in many formats and this is what Appneders does exactly. Appender is responsible for publishing the final log output to destinations. There are a number of appenders some of them are listed below

ConsoleAppender

    ConsoleAppender appender = new ConsoleAppender(new PatternLayout()); 
        

FileAppender

    FileAppender appender = new FileAppender(new PatternLayout(),"filename"); 
        

WriterAppender

    WriterAppender appender = new WriterAppender(new PatternLayout(),new  FileOutputStream("filename")); 

Othet than these appenders listed above there are some other appenders that LOG4J provides : SMTPAppender, SocketAppender, TelnetAppender …etc.



3) Layout in LOG4J

In LOG4J logging framework, each appender requires a layout which formats the final output to be displayed by appenders. User can control and manage the output formats of log messages by modifying layout settings in log4j.properties file.

There are basically three types of layout, HTML Layout, Pattern Layout and Simple Layout.

Now we will go to the actual configuration and implementation of LOG4J in Spring


we will cover LOG4J configuration with Maven Spring MVC step by step process. We will also look into LOG4J configuration using XML files



Project Structure will look like below



 



Start with Log4J Configuration file log4j.xml


This is the main configuration file having all runtime configuration used by log4j. This file will have appenders information, log level information and output file names for file appenders.
 

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
    <appender name="FileLogger" class="org.apache.log4j.RollingFileAppender">
        <!--param name="DatePattern" value="'.'yyyy'-'MM'-'dd"/-->
        <param name="File" value="E:/Trainings/Spring/SpringMVC/logs/spring.log" />
        <param name="MaxFileSize" value="10MB" />
        <param name="maxBackupIndex" value="5"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                value="%d{dd-MM-yyyy HH:mm:ss,SSS} %5p [%t] %C %L - %m%n" />
        </layout>
    </appender>
   
    <root>
        <priority value="DEBUG" />
        <appender-ref ref="FileLogger" />
    </root>

</log4j:configuration>




Update pom.xml file with log4j and spring dependencies 



<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.mahesh</groupId>
    <artifactId>SpringMVC</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>SpringMVC Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <spring.version>3.0.5.RELEASE</spring.version>
    </properties>

    <dependencies>

        <!-- Spring 3 dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
       
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>SpringMVC</finalName>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>


 Below is the Content for HelloController.java with logging code




package com.mahesh.common.controller;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/welcome")
public class HelloController {
    private static final Logger LOG = Logger.getLogger("HelloController.class");

    @RequestMapping(method = RequestMethod.GET)
    public String printWelcome(ModelMap model) {
       
        LOG.info("Entered printWelcome Method");

        model.addAttribute("message", "Spring 3 MVC FrameWork");
        LOG.debug("added message attribute");
       
        return "hello";

    }
}


Below is the Content for mvc-example-servlet.xml



<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans    
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com.mahesh.common.controller" />

    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/pages/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

</beans>



Below is the Content for web.xml



<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <display-name>Spring Web MVC Application</display-name>

    <servlet>
        <servlet-name>mvc-example</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>mvc-example</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/mvc-example-servlet.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

</web-app>



Below is the Content for  hello.jsp



<html>
<body>
    <h1>Hello : ${message}</h1>   
</body>
</html>



Finally generate the war file and deploy it in tomcat Server:


mvn clean install command to generate war


log file will be generated in specified path as mentioned in below param tag after successfull deployement of application in Tomcat Server.

<param name="File" value="E:/Trainings/Spring/SpringMVC/logs/spring.log" />





No comments:

Post a Comment