让每个控制器记录 request.getRemoteAddr() 和 request.getRequestURI()

问题描述 投票:0回答:1

我编写了以下示例代码来检查日志。这段代码有效。我正在使用 Spring Boot 2.7.1。

所有控制器都有这行代码:

log.debug("IP " + request.getRemoteAddr() + " -> " + request.getRequestURI());

由于在这个项目的整个代码中,我希望所有控制器都有这行代码,我想知道是否有一种方法可以以更紧凑的方式实现相同的结果。换句话说,我不想每次都重复这行代码。我希望每个控制器自动出现带有 IP 和 URL 的

log.debug
。这可能吗?

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";
    }
    
}
spring-boot
1个回答
0
投票

假设我所有的控制器都在

xxx.layer1controllers
包中,以下类是一个可能的解决方案:

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());
        }
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.