Springboot接口项目使用AOP记录日志的方法
                                            这篇文章主要讲解了Springboot接口项目使用AOP记录日志的方法,内容清晰明了,对此有兴趣的小伙伴可以学习一下,相信大家阅读完之后会有帮助。

10年积累的成都网站设计、网站制作经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先建设网站后付款的网站建设流程,更有新巴尔虎右免费网站建设让你可以放心的选择与我们合作。
一、 背景
一直想给项目构建一个统一的日志收集系统,先迈出第一步,构建一个日志收集类,用AOP实现无侵入日志收集
二、 环境
1.此随笔内容基于spring boot项目
2.数据库为MySQL 5.7.9版本
3.jdk 版本为1.8
三、 说明
此版采用数据库存储,之后考虑使用elasticsearch等工具存储
四、 内容
1、构建日志采集实体类:BaseLogMessage
public class BaseLogMessage {
  private String serverIP;
  private String appName;
  private String method;
  private String type;
  private String userCode;
  private String uri;
  private String operationName;
  private String operationStatus;
  private long startTime;
  private Object parameter;
  private Object result;
  private int SpendTime;
 // 此处省略get、set
}2、构建一个配置文件读取类,用于读取配置文件中的系统名称:SystemPropetiesUtil
@Configuration
public class SystemPropetiesUtil {
  @Value("${spring.application.name}")
  private String sysName;//系统名称
  // 此处省略get、set
}3、新建一个AOP类,在控制器方法上作为切点,执行日志收集: LogAspect
@Aspect
@Component
public class LogAspect {
  @Autowired
  private SystemPropetiesUtil systemPropetiesUtil;
 
  //定义切点方法
  @Pointcut("execution(public * cq..campus.prevented.controller.*.*(..))")
  public void controllerLog() {
  }
 
  public static final Logger LOGGER = LoggerFactory.getLogger(LogAspect.class);
 
  @Around("controllerLog()")
  public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
    long startTime = System.currentTimeMillis();
    //获取当前请求对象
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();
    //记录请求信息
    BaseLogMessage baseLogMessage = new BaseLogMessage();
    //1.获取到所有的参数值的数组
    Object[] args = joinPoint.getArgs();
    Signature signature = joinPoint.getSignature();
    MethodSignature methodSignature = (MethodSignature) signature;
    //2.获取到方法的所有参数名称的字符串数组
    String[] parameterNames = methodSignature.getParameterNames();
    Object result = joinPoint.proceed();
    Method method = methodSignature.getMethod();
    if (method.isAnnotationPresent(ApiOperation.class)) {
      ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
      baseLogMessage.setOperationName(apiOperation.value());
    }
    long endTime = System.currentTimeMillis();
    String urlStr = request.getRequestURL().toString();
    baseLogMessage.setUri(urlStr);
    baseLogMessage.setType("操作日志");
    baseLogMessage.setServerIP(getRemoteIP(request));
    baseLogMessage.setMethod(request.getMethod());
    baseLogMessage.setAppName(systemPropetiesUtil.getSysName());
    baseLogMessage.setResult(result);
    baseLogMessage.setParameter(getParameter(method, joinPoint.getArgs()));
    baseLogMessage.setSpendTime((int) (endTime - startTime));
    baseLogMessage.setStartTime(endTime);
    LOGGER.info("{}", JsonUtils.objectToJson(baseLogMessage));
    // 数据库存储操作
    return result;
  }
 
  /**
   * 异常返回通知,用于拦截异常日志信息 连接点抛出异常后执行
   *
   * @param joinPoint 切入点
   * @param e     异常信息
   */
  @AfterThrowing(pointcut = "controllerLog()", throwing = "e")
  public void saveExceptionLog(JoinPoint joinPoint, Throwable e) {
    long startTime = System.currentTimeMillis();
    if(null==kafkaClient){
      kafkaClient = KafkaProducerClient.getInstance(systemPropetiesUtil.getKafkaHost());
     //  redisClient= RedisClient.getInstance(systemPropetiesUtil.getReidsHost(), Integer.parseInt(systemPropetiesUtil.getRedisPort()), "");
    }
    // 获取RequestAttributes
    RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
    // 从获取RequestAttributes中获取HttpServletRequest的信息
    HttpServletRequest request = (HttpServletRequest) requestAttributes
        .resolveReference(RequestAttributes.REFERENCE_REQUEST);
    String urlStr = request.getRequestURL().toString();
    BaseLogMessage baseLogMessage = new BaseLogMessage();
    Signature signature = joinPoint.getSignature();
    MethodSignature methodSignature = (MethodSignature) signature;
    Method method = methodSignature.getMethod();
    StringBuffer strbuff = new StringBuffer();
    for (StackTraceElement stet : elements) {
      strbuff.append(stet + "\n");
    }
    String message = exceptionName + ":" + exceptionMessage + strbuff.toString();
    try {
      Object[] args = joinPoint.getArgs();
      String[] parameterNames = methodSignature.getParameterNames();
      long endTime = System.currentTimeMillis();
      baseLogMessage.setUri(urlStr);
      baseLogMessage.setType("异常日志");
      baseLogMessage.setServerIP(getRemoteIP(request));
      baseLogMessage.setMethod(request.getMethod());
      baseLogMessage.setAppName(systemPropetiesUtil.getSysName());
      baseLogMessage.setResult(message);
      baseLogMessage.setParameter(getParameter(method, joinPoint.getArgs()));
      baseLogMessage.setSpendTime((int) (endTime - startTime));
      baseLogMessage.setStartTime(endTime);
      LOGGER.info("{}", JsonUtils.objectToJson(baseLogMessage));
     // 数据库存储操作
    } catch (Exception e2) {
      e2.printStackTrace();
    }
 
  }
 
  /**
   * 根据方法和传入的参数获取请求参数
   */
  private Object getParameter(Method method, Object[] args) {
    List五、 问题
1、如果方法正常执行,不进入AOP类,请检查AOP的切点是否书写正确。
看完上述内容,是不是对Springboot接口项目使用AOP记录日志的方法有进一步的了解,如果还想学习更多内容,欢迎关注创新互联行业资讯频道。
分享标题:Springboot接口项目使用AOP记录日志的方法
标题路径:http://www.scyingshan.cn/article/gcedcd.html

 建站
建站
 咨询
咨询 售后
售后
 建站咨询
建站咨询 
 