Tuesday, January 12, 2010

LOG4J Implementation with Spring AOP

LOG4J Implementation with Spring AOP

LOG4J Implementation:

Introduction : Apache log4j is a Java-based logging utility.

Jar Files:

(Download url http://logging.apache.org/log4j/1.2/download.html)

Commons-logging-1.1.jar

Log4j-1.2.8.jar

Log4j-boot.jar

Along with Spring jar file spring.jar

Configuration :

applicationContext.xml:

Creating a bean(In Spring ,Bean represents a java class) to define logger properties like what

the levels(statements) log should be invoked ,we can call this class as Adviser class for logging

mechanism ,it tells the logger to how to work or behave.

<bean id="loggingAdviceWithSpringAOP"

class="com.loggerExampleWithSpringAOP.logging.LoggingAdviserWithSpringAOP" />

//Enabling aspect autoproxy target class true

<aop:aspectj-autoproxy proxy-target-class="true" />

//Creating a pointCut using AOP ,PointCut is nothing but a locations or files or methods to fire

or call the Advice i.e In case of logging logger Advice(loggingAdviceWithSpringAOP)

<aop:config>

<aop:pointcut id="loggingPointcutUsingSpringAOP"

expression="execution(*com.loggerExampleWithSpringAOP.ram.*.*.*.*(..))

and

!execution(*com.loggerExampleWithSpringAOP.ram.*.*.*.set*(..))

and

!execution(*com.loggerExampleWithSpringAOP.ram.*.*.*.get*(..))" />

<!—this below statement or AOP advisor mapping between the pointCUt and Adviser class

,This advicer class is referenced using property advice-ref , pointCut is referenced By pointcutref

property . This Advisor invoked as per the pointCut definition. ----à

<aop:advisor advice-ref="loggingAdviceWithSpringAOP" pointcut-ref="

loggingPointcutUsingSpringAOP" />

</aop:config>//End of AOP configuration

In above point Cut, the logger advice should be be execute the methods or classes of the

methods which resides in the package com.loggerExampleWithSpringAOP.ram , by using the

expression property or attribute ,using the execution method which was defined in declarative

Spring AOP. In this point Cut , if Method starts with Set or get in package

com.loggerExampleWithSpringAOP.ram.*.*.*. ,In that package for testing let consider, there is

a class com.loggerExampleWithSpringAOP.ram.*.*.*.TestLoggingService.java , Code looks

like below

Sample Test Class:

package com.loggerExampleWithSpringAOP.ram.test.logger.Service;

public class TestLoggingService {

private DAO dao;

/**

* @return the dao

*/

public DAO getDao() {

return dao;

}

/**

* @param dao the dao to set

*/

public void setDao(DAO dao) {

this.dao = dao;

}

Public TestLogger(){

Int i=0;

System.out.println("I value is"+i);

Sysout.out.println("this method will executes or onvoked by the logger and the methods which

starts with set or get in this class won't execute ,We are not invoking the logger for set and get

because those methods are just setters and getters and won't perfom any business logic to

maintain the logger );

}

}

package com.loggerExampleWithSpringAOP.logging;

import java.lang.reflect.InvocationTargetException;

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

import org.apache.log4j.Logger;

Logger Adviser class:

/**

*

* This class used for Logging the information during method execution

*

* @author Ram

*

*/

public class LoggingAdviserWithSpringAOP implements MethodInterceptor {

public LoggingAdviserWithSpringAOP () {

}

public Object invoke(MethodInvocation invocation) throws Throwable{

Object result = null;

try {

Logger logger = Logger.getLogger(invocation.getMethod()

.getDeclaringClass().getName());

logger.info(invocation.getMethod().getName());

result = invocation.proceed();

} catch (InvocationTargetException e) {

Logger logger = Logger.getLogger("ERROR");

logger.error("Exception occured"+e.getMessage());

logger.error("Exception occured"+e.toString());

logger.error("Exception occured"+e.getLocalizedMessage());

}catch (Exception e){

Logger logger = Logger.getLogger("ERROR");

logger.error("Exception occured"+e.getMessage());

logger.error("Exception occured"+e.toString());

throw e;

}

return result;

}

}

Log4j Configuration file:

For eg : our Project/Application name is loggerExampleWithSpringAOP(the EAR generating

file name) then configuration name will be

loggerExampleWithSpringAOP_log4j.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE log4j:configuration SYSTEM "D:\log4j.dtd">

<log4j:configuration threshold="Debug"

xmlns:log4j='http://jakarta.apache.org/log4j/'>

<appender name="FILE_APPENDER"

class="org.apache.log4j.DailyRollingFileAppender">

<param name="File" value="E:/ loggerExampleWithSpringAOP

_test_application.log" />

<param name="Append" value="true"/>

<param name="DatePattern" value="'.'yyyy-MM-dd.HH"/>

<layout class="org.apache.log4j.PatternLayout">

<param name="ConversionPattern" value="%d %p [%X{uName}] [%c{4}]

%M %m%n"/>

</layout>

</appender>

<category name=" com.loggerExampleWithSpringAOP">

<priority value="INFO" />

<appender-ref ref="FILE_APPENDER" />

</category>

</log4j:configuration>

This file location should be added to Application Server classpath, UserEntries for Eg this

folder under common resources

CommonResources/log4j/loggerExampleWithSpringAOP_log4j.xml

In classpath,USerEntries .just we need to add upto log4j folder is enough ,if file directly added

it won't work .

To add this folder in case of JBoss Application server

Click on configured Server, Open launch Configuration,therea tab with name classpath, by

clickon that ,bottom to that tab ,class path in editable mode will be appear, Right side there is a

button called Advanced , by clicking on that will get below screen

By Selecting add folders from the above screen, we can add the log4j folder to classpath. Once

added just restart the server…Our Log works fine.

Brief general information of Log From the http://logging.apache.org/log4j/ is below

Log level

The following table defines the log levels and messages in Log4j, in decreasing order of

severity. The left column lists the log level designation in Log4j and the right column provides

a brief description of each log level.

Level Description

FATAL

Severe errors that cause premature

termination. Expect these to be

immediately visible on a status console.

ERROR

Other runtime errors or unexpected

conditions. Expect these to be

immediately visible on a status console.

WARN

Use of deprecated APIs, poor use of API,

'almost' errors, other runtime situations

that are undesirable or unexpected, but

not necessarily "wrong". Expect these to

be immediately visible on a status

console.

INFO

Interesting runtime events (startup/

shutdown). Expect these to be

immediately visible on a console, so be

conservative and keep to a minimum.

DEBUG

Detailed information on the flow through

the system. Expect these to be written to

logs only.

TRACE

More detailed information. Expect these

to be written to logs only. Was only

added in version 1.2.12.

Inserting log statements into your code is a low-tech method for debugging it. It may also be

the only way because debuggers are not always available or applicable. This is often the case

for distributed applications.

On the other hand, some people argue that log statements pollute source code and decrease

legibility. (We believe that the contrary is true). In the Java language where a preprocessor is

not available, log statements increase the size of the code and reduce its speed, even when

logging is turned off. Given that a reasonably sized application may contain thousands of log

statements, speed is of particular importance.

With log4j it is possible to enable logging at runtime without modifying the application binary.

The log4j package is designed so that these statements can remain in shipped code without

incurring a heavy performance cost. Logging behavior can be controlled by editing a

configuration file, without touching the application binary.

Logging equips the developer with detailed context for application failures. On the other hand,

testing provides quality assurance and confidence in the application. Logging and testing

should not be confused. They are complementary. When logging is wisely used, it can prove to

be an essential tool.

One of the distinctive features of log4j is the notion of inheritance in loggers. Using a logger

hierarchy it is possible to control which log statements are output at arbitrarily fine granularity

but also great ease. This helps reduce the volume of logged output and minimize the cost of

logging.

The target of the log output can be a file, an OutputStream, a java.io.Writer, a remote log4j

server, a remote Unix Syslog daemon, or many other output targets.

On an AMD Duron clocked at 800Mhz running JDK 1.3.1, it costs about 5 nanoseconds to

determine if a logging statement should be logged or not. Actual logging is also quite fast,

ranging from 21 microseconds using the SimpleLayout, 37 microseconds using the

TTCCLayout. The performance of the PatternLayout is almost as good as the dedicated layouts,

except that it is much more flexible.

Almost every large application includes its own logging or tracing API. In conformance with

this rule, the E.U. SEMPER project decided to write its own tracing API. This was in early

1996. After countless enhancements, several incarnations and much work that API has evolved

to become log4j, a popular logging package for Java. The package is distributed under the

Apache Software License, a fully-fledged open source license certified by the

open source initiative. The latest log4j version, including full-source code, class files and

documentation can be found at http://logging.apache.org/log4j/. By the way,

log4j has been ported to the C, C++, C#, Perl, Python, Ruby, and Eiffel languages.

Inserting log statements into code is a low-tech method for debugging it. It may also be the

only way because debuggers are not always available or applicable. This is usually the case for

multithreaded applications and distributed applications at large.

Experience indicates that logging was an important component of the development cycle. It

offeres several advantages. It provides precise context about a run of the application. Once

inserted into the code, the generation of logging output requires no human intervention.

Moreover, log output can be saved in persistent medium to be studied at a later time. In

addition to its use in the development cycle, a sufficiently rich logging package can also be

viewed as an auditing tool.