前言
在開發項目的時候,想知道請求的各種參數,需要自己去logger打印,但是我總覺得的有點麻煩。所以我就使用AOP寫了一個starter,來打印一些請求參數,方便開發時查看請求參數以及其他內容。
一、配置類
首先寫個配置類,主要是方便日誌打印的開啓與關閉
@ConfigurationProperties(prefix="spring.request.logging")
public class RequestLoggingProperties {
private boolean enable;
public boolean isEnable() {
return enable;
}
public void setEnable(boolean enable) {
this.enable = enable;
}
}
二、AOP打印請求日誌
主要是切controller層的方法,把方法的請求路徑,參數等等都打印出來,方法的執行時間,返回數據也一併打印出來。返回的數據根據不同情況打印不同的內容。ResultBO參考之前的自定義異常。
我過濾了一下一些關於swagger的路徑。
@Aspect
public class ControllerAspect {
private static final Logger log = LoggerFactory.getLogger(ControllerAspect.class);
private final String cut = "@annotation(org.springframework.web.bind.annotation.RequestMapping)"
+ "||"
+ "@annotation(org.springframework.web.bind.annotation.PostMapping)"
+ "||"
+ "@annotation(org.springframework.web.bind.annotation.GetMapping)"
+ "||"
+ "@annotation(org.springframework.web.bind.annotation.DeleteMapping)"
+ "||"
+ "@annotation(org.springframework.web.bind.annotation.PatchMapping)"
+ "||"
+ "@annotation(org.springframework.web.bind.annotation.PutMapping)";
public long startTime;
public long endTime;
@Autowired
private RequestLoggingProperties properties;
/**請求方法前打印請求內容
* @param joinPoint
*/
@Before(value=cut)
public void methodBefor(JoinPoint joinPoint) {
if (properties.isEnable()) {
startTime = System.currentTimeMillis();
ServletRequestAttributes requestAttributes=(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
String url = request.getRequestURL().toString();
if (!url.contains("swagger")) {
log.info("==========請求內容==========");
log.info("請求ip:{}",IpGetterUtils.getIPAddress(request));
log.info("請求全路徑:{}",request.getRequestURL().toString());
log.info("請求方式:{}",request.getMethod());
log.info("請求端口:{}",request.getLocalPort());
//log.info("請求類方法:{},joinPoint.getSignature());
log.info("請求參數:{}",Arrays.toString(joinPoint.getArgs()));
log.info("==========請求結束==========");
}
}
}
/**請求結束後打印返回內容
* @param returnValue 返回值
*/
@AfterReturning(pointcut=cut,returning="returnValue")
public void methodAfterReturing(Object returnValue){
if (properties.isEnable()) {
endTime = System.currentTimeMillis();
long currentTime = endTime - startTime;
ServletRequestAttributes requestAttributes=(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = requestAttributes.getRequest();
String url = request.getRequestURL().toString();
if (!url.contains("swagger")) {
log.info("==========響應內容==========");
log.info("請求耗時:{}",currentTime+"ms");
if (returnValue instanceof ResultBO) {
@SuppressWarnings("unchecked")
ResultBO<Object> res = (ResultBO<Object>) returnValue;
Integer code = res.getCode();
String msg = res.getMsg();
log.info("code:{}",code);
log.info("msg:{}",msg);
}else if(returnValue instanceof ResponseEntity){
@SuppressWarnings("unchecked")
ResponseEntity<Object> res = (ResponseEntity<Object>) returnValue;
int code = res.getStatusCodeValue();
log.info("code:{}",code);
}else{
log.info("返回數據:{}",returnValue);
}
log.info("==========響應內容==========");
}
}
}
}
三、自動配置
還是和之前一樣,需要一個AutoConfiguration和一個註解。
@Configuration
@EnableConfigurationProperties(value={RequestLoggingProperties.class})
@ConditionalOnClass(value=ControllerAspect.class)
@ConditionalOnProperty(prefix="spring.request.logging",value="enable",matchIfMissing=true)
public class RequestLoggingAutoConfiguration {
@Bean
@ConditionalOnMissingBean(ControllerAspect.class)
public ControllerAspect controllerAspect() {
ControllerAspect controllerAspect = new ControllerAspect();
return controllerAspect;
}
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({RequestLoggingAutoConfiguration.class})
public @interface EnableRequestLogging {
}
四、使用
啓動類添加@EnableRequestLogging註解。
如果想關閉日誌打印,可以在application.properties裏配置
spring.request.logging.enable=false
寫在最後的話
請求日誌打印和全局異常處理我寫在一起了,這樣更方便一些。