0

I wrote the following sample code to check logs. This code works. I'm using Spring Boot 2.7.1.

All controllers have this line of code: log.debug("IP " + request.getRemoteAddr() + " -> " + request.getRequestURI());

Since throughout the code for this project I would like all controllers to have this line of code, I am wondering if there is a way to achieve the same result in a more compact way. In other words, I would not want to repeat this line of code every time. I would prefer the log.debug with IP and URL to happen automatically for each controller. Is this possible?

package ...;

import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestMe {
    
    private final Logger log = LoggerFactory.getLogger(this.getClass());
    
    @GetMapping("/testme")
    @ResponseBody
    public String testme(HttpServletRequest request) {
        log.debug("IP " + request.getRemoteAddr() + " -> " + request.getRequestURI());
        return "I'm working! :-)";
    }
    
    @GetMapping("/testerror")
    @ResponseBody
    public int testerror(HttpServletRequest request) {
        log.debug("IP " + request.getRemoteAddr() + " -> " + request.getRequestURI());
        return 1 / 0;
    }

    @GetMapping("/testexception")
    @ResponseBody
    public int testexception(HttpServletRequest request) {
        log.debug("IP " + request.getRemoteAddr() + " -> " + request.getRequestURI());
        throw new IllegalStateException("Test Exception");
    }
    
    @GetMapping("/testlogs")
    @ResponseBody
    public String testlogs(HttpServletRequest request) {
        log.debug("IP " + request.getRemoteAddr() + " -> " + request.getRequestURI());
        log.trace("test log TRACE level");
        log.debug("test log DEBUG level");
        log.info("test log INFO level");
        log.warn("test log WARN level");
        log.error("test log ERROR level");
        return "Please check the logs";
    }
    
    /**
     * Spring Controller to handle all requests not matched by the previous Controllers,
     * @return 
     */
    @RequestMapping (value = "/**", method = {RequestMethod.GET, RequestMethod.POST})
    public String greetings(HttpServletRequest request) {
        log.debug("IP " + request.getRemoteAddr() + " -> " + request.getRequestURI());
        log.warn("Unmapped request handling from IP " + request.getRemoteAddr() + " -> " + request.getRequestURI());
        return "Greetings! Please check the logs";
    }
    
}
Francesco Galgani
  • 6,137
  • 3
  • 20
  • 23

1 Answers1

0

Assuming that all my Controllers are in the xxx.layer1controllers package, the following class is a possible solution:

package ...;

import javax.servlet.http.HttpServletRequest;
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;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class MyAspect {

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

    // info: https://www.baeldung.com/spring-aop-pointcut-tutorial & https://stackoverflow.com/a/39508845/1277576
    @Before("within(xxx.layer1controllers..*))")
    public void logController(JoinPoint joinPoint) throws Exception {

        if (joinPoint.getArgs().length > 0 && joinPoint.getArgs()[0] instanceof HttpServletRequest) {
            HttpServletRequest request = (HttpServletRequest) joinPoint.getArgs()[0];
            log.debug("IP " + request.getRemoteAddr() + " -> " + request.getRequestURI());
        } else {
            log.warn("Let's remember to add a HttpServletRequest parameter to " + joinPoint.getSignature().toShortString());
        }
    }
}

Francesco Galgani
  • 6,137
  • 3
  • 20
  • 23