<!--引入aop-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--日志切面,以json形式输出-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
<!--spring-boot-starter-aop包中含aspectj,所以项目这里不需要再引入-->
<!--<dependency>-->
<!--<groupId>org.aspectj</groupId>-->
<!--<artifactId>aspectjweaver</artifactId>-->
<!--<version>1.9.4</version>-->
<!--<scope>compile</scope>-->
<!--</dependency>
import java.lang.annotation.*;
/**
* @Author ds
* @Date 12/5/22
* @Retention 什么时候使用该注解,这里定义为运行时
* @Target 注解用于什么地方,我们定义为作用于方法上
* @Documented 注解是否将包含在JavaDoc中
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
@Documented
public @interface WebLog {
/**
* 是否必须打印返回参数,默认是
* @return
*/
boolean resultRequired() default true;
}
import com.google.gson.Gson;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
/**
* @Author ds
* @Date 12/5/22
*/
@Aspect
@Component
@Slf4j
public class WebLogAspect {
/**
* 换行符
*/
private static final String LINE_SEPARATOR = System.lineSeparator();
@Pointcut("@annotation(cn.com.zengxin.common.annotation.WebLog)")
public void webLog(){}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) throws Throwable{
// 开始打印请求日志
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 获取@WebLog 注解的描述信息
String methodDescription = getAspectLogDescription(joinPoint);
// 打印请求相关参数
log.info("======================================== start ========================================");
// 打印请求 url
log.info("URL :{}",request.getRequestURL().toString());
// 打印描述信息
log.info("Description :{}",methodDescription);
// 打印Http method
log.info("HTTP Method :{}" ,request.getMethod());
// 打印调用controller 的全路径以及执行方法
log.info("Class Method :{}.{}",joinPoint.getSignature().getDeclaringTypeName(),joinPoint.getSignature().getName());
// 打印请求的 IP
log.info("IP :{}",request.getRemoteAddr());
// 打印请求入参
log.info("Request Args :{}",new Gson().toJson(joinPoint.getArgs()));
log.info("=====================================================================================");
}
public void doAfter() throws Throwable {
// 接口结束后换行,方便分割查看
log.info("======================================== end ========================================" + LINE_SEPARATOR);
}
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
long startTime = System.currentTimeMillis();
Object result = proceedingJoinPoint.proceed();
MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
Method method = signature.getMethod();
if(method.isAnnotationPresent(WebLog.class)){
WebLog webLog = method.getAnnotation(WebLog.class);
if(webLog.resultRequired()){
// 打印出参
log.info("Response Args :{}",new Gson().toJson(result));
}
}
// 执行耗时
log.info("Time-Consuming :{} ms",System.currentTimeMillis(),startTime);
return result;
}
public String getAspectLogDescription(JoinPoint joinPoint) throws Exception{
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
StringBuilder description = new StringBuilder();
for(Method method :methods){
if(method.getName().equals(methodName)){
Class[] classes = method.getParameterTypes();
if(classes.length == arguments.length){
description.append(method.getAnnotation(WebLog.class).resultRequired());
break;
}
}
}
return description.toString();
}
}
@ApiOperation(value = "【IN1001】业务数据推送", produces = "application/json")
@PostMapping(value = "in1001", produces = {"application/json;charset=UTF-8"})
@WebLog
public RestResponse in1001(@RequestBody BusinessDataPushVo businessDataPushVo) {
// 省略逻辑.....
}
22-12-05.16:37:29.691 [http-nio-42202-exec-3] INFO WebLogAspect - ======================================== start ========================================
22-12-05.16:37:29.692 [http-nio-42202-exec-3] INFO WebLogAspect - URL :http://127.0.0.1:42202/api/api/v3/in1001
22-12-05.16:37:29.692 [http-nio-42202-exec-3] INFO WebLogAspect - Description :true
22-12-05.16:37:29.692 [http-nio-42202-exec-3] INFO WebLogAspect - HTTP Method :POST
22-12-05.16:37:29.692 [http-nio-42202-exec-3] INFO WebLogAspect - Class Method :cn.com.zengxin.api.controller.v3.ApiV3In1001Ctrl.in1001
22-12-05.16:37:29.692 [http-nio-42202-exec-3] INFO WebLogAspect - IP :127.0.0.1
22-12-05.16:37:29.694 [http-nio-42202-exec-3] INFO WebLogAspect - Request Args :[{"btypeId":"51"}]
22-12-05.16:37:29.694 [http-nio-42202-exec-3] INFO WebLogAspect - =====================================================================================
参考:
https://blog.csdn.net/weixin_39638048/article/details/111036767
网友评论