實現打印異常日志_老生常談SpringAop日志收集與處理做的工具包

a4c09e7d9aab01bf38c346d4d368355d.png

場景 :

  1. 使用Spring Aop攔截參數日志目前大部分做法都基本上大同小異,不想日后每個項目工程都寫一份這樣的Aop攔截處理日志的代碼,甚至代碼侵入。
  2. 我想知道一些相對重要的請求方法的請求參數,響應參數,請求頭,以及內部耗時,方法是成功還是失敗等等信息。發生錯誤時我也不知道執行到哪一步發生了異常,是不是某個參數導致出的邏輯問題。
  3. 普通的log.info或warn信息沒有所屬請求的上下關系,并不方便查看和分析。
  4. 正式環境中,我并不想打印太多無意義的info日志(有些只是為了排查問題打印的日志,程序正常運行時其實毫無意義),只希望在發生異常時記錄日志或者只希望每次請求只記錄一條關鍵的請求信息。
  5. 日志的收集,我希望將這些請求的日志記錄下來,記錄的實現方式我自己決定,比如正常的日志打印,常見的日志寫入數據庫,日志寫入到文件,日志入隊列等等。
  6. 整個日志的記錄完全不干擾正常請求方法的流程,日志的收集處理異步化,完全不影響正常請求方法的性能與響應。
  7. 只需要通過@AopLog注解決定是否記錄。

快速開始

項目通過maven的pom.xml引入

<dependency>
????<groupId>com.github.ealenxiegroupId>
????<artifactId>aop-logartifactId>
????<version>2.2version>
dependency>

或者通過gradle引入

compile?group:?'com.github.ealenxie',?name:?'aop-log',?version:?'2.2'

@AopLog注解使用,進行日志記錄

直接在類(作用類的所有方法)或類方法(作用于方法)上加上注解@AopLog,進行日志記錄

例如 :

import?com.github.AopLog;
import?name.ealen.infra.base.resp.RespBody;
import?org.springframework.web.bind.annotation.GetMapping;
import?org.springframework.web.bind.annotation.RestController;

/**
?*?@author?EalenXie?create?on?2020/6/22?14:28
?*/
@AopLog(type?=?"測試",stackTraceOnErr?=?true)
@RestController
public?class?AppController?{

????@GetMapping("/app/sayHello")
????public?RespBody?sayHello()?{
????????return?RespBody.ok("hello?EalenXie");
????}

}

自定義全局的日志收集器實現收集 LogCollector

例如只是簡單打印,或寫入到庫等等。

import?com.fasterxml.jackson.core.JsonProcessingException;
import?com.fasterxml.jackson.databind.ObjectMapper;
import?com.github.LogData;
import?com.github.collector.LogCollector;
import?lombok.extern.slf4j.Slf4j;
import?org.springframework.stereotype.Component;

/**
?*?@author?EalenXie?create?on?2020/9/15?13:46
?*?此為樣例參考
?*?配置一個簡單的日志收集器?這里只是做了一個log.info打印一下,可以在這里寫入到數據庫中或者寫入
?*/
@Slf4j
@Component
public?class?AopLogCollector?implements?LogCollector?{
????private?ObjectMapper?objectMapper?=?new?ObjectMapper();
????@Override
????public?void?collect(LogData?logData)?{
????????try?{
????????????log.info(objectMapper.writeValueAsString(logData));
????????}?catch?(JsonProcessingException?e)?{
????????????e.printStackTrace();
????????}
????}
}

配置@Component的全局日志收集器只能配置一個。

接口調用 /say/hello 測試即可看看到控制臺打印出結果 :

2020-09-16?16:01:04.782??INFO?2012?---?[AsyncExecutor-2]?name.ealen.infra.advice.AopLogCollector??:?{"appName":"app-template","host":"127.0.0.1","port":8080,"clientIp":"192.168.110.1","reqUrl":"http://localhost:8080/app/sayHello","httpMethod":"GET","headers":{"User-Agent":"Apache-HttpClient/4.5.10?(Java/11.0.5)"},"type":"測試","content":"","method":"name.ealen.api.facade.AppController#sayHello","args":null,"respBody":{"code":"200","desc":"OK","message":"請求成功","dateTime":"2020-09-16?16:01:04","body":"hello?EalenXie"},"logDate":1600243264780,"costTime":1,"threadName":"http-nio-8080-exec-3","threadId":33,"success":true}

記錄的日志對象LogData屬性說明

「LogData 記錄的內容」

字段類型注釋
appNameString應用名稱
hostString主機
portint端口號
clientIpString請求客戶端的Ip
reqUrlString請求地址
headersObject請求頭部信息(可選擇記錄) 默認記錄user-agent,content-type
typeString操作類型,默認值undefined
contentString方法步驟內容,默認是空,可使用LogData.step進行內容步驟記錄
methodString請求的本地java方法
argsObject方法請求參數
respBodyObject方法響應參數
costTimelong整個方法耗時
logDateDateLog產生時間,LogData對象初始化的時間
threadNameString線程名稱
threadIdlong線程Id
successboolean執行狀態,成功(true)/異常(false)

AopLog 注解選項說明

選項類型說明默認
logOnErrboolean僅當發生異常時才記錄收集false
typeString操作類型默認值"undefined"
headersString[]記錄的header信息 ,選擇要記錄哪些header信息默認"User-Agent","content-type"
argsboolean是否記錄請求參數true
respBodyboolean是否記錄響應參數true
stackTraceOnErrboolean當目標方法發生異常時,是否追加異常堆棧信息到LogData的content中false
asyncModeboolean異步方式收集true
collectorClass extends LogCollector>指定日志收集器默認不調整收集器,使用全局的日志收集器

LogData的step方法。

記錄步驟。(如果某些重要步驟希望被記錄下來) 例如 :

import?com.github.AopLog;
import?com.github.LogData;
import?name.ealen.infra.base.resp.RespBody;
import?org.springframework.web.bind.annotation.GetMapping;
import?org.springframework.web.bind.annotation.RestController;


/**
?*?@author?EalenXie?create?on?2020/6/22?14:28
?*/
@AopLog(type?=?"測試",stackTraceOnErr?=?true)
@RestController
public?class?AppController?{


????@GetMapping("/app/sayHello")
????public?RespBody?sayHello()?{
????????LogData.step("1.?第一步執行完成");
????????//......
????????LogData.step("2.?第二步執行完成");
????????//.....
????????LogData.step("3.?service的方法執行完成");
????????//.....return?RespBody.ok("hello?EalenXie");
????}
}

此時再次接口調用 /say/hello 測試即可看看到控制臺打印出結果,重點觀察content字段 :

2020-09-16?17:26:20.285??INFO?3284?---?[AsyncExecutor-2]?name.ealen.infra.advice.AopLogCollector??:?{"appName":"app-template","host":"127.0.0.1","port":8080,"clientIp":"192.168.110.1","reqUrl":"http://localhost:8080/app/sayHello","httpMethod":"GET","headers":{"User-Agent":"Apache-HttpClient/4.5.10?(Java/11.0.5)"},"type":"測試","content":"1.?第一步執行完成\n2.?第二步執行完成\n3.?service的方法執行完成\n","method":"name.ealen.api.facade.AppController#sayHello","args":null,"respBody":{"code":"200","desc":"OK","message":"請求成功","dateTime":"2020-09-16?17:26:20","body":"hello?EalenXie"},"logDate":1600248380283,"costTime":1,"threadName":"http-nio-8080-exec-2","threadId":32,"success":true}

關于

開源Github地址 : https://github.com/EalenXie/aop-log

作者:風雪漫中州

https://www.cnblogs.com/ealenxie/p/13685216.html

a6a0291d507a06f109208af63c2fe313.png

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/397247.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/397247.shtml
英文地址,請注明出處:http://en.pswp.cn/news/397247.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

服務器128g內存顯示64g,64g內存服務器

64g內存服務器 內容精選換一換華為云幫助中心&#xff0c;為用戶提供產品簡介、價格說明、購買指南、用戶指南、API參考、最佳實踐、常見問題、視頻幫助等技術文檔&#xff0c;幫助您快速上手使用華為云服務。接口名稱GetCloudPhoneServerModelsGetCloudPhoneServerModels功能描…

[LeetCode]--71. Simplify Path

Given an absolute path for a file (Unix-style), simplify it. For example, path “/home/”, > “/home” path “/a/./b/../../c/”, > “/c” click to show corner cases. Corner Cases: Did you consider the case where path “/../”? In this case, …

IOPLL動態重配

連接 Avalon -MM接口 mgmt_waitrequest:當 PLL 重配置進程開始后&#xff0c;此端口變高并在 PLL 重配置期間保持高電平。 PLL 重配置進程完成后&#xff0c;此端口變低。 I/O PLL重配寫操作步驟&#xff1a; 1、 為mgmt_address和mgmt_writedata設置有效值&#xff0c;并且…

android 的屬性動畫

public void zyluoti(View v){ValueAnimator animator ValueAnimator.ofFloat(0,screenHeight - mImageView.getHeight());//設置屬性動畫的值&#xff0c;值的類型為floatanimator.setDuration(1000);//動畫的作用時間animator.setTarget(mImageView);//設置動畫的作用目標an…

qt中如何模擬按鈕點擊_如何快速在 Shopify 中加入按鈕

假如你會 CSS , HTML , JS 三件套&#xff0c;那么修改 Shopify 代碼將不會太難&#xff08;畢竟一個模板中的代碼量還是挺多的&#xff0c;除非深入研究了代碼&#xff0c;不然改起來還是會比較麻煩的&#xff09;。但挺多玩家是不會這三件套的&#xff0c;修改代碼來達到添加…

clear ,refresh,free

itab 即是內表也是工作區的情況下&#xff0c;即with header line. clear itab&#xff0c;僅清空HEADER LINE&#xff0c;對內表數據存儲空間不影響&#xff0c;保留內存區。 refresh itab&#xff0c;不清空HEADER LINE&#xff0c;清除內表數據存儲空間&#xff0c;但保存內…

淺談關于java中的深淺拷貝

一.淺拷貝(shallow copy) 1.如何實現淺拷貝? Object類 是所有類的直接或間接父類,Object中存在clone方法,如下 protected native Object clone() throws CloneNotSupportedException; 如果想要使一個類的對象能夠調用clone方法 ,則需要實現Cloneable接口, 并重寫 clone方法: p…

iOS開發-Protocol協議及委托代理(Delegate)傳值

前言&#xff1a;因為Object&#xff0d;C是不支持多繼承的&#xff0c;所以很多時候都是用Protocol&#xff08;協議&#xff09;來代替。Protocol&#xff08;協議&#xff09;只能定義公用的一套接口&#xff0c;但不能提供具體的實現方法。也就是說&#xff0c;它只告訴你要…

git 查看分支編碼_12個常用的Git命令,趕緊記一波!

今天齊姐簡單講下 Git 的實現原理&#xff0c;知其所以然才能知其然&#xff1b;并且梳理了日常最常用的 12 個命令&#xff0c;分為三大類分享給你。本文的結構如下&#xff1a;作者和開發原由Git 的數據模型常用命令資源推薦作者和開發原由Talk is cheap. Show me the code.這…

在域環境下搭建samba服務器

環境&#xff1a;samba&#xff1a;smbserver&#xff1a; 192.168.0.18AD:rise.com&#xff1a;192.168.0.37組&#xff1a;zixun xingzheng teacher class admin共享目錄:zixun xingzheng xueshu other一.安裝Samba服務器yum install -y samba二.把linux加入到ad中1.先…

Android NDK編程,引入第三方.so庫

android自帶的編譯工具NDK進行編譯時&#xff08;非單純的調用第三方.so而是進行ndk編程&#xff09;&#xff0c;armeabi以及armeabi-v7a文件夾下的第三方so文件將會被刪除&#xff0c;只會產生編譯后的so文件&#xff0c;其他的so文件將無法引入,現在我們就來解決&#xff1a…

會做飯的機器人曰記_顏真卿《麻姑仙壇記》:蒼勁古樸,體態沉雄,氣象宏大...

《麻姑仙壇記》&#xff0c;全稱《有唐撫州南城縣麻姑山仙壇記》&#xff0c;或稱《麻姑山仙壇記》。顏真卿撰并書于大歷六年&#xff08;771&#xff09;四月。此碑有大、中、小三種刻本&#xff0c;且原石均佚&#xff0c;原拓佳本亦難得。大字本&#xff0c;字徑約5厘米&…

IBM服務器硬盤出現Other Error可能原因

除了確實物理等因素外&#xff0c;可能還因為&#xff1a;Other Errors的 很有可能也是固件(firmware)版本太低造成。 固件版本太低的話&#xff0c;硬盤自身有power safe模式&#xff0c;在硬盤長時間沒有I/O情況下&#xff0c;硬盤會自動斷電&#xff0c;而系統本身誤以為是硬…

怪異模式

眾所周知,HTML文檔結構可分為:文檔聲明<!DOCTYPE HTML>、HTML元素&#xff08;根元素/根標記/根標簽/祖先元素&#xff09;、head元素、body元素。 文檔聲明是用來通知瀏覽器&#xff0c;目前的文檔正使用哪個HTML版本&#xff0c;如果我們不寫文檔聲明<!DCOTYPE HTML…

Metro UI 菜單(Winform)

我有個項目需要要到菜單導航&#xff0c;就自己動作做了一個&#xff0c;感覺還可以&#xff0c;分享給大家。下載地址:http://files.cnblogs.com/files/dyj057/MetroUIMenu.zip 主要代碼&#xff1a; private void SetElements(){if (Elements null) return;int eWidth Bord…

echarts 山東地圖_用Python畫中國地圖,實現各省份數據可視化

第一步&#xff1a;安裝pyechartspyecharts是一款將python與echarts結合的強大的數據可視化工具&#xff0c;本文使用了0.1.9.4版本pip install pyecharts0.1.9.4第二步&#xff1a;讀取數據我的數據是在Excel表格里&#xff0c;如下圖&#xff1a;Execel數據使用xlrd(沒有就通…

mysql 中某個字段相同的數據拼接起來

2019獨角獸企業重金招聘Python工程師標準>>> mysql> select name, GROUP_CONCAT( age SEPARATOR ‘#’) from student group by name; ——————————————————— | name | GROUP_CONCAT( age SEPARATOR ‘#’) | ———————————————…

微信紅包系統架構的設計和優化分享

微信紅包系統架構的設計和優化分享 編者按&#xff1a;經過2014年一年的醞釀&#xff0c;2015微信紅包總量創下歷史新高&#xff0c;峰值1400萬次/秒&#xff0c;8.1億次每分鐘&#xff0c;微信紅包收發達10.1億次&#xff0c;系統整體運行平穩, 在這里我分享下微信紅包背后的技…

Jquery各版本下載

jquery-2.1.4 (注&#xff01;jquery-2.0以上版本不再支持IE 6/7/8) 百度引用地址 (推薦目前最穩定的&#xff0c;不會出現延時打不開情況) 百度壓縮版引用地址: <script src"http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script> 微軟壓縮版引…

python list方法操作_Python 列表(List)操作方法詳解

參考文獻來源于腳本之家列表是Python中最基本的數據結構&#xff0c;列表是最常用的Python數據類型&#xff0c;列表的數據項不需要具有相同的類型。列表中的每個元素都分配一個數字 - 它的位置&#xff0c;或索引&#xff0c;第一個索引是0&#xff0c;第二個索引是1&#xff…