最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Springboot接口項(xiàng)目如何使用AOP記錄日志

 更新時(shí)間:2020年06月03日 10:44:28   作者:畫筆灬  
這篇文章主要介紹了Springboot接口項(xiàng)目如何使用AOP記錄日志,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下

一、 背景

一直想給項(xiàng)目構(gòu)建一個(gè)統(tǒng)一的日志收集系統(tǒng),先邁出第一步,構(gòu)建一個(gè)日志收集類,用AOP實(shí)現(xiàn)無侵入日志收集

二、 環(huán)境

1.此隨筆內(nèi)容基于spring boot項(xiàng)目

2.數(shù)據(jù)庫為mysql 5.7.9版本

3.jdk 版本為1.8

三、 說明

此版采用數(shù)據(jù)庫存儲,之后考慮使用elasticsearch等工具存儲

四、 內(nèi)容

1、構(gòu)建日志采集實(shí)體類: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、構(gòu)建一個(gè)配置文件讀取類,用于讀取配置文件中的系統(tǒng)名稱:SystemPropetiesUtil

@Configuration
public class SystemPropetiesUtil {
  @Value("${spring.application.name}")
  private String sysName;//系統(tǒng)名稱<br>  // 此處省略get、set<br>}

3、新建一個(gè)AOP類,在控制器方法上作為切點(diǎn),執(zhí)行日志收集: LogAspect

@Aspect
@Component
public class LogAspect {
  @Autowired
  private SystemPropetiesUtil systemPropetiesUtil;
 
  //定義切點(diǎn)方法
  @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();
    //獲取當(dāng)前請求對象
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();
    //記錄請求信息
    BaseLogMessage baseLogMessage = new BaseLogMessage();
    //1.獲取到所有的參數(shù)值的數(shù)組
    Object[] args = joinPoint.getArgs();
    Signature signature = joinPoint.getSignature();
    MethodSignature methodSignature = (MethodSignature) signature;
    //2.獲取到方法的所有參數(shù)名稱的字符串?dāng)?shù)組
    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));
    // 數(shù)據(jù)庫存儲操作
    return result;
  }
 
  /**
   * 異常返回通知,用于攔截異常日志信息 連接點(diǎn)拋出異常后執(zhí)行
   *
   * @param joinPoint 切入點(diǎn)
   * @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));
     // 數(shù)據(jù)庫存儲操作
    } catch (Exception e2) {
      e2.printStackTrace();
    }
 
  }
 
  /**
   * 根據(jù)方法和傳入的參數(shù)獲取請求參數(shù)
   */
  private Object getParameter(Method method, Object[] args) {
    List<Object> argList = new ArrayList<>();
    Parameter[] parameters = method.getParameters();
    for (int i = 0; i < parameters.length; i++) {
     
      RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
      if (requestBody != null) {
        argList.add(args[i]);
      }
      RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
      if (requestParam != null) {
        Map<String, Object> map = new HashMap<>();
        String key = parameters[i].getName();
        if (!StringUtils.isEmpty(requestParam.value())) {
          key = requestParam.value();
        }
        map.put(key, args[i]);
        argList.add(map);
      }
    }
    if (argList.size() == 0) {
      return null;
    } else if (argList.size() == 1) {
      return argList.get(0);
    } else {
      return argList;
    }
  }
 /**
   * 獲取請求ip
   */
  public static String getRemoteIP(HttpServletRequest request) {
    String ip =null;
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getHeader("X-Forwarded-For");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getHeader("Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
      ip = request.getRemoteAddr();
    }
    if (ip != null) {
      //對于通過多個(gè)代理的情況,最后IP為客戶端真實(shí)IP,多個(gè)IP按照','分割
      int position = ip.indexOf(",");
      if (position > 0) {
        ip = ip.substring(0, position);
      }
    }
    return ip;
  }
}  

五、 問題

1、如果方法正常執(zhí)行,不進(jìn)入AOP類,請檢查AOP的切點(diǎn)是否書寫正確。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 如何用Spring發(fā)送電子郵件

    如何用Spring發(fā)送電子郵件

    這篇文章主要介紹了如何用Spring發(fā)送電子郵件,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-02-02
  • Java Servlet輸出中文亂碼問題解決方案

    Java Servlet輸出中文亂碼問題解決方案

    這篇文章主要介紹了Java Servlet輸出中文亂碼問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Hadoop之NameNode Federation圖文詳解

    Hadoop之NameNode Federation圖文詳解

    今天小編就為大家分享一篇關(guān)于Hadoop之NameNode Federation圖文詳解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • java實(shí)現(xiàn)單鏈表中的增刪改

    java實(shí)現(xiàn)單鏈表中的增刪改

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)單鏈表中的增刪改,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 簡單了解mybatis攔截器實(shí)現(xiàn)原理及實(shí)例

    簡單了解mybatis攔截器實(shí)現(xiàn)原理及實(shí)例

    這篇文章主要介紹了簡單了解mybatis攔截器實(shí)現(xiàn)原理及實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 在Mybatis中使用自定義緩存ehcache的方法

    在Mybatis中使用自定義緩存ehcache的方法

    這篇文章主要介紹了在Mybatis中使用自定義緩存ehcache的方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Java實(shí)現(xiàn)從jar包中讀取指定文件的方法

    Java實(shí)現(xiàn)從jar包中讀取指定文件的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)從jar包中讀取指定文件的方法,涉及java針對jar文件的讀取及查找相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • Java多線程中的Callable和Future詳解

    Java多線程中的Callable和Future詳解

    這篇文章主要介紹了Java多線程中的Callable和Future詳解,創(chuàng)建線程的兩種方式,一種是直接繼承Thread,另外一種就是實(shí)現(xiàn)Runnable接口,本文提供了部分代碼,需要的朋友可以參考下
    2023-08-08
  • Spring spel表達(dá)式使用方法示例

    Spring spel表達(dá)式使用方法示例

    這篇文章主要介紹了Spring spel表達(dá)式使用方法示例,通過一些實(shí)例向大家展示了spel表達(dá)式的用法,需要的朋友可以了解下。
    2017-09-09
  • SpringBoot2線程池定義使用方法解析

    SpringBoot2線程池定義使用方法解析

    這篇文章主要介紹了SpringBoot2線程池定義使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-03-03

最新評論

天峻县| 涿州市| 宝丰县| 南康市| 达日县| 东源县| 通化市| 台前县| 称多县| 长春市| 广德县| 广昌县| 云安县| 望江县| 贵德县| 八宿县| 沙河市| 左权县| 长葛市| 顺昌县| 永丰县| 扎兰屯市| 千阳县| 浦县| 同仁县| 濉溪县| 丁青县| 大石桥市| 云南省| 牙克石市| 隆德县| 鹤岗市| 郸城县| 桂林市| 姜堰市| 柘城县| 中方县| 陕西省| 陵川县| 夏河县| 东源县|