项目场景:
如:相关登录、删除 重点方法日志。需要存进mysql中。
解决方案:
提示:自定义方法注解 运用AOP实现日志入库 以及 监控方法是否正常执行。
1.自定义注解 :运用@Target @Retention 两个原注解实现
/**
* @Description: 重点方法记录注解
* @Author: HuangJiangMin
* @Date:
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EchoLog {
String methodDescription() default "方法描述";
}
2.库表Entity
/**
* 重点方法记录表
* hjm
*/
@Data
@Table(name = "method_log")
@Entity
public class MethodLogEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String telephone;
private String serveSource;
private String userIp;
//浏览器
private String userWebAgent;
//方法APi
private String methodApi;
//方法描述
private String methodDescription;
//方法执行类型 0 正常 1 异常
private Integer methodExecuteType;
//请求入参
private String methodRequest;
//返回 异常则 存储异常信息
private String methodResponse;
private Date createTime;
}
3.AOP实现
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonObject;
import io.micrometer.core.instrument.util.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import scirichon.echo.art.app.methodLog.IMethodLog;
import scirichon.echo.art.domain.methodLog.MethodLogEntity;
import scirichon.echo.art.dto.base.ResponseVO;
import scirichon.echo.art.infrastructure.Exception.EchoException;
import scirichon.echo.art.infrastructure.annotation.EchoLog;
import scirichon.echo.art.infrastructure.constant.Constant;
import scirichon.echo.art.infrastructure.echoUtils.IpUtils;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;
/**
* @Description:项目重点方法日志入库监控
* @Author: HuangJiangMin
* @Date: 2019/12/2
*/
@Aspect
@Component
@Slf4j
public class MethodLogAspect {
@Autowired
IMethodLog methodLogService;
public static String content = "";
public static Boolean isNormalProcess = true;
@Pointcut("@annotation(scirichon.echo.art.infrastructure.annotation.EchoLog)")
public void MyPointcut() {
//定义切入点
}
@AfterReturning(returning = "ret", pointcut = "MyPointcut()")// returning的值和doAfterReturning的参数名一致
public void doAfterReturning(JoinPoint joinPoint, Object ret) throws Throwable {
saveLog(joinPoint, isNormalProcess, content);
}
@AfterThrowing(throwing = "ex", pointcut = "MyPointcut()")
public void afterThrowing(JoinPoint joinPoint, Exception ex) {
isNormalProcess = false;
content = ex.getMessage();
saveLog(joinPoint, isNormalProcess, content);
}
void saveLog(JoinPoint point, Boolean isNormalProcess, String context) {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
EchoLog annotation = method.getAnnotation(EchoLog.class);
// 获取request
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String token = request.getHeader("token");
String telephone = "";
if (null == token || token.equals("")) {
telephone = StringUtils.substringBetween(Arrays.toString(point.getArgs()), "telephone=", ",");
telephone = StringUtils.substringBefore(telephone, "}");
} else {
try {
telephone = JWT.decode(token).getAudience().get(0);
} catch (Exception e) {
throw new EchoException("token存在异常");
}
}
//ip
String ipAddr = IpUtils.getIpAddr(request);
//操作端
String serveResource = request.getHeader(Constant.SERVE_RESOURCE);
String browser = request.getHeader("User-Agent");
//方法描述
String methodDescription = annotation.methodDescription();
MethodLogEntity methodLogEntity = new MethodLogEntity();
methodLogEntity.setMethodApi(point.getSignature().getName());
methodLogEntity.setMethodRequest(Arrays.toString(point.getArgs()));
methodLogEntity.setCreateTime(new Date());
methodLogEntity.setMethodDescription(methodDescription);
methodLogEntity.setUserIp(ipAddr);
methodLogEntity.setTelephone(telephone);
methodLogEntity.setServeSource(serveResource);
methodLogEntity.setUserWebAgent(browser);
//该请求是否异常
if (isNormalProcess) {
methodLogEntity.setMethodExecuteType(0);
} else {
methodLogEntity.setMethodExecuteType(1);
}
methodLogEntity.setMethodResponse(context);
methodLogService.save(methodLogEntity);
}
}
ok了。