如何在zuul上做日誌處理
由於zuul作為api閘道器,所有的請求都經過這裡,所以在閘道器上,可以做請求相關的日誌處理。
我的需求是這樣的,需要記錄請求的 url,ip地址,引數,請求發生的時間,整個請求的耗時,請求的響應狀態,
甚至請求響應的結果等。
很顯然,需要實現這樣的一個功能,需要寫一個ZuulFliter,它應該是在請求傳送給客戶端之前做處理,並且在
route過濾器路由之後,在預設的情況下,這個過濾器的order應該為500-1000之間。那麼如何獲取這些我需要的
日誌資訊呢?找RequestContext,在請求的生命週期裡這個物件裡,儲存了整個請求的所有資訊。
瞭解springcloud架構可以加求求:三五三六二四七二五九
現在編碼,在程式碼的註釋中,做了詳細的說明,程式碼如下:
@Component public class LoggerFilter extends ZuulFilter { @Override public String filterType() { return FilterConstants.POST_TYPE; } @Override public int filterOrder() { return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext context = RequestContext.getCurrentContext(); HttpServletRequest request = context.getRequest(); String method = request.getMethod();//氫氣的型別,post get .. Map<String, String> params = HttpUtils.getParams(request); String paramsStr = params.toString();//請求的引數 long statrtTime = (long) context.get("startTime");//請求的開始時間 Throwable throwable = context.getThrowable();//請求的異常,如果有的話 request.getRequestURI();//請求的uri HttpUtils.getIpAddress(request);//請求的iP地址 context.getResponseStatusCode();//請求的狀態 long duration=System.currentTimeMillis() - statrtTime);//請求耗時 return null; } }
現在讀者也許有疑問,如何得到的statrtTime,即請求開始的時間,其實這需要另外一個過濾器,在網路請求route之前(大部分耗時都在route這一步),在過濾器中,在RequestContext儲存一個時間即可,另寫一個過濾器,程式碼如下:
@Component public class AccessFilter extends ZuulFilter { @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext ctx = RequestContext.getCurrentContext(); ctx.set("startTime",System.currentTimeMillis()); return null; } }
可能還有這樣的需求,我需要將響應結果,也要儲存在log中,在之前已經分析了,在route結束後,將從具體服務獲取的
響應流儲存在RequestContext中,在SendResponseFilter過濾器寫入在HttpServletResponse中,最終返回給客戶端。那麼我只需要在SendResponseFilter寫入響應流之前把響應流寫入到 log日誌中即可,那麼會引發另外一個問題,因為響應流寫入到 log後,RequestContext就沒有響應流了,在SendResponseFilter就沒有流輸入到HttpServletResponse中,導致客戶端沒有任何的返回資料,那麼解決的辦法是這樣的:
InputStream inputStream =RequestContext.getCurrentContext().getResponseDataStream(); InputStream newInputStream= copy(inputStream); transerferTolog(inputStream); RequestContext.getCurrentContext().setResponseDataStream(newInputStream);
從RequestContext獲取到流之後,首先將流 copy一份,將流轉化下字串,存在日誌中,再set到RequestContext中,
這樣SendResponseFilter就可以將響應返回給客戶端。這樣的做法有點影響效能,如果不是字元流,可能需要做更多的處理工作。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69952307/viewspace-2676257/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 對 Hyperf 做的那些事 3(日誌處理)
- shell日誌顏色處理
- orbeon form 的日誌處理ORBORM
- node錯誤處理與日誌
- DATAGUARD中手工處理日誌GAP
- ELK 處理 Spring Boot 日誌,不錯!Spring Boot
- 搭建node服務(1):日誌處理
- SpringBoot第十三篇:日誌處理Spring Boot
- 指令碼處理iOS的Crash日誌指令碼iOS
- 利用 ELK 處理 Percona 審計日誌
- 基於go開發日誌處理包Go
- node專案錯誤處理與日誌
- SQLServer資料庫日誌太大處理方式SQLServer資料庫
- logback下日誌輸出前處理操作——以日誌脫敏為例
- 『無為則無心』Python日誌 — 67、logging日誌模組處理流程Python
- 如何在iOS手機上檢視應用日誌iOS應用日誌
- Spark SQL:實現日誌離線批處理SparkSQL
- 從0寫一個Golang日誌處理包Golang
- Oracle DataGuard歸檔日誌丟失處理方法Oracle
- ES & Filebeat 使用 Pipeline 處理日誌中的 @timestamp
- SpringBoot部落格開發之AOP日誌處理Spring Boot
- 結合 AOP 輕鬆處理事件釋出處理日誌事件
- 如何在 Linux 中管理日誌Linux
- 基於flink和drools的實時日誌處理
- syslog強大而安全的日誌處理系統
- Golang 快速讀取處理大日誌檔案工具Golang
- ORACLE 11G DATAGUARD 日誌中斷處理方案Oracle
- 使用Kafka做日誌收集Kafka
- 日誌伺服器搭建之多伺服器日誌轉發與格式化處理伺服器
- PG啟動流程StartupXlog函式回放日誌前處理函式
- SQLServer 2008中事務日誌已滿問題處理SQLServer
- mysqlbinlog 處理二進位制日誌檔案的工具MySql
- alert日誌中出現Private Strand Flush Not Complete的處理方法
- 同步伺服器日誌到 SeaTable,讓日誌更好的視覺化和協同處理伺服器視覺化
- 如何在程式碼中打日誌
- SpringBoot開發案例構建分散式日誌處理系統Spring Boot分散式
- scrapy處理post請求的傳參和日誌等級
- 體面編碼之異常日誌和測試處理