0

I have used this tutorial Accessing JPA Data with REST to create a simple RESTful Webservice that access some data from a database. It works great. I love how simple it is and I understand more or less how it works.

I have been asked, however, to add some custom logging. Whenever the web service gets called a log, "Start - TIME", is generated and just before the service returns generate another log, "End - TIME". Is there a way to do that without disrupting my the methods containing the @Query anotation

public interface PersonRepository extends PagingAndSortingRepository<Person, Long>

I was kind of hopping that there would be some sort of annotation but I can't seem to find anything.

Any suggestions?

Neil Stockton
  • 11,383
  • 3
  • 34
  • 29
Francisco
  • 145
  • 1
  • 3
  • 13

1 Answers1

4

Sounds like a case for Spring-AOP!

Working from a very helpful tutorial (and also a useful SO answer), I whipped up something that logged before and after executing any methods in my TokenRepository

@Repository
public interface TokenRepository extends CrudRepository<Token, String> {
}

and the interesting bit is

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingHandler {

    Logger log = LoggerFactory.getLogger(this.getClass());

    @Pointcut("this(org.springframework.data.repository.Repository)")
    public void repository() { }

    @Pointcut("execution(* *.*(..))")
    protected void allMethod() { }

    //before -> Any resource annotated with @Repository annotation
    //and all method and function
    @Before("repository() && allMethod()")
    public void logBefore(JoinPoint joinPoint) {
        log.info("Entering in Method :  " + 
joinPoint.getSignature().getName() + " at " + System.currentTimeMillis());
    }

    //After -> All method within resource annotated with @Repository annotation
    @AfterReturning(pointcut = "repository() && allMethod()")
    public void logAfter(JoinPoint joinPoint) {
        log.info("Method Returned at : " + System.currentTimeMillis());
    }
}
John
  • 81
  • 3
  • This worked like a charm. I just have to get acquainted with AOP – Francisco Aug 02 '17 at 15:48
  • What if I wanted to pass variables between the logBefore() and logAfter() methods. For example an identifier such that the before log would read "98f473ea-f333-4278-adf1-b70eba4c9338 - START - 2017-008-08 10:10:00" and the after log would read "98f473ea-f333-4278-adf1-b70eba4c9338 - END - 2017-008-08 10:10:10". Basically some sort of identifier that will identify the start and end of a call to the method – Francisco Aug 08 '17 at 18:37