前言
在开发项目的时候,想知道请求的各种参数,需要自己去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
写在最后的话
请求日志打印和全局异常处理我写在一起了,这样更方便一些。