【造個輪子系列】之springboot使用AOP打印請求日誌

前言

在開發項目的時候,想知道請求的各種參數,需要自己去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

寫在最後的話

請求日誌打印和全局異常處理我寫在一起了,這樣更方便一些。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章