Categories
程式開發

美團開源Logan Web:前端日誌在Web端的實現


1. 前言

Logan 是美團點評推出的大前端日誌系統,支持多端環境運行,可為客戶端、Web、小程序等用戶端環境提供前端日誌的存儲、收集、上報及分析能力,能夠幫助開發人員快速定位並解決端上問題,便於及時響應用戶反饋與排除異常。

  • 2018 年 10 月,Logan 在社區開源了 Android 與 iOS 端的 SDK,實現了在客戶端進行日誌存儲及上報代碼的功能,引起用戶端相關開發者的廣泛關注。詳細可參見博客文章:《Logan:美團點評的開源移動端基礎日誌庫》。
  • 2019 年12 月12 日,Logan 開源了在Web 環境運行的SDK、日誌分析平台以及服務端代碼,為開發者們提供了Logan 大前端日誌系統的一整套實現方案,進一步解決了多端環境中日誌的存儲與採集問題。

本文將圍繞 Logan 在 Web 端的應用背景、技術實現、美團點評的實踐、開源整體進展以及未來規劃這幾個方面展開介紹,以方便讀者對 Logan 大前端日誌系統有更加深入的了解。

Logan 項目地址:

https://github.com/Meituan-Dianping/Logan

2. 背景

2.1 為何需要 Logan?

在 Logan 誕生前,用戶端開發者在面對用戶反饋頁面功能異常時,最常說的靈魂三答是:

美團開源Logan Web:前端日誌在Web端的實現 1

這三條回答分別對應著開發者在解決端上問題時的心路歷程:

  • “啥問題”:通過與用戶溝通,獲取異常發生前後過程的詳細描述,嘗試在開發者本地模擬,以期復現問題。
  • “我這裡看是好的”:問題沒有復現,應該是用戶端兼容性的 Bug。
  • “你重啟下”:想不出修復的辦法,只能“死馬當活馬醫”,碰碰運氣。

對用戶端的開發者來說,本地無法復現的問題好比“斷了線的風箏”,讓人無計可施。如果有辦法獲取到事發時完整的日誌流以及用戶環境的上下文信息,就能夠幫助開發者快速了解並還原問題的發生現場,可以更有效地定位排查問題,讓風箏最終被拉回到開發者手裡。正是因為這樣的迫切需要,Logan 大前端日誌系統才應運而生。

2.2 Logan 日誌系統的策略與核心

2.2.1 Logan 在各端實行的通用策略

雖然用戶端上完整的日誌流及上下文環境信息更有助於開發者定位到問題,但對每個用戶端的日誌流都進行實時上報的話,也會出現如下問題:

  • 巨大開銷:耗費用戶流量,佔用企業帶寬與服務器存儲資源。
  • 大海撈針:在海量日誌中可能只有極少部分的日誌能夠幫助復現問題。

因此 Logan 在各端上實行的通用策略,是本地日誌存儲結合觸發上報的模式,如流程圖所示:

美團開源Logan Web:前端日誌在Web端的實現 2

a 平時在用戶端腳本執行過程中產生的日誌會落地到本地的存儲容器中。

b 當遇到用戶反饋或者端上異常被捕獲時,Logan 以特定機制觸發本地日誌的上報。

c 本地日誌流將在用戶端上傳,由服務端收集並解析,最後上傳至雲端存儲。

d 由 Logan 統一的日誌分析平台向開發者提供日誌數據的可視化展示。

e 開發者利用 Logan 日誌排查定位並解決問題後,向用戶反饋或者排除異常。

2.2.2 Logan 的三大核心

上文所闡述的 Logan 通用策略中的工作流程也決定了 Logan 日誌系統擁有三大核心:

  • 用戶端 SDK(客戶端版、Web 版及小程序版):負責存儲與上報端上日誌。
  • 服務器端:負責接收、解析、整合與分析日誌。
  • 日誌分析平台:提供日誌的查詢與數據可視化展示。

2.3 Logan 在 Web 端面臨的問題

在 Web 環境中若要實現端上日誌存儲及上報需要解決三大難點:

  • 如何存儲?需要解決 Web 本地大體積日誌流的存取。
  • 如何保障日誌安全?在本地已存儲的日誌需要有數據安全保障。
  • 如何上報?需要有效的機制觸發日誌的上報。

2.4 Logan Web 做了什麼?

Logan Web 是 Logan 在 Web 端的存儲及上報實現方案,利用現有的前端技術加以優化與整合,有效地解決了 Web 端面臨的三大難點。我們將存儲與上報的實現封裝在 Web 端的 SDK 內,開發者只需在頁面腳本中引入該 SDK,便可直接使用 Logan 在 Web 端上的日誌安全存儲與上報能力。

下面將重點圍繞存儲方案、數據安全及上報機制這三點,具體闡述 Logan Web 目前的技術實現。

3. 技術實現

Logan Web 在底層利用了現有前端技術來實現大體積日誌的安全存儲:

  • 存儲方面:利用瀏覽器的 IndexedDB 作為本地日誌的大容量存儲容器。
  • 日誌安全方面:使用混合加密模式確保本地已存的隱私日誌數據不會被破解。

Logan 為 Web 開發者提供了 logan-web 這個 SDK 包,其內部主要分為存儲與上報兩大核心模塊,底層依賴了 IndexedDB 存儲與加密組件。開發者可在頁面腳本中引入並加載該 SDK 來調用日誌存儲或上報接口。

3.1 Logan Web 整體技術架構

以下是 Logan Web 的整體架構示意圖:

美團開源Logan Web:前端日誌在Web端的實現 3

a logan-web 提供了一個入口文件,它將在日誌存儲方法或者日誌上報方法被觸發時,異步地獲取存儲或上報模塊。

b 存儲模塊中會優先處理日誌內容的加密及包裝,再執行後續的分頁存儲流程。

c 上報模塊會分頁讀取指定天的日誌數據,並行上報至接收日誌的服務端,進行後續的日誌解析、解密、整合及分析。

d 這兩大核心模塊都會使用 Logan DB 模塊封裝的日誌存取邏輯,該模塊還會控製本地日誌數據的存儲容量以及日誌分頁。

對 IndexedDB API 的調用被封裝在獨立於 logan-web 的 idb-managed 包中,該包主要解決在使用 IndexedDB 進行本地存儲時遇到的技術挑戰。

3.2 本地存儲方案:idb-managed

3.2.1 原生 IndexedDB API 的局限

IndexedDB 支持大容量存儲,並且其讀取操作是異步化的,非常適合作為 Logan Web 的本地存儲容器。但 IndexedDB API 在使用上會遇到如下幾個問題:

(1)DB 版本升級問題

本地 DB 依靠版本的升級來更新庫表結構,當本地該 DB 的版本升級後,嘗試連接低版本 DB 的操作將失敗。

美團開源Logan Web:前端日誌在Web端的實現 4

(2)獲取 DB 數據前需要設置 DB 版本及庫表信息

獲取DB 數據前需要首先連接DB,如果連接時沒有設置恰當的庫表信息,下一次存儲時依然以同版本建立連接,IndexedDB 則不再更新該DB 的庫表結構,最終會因為存儲數據不匹配表結構而導致存儲失敗。

美團開源Logan Web:前端日誌在Web端的實現 5

(3)IndexedDB 不提供數據的時效設置與過期數據清理

IndexedDB 默認數據是持久化落地的,儘管它的可用容量遠大於LocalStorage,但在像Logan Web 這樣需要隨時間不斷更新本地數據的使用場景下,就需要一套隨時間迭代的數據更新機制來“除舊存新”。

(4)原生 IndexedDB API 不提供多表間的原子性增刪操作

原生的IndexedDB API 只提供了單條數據的添加,以及單表內的數據批量刪除操作,並不直接提供API 對多表的數據進行添加或者刪除的原子性操作( 要么全部生效,要么全不生效) 。 Logan DB 的庫表結構涉及到兩張表數據間的聯動,需要多表間原子性增刪來保證日誌數據在兩張表間保持一致。

3.2.2 idb-managed 的​​解決手段

為了統一解決以上在使用 IndexedDB 時面臨的困擾,我們額外封裝了 idb-managed 包,該包隨著 Logan Web 一起開源。

idb-managed 中分別針對:

  • 問題 1 與 2:提出並實現了 DB Manager 機制來解決 DB 版本升級與數據獲取的困境。
  • 問題 3:封裝了對存儲數據的時效設置、過期處理邏輯。
  • 問題 4:利用事務回滾方法實現在多表內的原子性增刪操作。

(1)DB Manager 機制

idb-managed 中內建了一個 DB Manager 來管理當前所有本域下的 DB 版本與庫表結構信息,其實 DB Manager 自身就是一個版本號固化的 DB,它本身不存在升級問題。建立連接示意圖如下:

美團開源Logan Web:前端日誌在Web端的實現 6

當對一個新 DB 建立連接時,會將腳本中設置的 DB 版本及庫表信息註冊到 DB Manager 中並把數據存儲下來。下一次如果有該 DB 的低版本嘗試連接時,DB Manager 會用當前已註冊的庫表信息連接並打開 DB,由此避免了 DB 升級而導致連接低版本失敗的問題 。

同時,因為有 DB Manager 來統一管理本地的 DB 信息,所以從 DB 獲取數據可以無需知曉 DB 庫表結構,只需要 DB 名和表名即可。當本地庫表不存在時,DB Manager 會阻止對該 DB 的連接,直接返回空數據,避免了錯誤的庫表結構污染本地 DB。

(2)數據時效控制

idb-managed 會為每張表建立一個到期時間索引,開發者可對單條數據、單個表或者單個庫設置一個持久化時間限制,在數據存儲時idb-managed 會根據這些限制及優先級順序(單條> 單表> 單庫)計算該條數據的到期時間,並與數據一起保存下來,過期的數據會在該表下一次添加數據時先行刪除。

(3)多表間原子性增刪操作

IndexedDB 中數據的增刪操作全部建立在事務(IDBTransaction)基礎之上,idb-managed 封裝了多表批量數據的增刪操作接口,並將這些操作包裹在一次事務內。如果在一次事務中發生異常,idb-managed 將執行本次事務的回滾,從而保證這批操作具有原子性。

3.3 日誌加密方案:混合加密

混合加密方式吸取了對稱加密與非對稱加密各自的優勢:

  • 對稱加密:保證對長內容加密的效率。
  • 非對稱加密:保證對稱密鑰的安全性。

Logan Web 選擇了 AES-128-CTR 結合 RSA-1024 的混合加密模式。在存儲每條具有私密性的日誌前都會經歷以下加密流程:

a 準備對稱密鑰與初始向量:隨機產生 AES 對稱密鑰 AES Key 及初始向量 IV。

b 對稱加密:使用 AES Key 及 IV 對日誌明文進行 AES-CTR 對稱加密,得到日誌密文。

c 非對稱加密 AES Key:使用 RSA 公鑰對 AES Key 進行非對稱加密,得到 AES Key 密文。該 RSA 公鑰與服務器端的私鑰是成套的,只有該私鑰可以解開該 AES Key 密文,從而解開日誌密文。

d 包裝數據:將以上初始向量、日誌密文與 AES Key 密文包裝成一條日誌對象,隨後存儲落地。

美團開源Logan Web:前端日誌在Web端的實現 7

3.4 上報的觸發機制

用戶端的日誌上報觸發機制一般分為兩大類:

  • 用戶主動觸發。優點是上報的日誌能夠對應到用戶反饋的個案;缺點是存在交互上的用戶教育成本,同時依賴用戶反饋的異常處理流程,過於滯後。
  • 代碼層面觸發。優點是用戶無需感知上報流程;缺點是可能存在大量“無幫助”的上報日誌,需要對觸發條件做好頻率控制。

Logan Web 在兩類方式上提供了配置與接口,供 SDK 使用方自行選擇與擴展,例如:

(1)用戶主動觸發

  • PC 端:Logan Web 在美團點評內實踐時,為業務方提供了 DOM 元素配置項,用於 Logan Web 綁定觸發上報的鉤子函數。
  • H5 手機端:Logan Web 可擴展內置設備搖動檢測,利用瀏覽器的 DeviceMotionEvent 事件監聽,當用戶“搖一搖”時,引導上報流程的美團卡通形象會出現在頁面側欄,如下圖所示。
  • 通用:Logan Web 在美團點評內擴展提供了接口供業務方顯示或者隱藏引導上報流程的側欄。

美團開源Logan Web:前端日誌在Web端的實現 8

(2)代碼層面觸發

考慮到用戶主動觸發方式存在的弊端,Logan Web 提供了上報接口供使用者在代碼層面調用。另外 Logan Web 也正在迭代實現內部的代碼觸發上報邏輯,提供在 Web 端內異常發生等特定場景下主動上報日誌的能力。

4. Logan Web 在美團點評內的實踐

Logan Web 已在美團內部上線,並持續迭代了一年多的時間,覆蓋公司很多主要的業務線。截止2019 年11 月,公司內使用Logan Web 的頁面PV 量已達日均1.5 億餘次,Web 上報日誌量達日均500 餘次,約97% 上報的Web 日誌在Logan 日誌分析平台上被公司研發同學搜索查閱。利用 Logan 日誌系統,公司各研發團隊已能夠儘早獲得完整的用戶端日誌流及環境信息,幫助業務及時排查問題並響應用戶反饋。

另外,在美團,Logan Web 除了提供上文介紹的技術實現之外,還利用美團內部的通用 JS 橋組件實現了與 Logan 客戶端日誌的打通,如下圖流程所示:

美團開源Logan Web:前端日誌在Web端的實現 9

這意味著在美團現有的App 環境(如美團App、點評App 等)中運行的H5 頁面如果使用了Logan Web,所記錄的日誌會利用JS 橋傳給Logan 客戶端,與客戶端日誌一起落地在App 本地文件中。因此在美團的 App 環境內上報的日誌流中可查看上下文連續的 Web 端日誌與客戶端日誌,日誌分析平台展示的某篇日誌詳情示意圖如下:

美團開源Logan Web:前端日誌在Web端的實現 10

5. Logan 開源進展與未來規劃

在 Logan Web 開源前,我們在美團 Logan 開源技術交流群中進行了開發者需求調研,依據收集到的建議,Logan Web 這次開源版本將支持 TypeScript,同時提供了本地日誌的加密策略選擇。開源的代碼及使用文檔可在 Meituan-Dianping/Logan/WebSDK 倉庫下查閱,開發者也可以在項目中直接通過 npm 包引入的方式引入 logan-web。同時 Logan Web 底層依賴的 idb-managed 也已在 GitHub 與 npm 倉庫開源。

隨著本次 Logan Web 同時開源的還有 Logan 服務端與 Logan 日誌分析平台的實現,讀者可一併在 Logan 代碼倉庫 下找到相應的代碼和使用文檔。客戶端 SDK 的實現博客可點擊參考:《美團點評移動端基礎日誌庫——Logan》。

目前 Logan 已開源了客戶端 SDK、Web 端 SDK、服務端及日誌分析平台,已經為社區開發者們提供了初步完善的整套 Logan 日誌系統實現。在未來我們將繼續優化擴展 Logan 能力,幫助開發者們在各端環境中,都能更快更早更方便地定位問題及排除異常。

美團開源Logan Web:前端日誌在Web端的實現 11

6. 聯繫我們

本次開源只是 Logan 貢獻社區的一小步,我們希望在未來 Logan 能夠為社區提供更完整可靠的大前端日誌服務,我們誠摯地歡迎開發者向我們提出寶貴的建議,與我們共建社區。您可以挑選以下方式向我們反饋建議和問題:

作者介紹

孫懿,美團點評基礎技術部前端技術中心資深工程師。

本文轉載自公眾號美團技術團隊(ID:meituantech)。

原文鏈接

https://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&mid=2651751273&idx=1&sn=388f666fd1bce3413d8564662b120b71&chksm=bd125a248a65d332417c729d9e434157236a41c380fb5ca5b2b3efa7bf6e980273cc544757a9&scene=27#wechat_redirect