Aspect trace logging in Java (Spring Framework)

An easy way to enable tracing of methods and parameter values in Java Spring is by using AspectJ. A simplified example of my Aspect class to make tracing easy, without any ‘logger.trace’ code in the classes itself:

package com.markvandenbergh.test.util;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Aspect
public class LoggerAspect {

    private final Logger logger = LoggerFactory.getLogger(LoggerAspect.class);

    // before the execution of any method with any number and type of parameters
    // in package 'test' and any sub-package execute the following code...
    @Before("execution(* com.markvandenbergh.test..*.*(..))")
    public void beforeMethod(JoinPoint joinPoint) {
        if(logger.isTraceEnabled()) {
            // constructing a string of the method signature, method and parameters
            String traceString = joinPoint.getSignature().getDeclaringTypeName() +
                "." + joinPoint.getSignature().getName() + "(";
            Object[] args = joinPoint.getArgs();
            for(int i = 0; i < args.length; i++) {
                if(args[i] != null) {
                    traceString += args[i];
                } else {
                    traceString += "null";
                }
                if(i < (args.length -1)) {
                    traceString += ", ";
                }
            }
            traceString += ")";
            logger.trace(traceString);
        }
    }
}

If tracing is enabled this will log the entry of any method with it’s parameters within the com.markvandenbergh.test package (sub-packages included, because of the double dot between ‘test’ and ‘*.*’). Example of the output:

2012-01-26 15:51:55,942 TRACE http-bio-8080-exec-4 com.markvandenbergh.test.service.TestService.methodNumberOne(parameterValue)
2012-01-26 15:51:55,942 TRACE http-bio-8080-exec-4 com.markvandenbergh.test.service.TestRepository.methodInRepository(parameterValue)

Do note that only Spring beans will be picked up by the Aspect. If you have regular Java classes that are not instantiated using Spring they will not be logged using this code.
You also need some minor Spring configuration for this.

<?xml version="1.0" encoding="UTF-8"?>
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <aop:aspectj-autoproxy />
    <bean class="com.markvandenbergh.test.util.LoggerAspect" />

</beans>

The Maven dependencies for this are:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>

All of this is nothing new or fancy, but I found it quite useful in reducing the amount of work and boilerplate code in my classes. Some other useful ‘advice’ types (that’s what the ‘before’ is called) are: ‘after’ and ‘around’. ‘After’ works about the same as the ‘before’ in my example, for an example of the ‘around’ advice go to the Spring framework reference documentation.

This entry was posted in Coding, General, Java, Spring and tagged , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>