改造 cronet 庫使得 安卓 release SDK 可以捕獲 cronet 庫 QUIC 相關日誌實踐

1、背景介紹

在我們移動端文件上傳場景中,嘗試使用 QUIC 協議來優化上傳效果,爲了準確的分析上傳失敗的任務,需要建立上傳任務與 QUIC 連接的關聯性;

當前每個上傳任務結束時,或失敗或成功都會上報一條日誌,我們打算在啓用了 QUIC 的上傳任務中,增加一個字段保存 QUIC 相關信息,比如連接 ID、連接建立的日誌、連接關閉的日誌等,QUIC 連接關閉時會帶上詳細的關閉原因,幫助分析 QUIC 失敗時客戶端的狀態,實現效果如下圖,兩條 APM 日誌:

在服務端我們使用 Caddy 轉發業務流量,Caddy 併發處理所有請求,因此各個請求的日誌混在在一起,如果不對同一請求的日誌加上唯一性標誌,服務端對日誌就失去了作用,而不同 QUIC 請求可以使用連接 ID 來標識;

爲了把各個 QUIC 連接對應的日誌關聯起來,我們修改了 Caddy 源碼,將 INFO、DEBUG 級別的每條日誌加上了連接 ID,這需要修改 lucas-clemente/quic-go/interface.go 中 Session 接口,增加返回連接 ID 的方法,這樣邊能在每條日誌輸出時加上連接 ID,效果見下圖,修改的日誌用中括號將連接 ID 框起:

2、方案分析

cronet 庫本身有調試日誌,但數量太多,而且 release 版本不會輸出這些日誌,cronet 庫使用的 chromium 網絡棧,因此 QUIC 的日誌可以使用 base::logging 來輸出,它支持回調、輸出到文件等方式,寫文件要控制的細節太多,比如什麼時候上傳、如果日誌上報失敗怎麼處理等問題;最後我們採取的方案是回調。

比如安卓實現的時候,Java 層會通過 JNI 層註冊回調函數,該回調函數會將 base::logging 捕獲的日誌上報 APM,註冊時會通過 JNI 層的方法向 base::logging 註冊 C++ 層的回調方法,該回調方法負責將捕獲的日誌通過 JNI 層傳遞到 Java 層的回調函數,C++ 層註冊回調方法的接口爲 logging::SetLogMessageHandler。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章