我编写了以下示例代码来检查日志。这段代码有效。我正在使用 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";
}
}
假设我所有的控制器都在
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());
}
}
}