摘要:接口日志有啥用在我們日常的開發過程中,我們可以通過接口日志去查看這個接口的一些詳細信息。在切入點返回內容之后切入內容可以用來對處理返回值做一些加工處理。
接口日志有啥用
在我們日常的開發過程中,我們可以通過接口日志去查看這個接口的一些詳細信息。比如客戶端的IP,客戶端的類型,響應的時間,請求的類型,請求的接口方法等等,我們可以對這些數據進行統計分析,提取出我們想要的信息。
怎么拿到接口日志這里,我們使用的是Spring的兩大殺器之AOP,通過在Controller層定義切點,然后對請求對象進行分析獲取接口信息,同時開啟一個ThreadLocal來記錄響應時間。
關于AOP的注解@Aspect:將一個類定義為切面類。
@Pointcut:定義一個切入點。
@Before:在切入點開始處切入內容。
@After:在切入點結尾處切入內容。
@AfterReturning:在切入點返回內容之后切入內容(可以用來對處理返回值做一些加工處理。
@Around:在切入點前后切入內容,并自己控制何時執行切入點自身的內容
@AfterThrowing:用來處理當切入內容部分拋出異常之后的處理邏輯。
@Order:在切入點前的操作,按order的值由小到大執行;在切入點后的操作,按order的值由大到小執行。
實戰應用 一:引入依賴首先,我們需要新增引入aop的依賴,以及用于分析客戶端信息的UserAgentUtils包,還有用于@Slf4j打印日志的Lombok的包:
二:定義一個ResponseAop切面類org.springframework.boot spring-boot-starter-aop eu.bitwalker UserAgentUtils 1.20
在之前的統一返回值和異常處理中我們已經定義過這個類,這里是對其進行完善。這里我再把代碼再寫一下:
@Aspect @Order(5) @Component @Slf4j public class ResponseAop三:定義一個ThreadLocal變量
直接在這里定義基本類型會有同步問題,所以我們定義一個ThreadLocal對象來記錄消耗的時間。
ThreadLocal四:定義切點startTime = new ThreadLocal<>();
這里需要注意的是切點的寫法,一定要正確才能保證AOP生效!這里附上一些簡單的寫法,后續會多帶帶開一章講解execution表達式的書寫。
任意公共方法:
execution(public * *(..))
任何一個以“set”開始的方法的執行:
execution(* set*(..))
Service接口的任意方法的執行:
execution(* com.xyz.service.Service.*(..))
定義在service包里的任意方法的執行:
execution(* com.xyz.service.*.*(..))
定義在service包和所有子包里的任意類的任意方法的執行:
execution(* com.xyz.service..*.*(..))
/** * 切點 */ @Pointcut("execution(public * indi.viyoung.viboot.*.controller..*(..))") public void httpResponse() { }五:在@Before中獲取請求信息
@Before("httpResponse()") public void doBefore(JoinPoint joinPoint){ //開始計時 startTime.set(System.currentTimeMillis()); ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); //打印請求的內容 UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));//獲取請求頭中的User-Agent log.info("接口路徑:{}" , request.getRequestURL().toString()); log.info("瀏覽器:{}", userAgent.getBrowser().toString()); log.info("瀏覽器版本:{}",userAgent.getBrowserVersion()); log.info("操作系統: {}", userAgent.getOperatingSystem().toString()); log.info("IP : {}" , request.getRemoteAddr()); log.info("請求類型:{}", request.getMethod()); log.info("類方法 : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); log.info("請求參數 : {} " + Arrays.toString(joinPoint.getArgs())); }六:在@AfterReturning中獲取方法的返回值和執行時間
@AfterReturning(returning = "ret" , pointcut = "httpResponse()") public void doAfterReturning(Object ret){ //處理完請求后,返回內容 log.info("方法返回值:{}" , ret); log.info("方法執行時間:{}毫秒", (System.currentTimeMillis() - startTime.get())); }七:測試結果
下面,我們對一個接口進行訪問:
2019-02-21 21:03:31.358 INFO 11788 --- [nio-8090-exec-5] indi.viyoung.viboot.aop.ResponseAop : 接口路徑:http://localhost:8090/users 2019-02-21 21:03:31.359 INFO 11788 --- [nio-8090-exec-5] indi.viyoung.viboot.aop.ResponseAop : 瀏覽器:CHROME 2019-02-21 21:03:31.359 INFO 11788 --- [nio-8090-exec-5] indi.viyoung.viboot.aop.ResponseAop : 瀏覽器版本:72.0.3626.109 2019-02-21 21:03:31.360 INFO 11788 --- [nio-8090-exec-5] indi.viyoung.viboot.aop.ResponseAop : 操作系統: MAC_OS_X 2019-02-21 21:03:31.360 INFO 11788 --- [nio-8090-exec-5] indi.viyoung.viboot.aop.ResponseAop : IP : 0:0:0:0:0:0:0:1 2019-02-21 21:03:31.360 INFO 11788 --- [nio-8090-exec-5] indi.viyoung.viboot.aop.ResponseAop : 請求類型:GET 2019-02-21 21:03:31.360 INFO 11788 --- [nio-8090-exec-5] indi.viyoung.viboot.aop.ResponseAop : 類方法 : indi.viyoung.viboot.apilog.controller.UserController.findAll 2019-02-21 21:03:31.360 INFO 11788 --- [nio-8090-exec-5] indi.viyoung.viboot.aop.ResponseAop : 請求參數 : {} [] ... 2019-02-21 21:03:31.393 INFO 11788 --- [nio-8090-exec-5] indi.viyoung.viboot.aop.ResponseAop : 方法返回值:ReturnVO{code="2000", message="操作成功", data=[User(id=10000001, password=123456, userName=vi-young), User(id=10000002, password=123456, userName=vi-young), User(id=10000003, password=123123, userName=lxt), User(id=10000004, password=123456, userName=yangwei)]} 2019-02-21 21:03:31.393 INFO 11788 --- [nio-8090-exec-5] indi.viyoung.viboot.aop.ResponseAop : 方法執行時間:36毫秒
可以看出,我們已經獲取到我們想要的信息~
在后面的應用實戰中,我們會將這些信息保存到數據庫中,并且使用一些數據分析工具進行分析。
公眾號您的推薦是對我最大的幫助!
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/75858.html
摘要:前言如題,今天介紹的數據緩存。說明確實做了數據緩存,第二次的測試結果是從數據緩存中獲取的,并沒有直接查數據庫。為為的數據做了緩存插入數據返回的結果數據庫中的結果訪問結果如下圖。后語以上為數據緩存的教程。 微信公眾號:一個優秀的廢人如有問題或建議,請后臺留言,我會盡力解決你的問題。 前言 如題,今天介紹 SpringBoot 的數據緩存。做過開發的都知道程序的瓶頸在于數據庫,我們也知道內...
showImg(https://segmentfault.com/img/remote/1460000018819338?w=1024&h=500); 在開發項目中,我們經常會需要打印日志,這樣方便開發人員了解接口調用情況及定位錯誤問題,很多時候對于Controller或者是Service的入參和出參需要打印日志,但是我們又不想重復的在每個方法里去使用logger打印,這個時候希望有一個管理者統一...
摘要:簡介項目基于的前后端分離的管理系統,項目采用分模塊開發方式,權限控制采用,基于角色的訪問控制,支持數據字典數據權限管理前端菜單支持動態路由,另外還有其他的功能模塊日志管理代碼生成器系統監控云存儲管理系統工具等等。 簡介 項目基于 Spring Boot 2.1.0 、 Spring Data JPA、 Spring Security、Redis、Vue的前后端分離的管理系統,項目采用分...
閱讀 1733·2021-11-24 10:18
閱讀 2207·2021-11-18 13:20
閱讀 2332·2021-08-23 09:46
閱讀 992·2019-08-30 15:56
閱讀 2840·2019-08-30 15:53
閱讀 738·2019-08-30 14:22
閱讀 470·2019-08-29 15:34
閱讀 2532·2019-08-29 12:14