Tobias Erdle's Blog

Development Engineer working with different technologies. Former Jakarta MVC & Eclipse Krazo Committer. All views are my own.

Github: erdlet | E-Mail: blog (at) erdlet (punkt) de

Trace method executions in Spring Boot application

Tracing method input parameters and return values is very helpful during development or debugging. During a project where I try to focus on logging, I stubled over Springs CustomizableTraceInterceptor, which is doing exactly the work I wanted to implement myself.

Necessary dependencies

In case you want to implement this Interceptor in an web application, you need at least the following 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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    ...

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

        ...

    </dependencies>

    ...

</project>

Configuration

To activate the CustomizableTraceInterceptor, you need to activate AOP on your Spring Boot application like this:

@EnableAspectJAutoProxy(proxyTargetClass = true)
@SpringBootApplication
public class Application {

    public static void main(final String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Also, you need to configure the logging framework of your application to log the methods you want to intercept on TRACE level. After everything is configured, you can add this example configuration and change the pointcut at [1] to your package name.

package de.erdlet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.interceptor.AbstractTraceInterceptor;
import org.springframework.aop.interceptor.CustomizableTraceInterceptor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class LoggingConfig {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoggingConfig.class);

    @Bean
    public AbstractTraceInterceptor traceInterceptor() {
        final CustomizableTraceInterceptor interceptor = new CustomizableTraceInterceptor();
        interceptor.setUseDynamicLogger(true);
        interceptor.setEnterMessage("Entering method with param types [$[argumentTypes]] and values [$[arguments]]");

        return interceptor;
    }

    @Bean
    public Advisor traceAdvisor() {
        final AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        [1] pointcut.setExpression("execution(public * de.erdlet..*.*(..))");

        return new DefaultPointcutAdvisor(pointcut, traceInterceptor());
    }
}