聊聊前端日誌庫在 SaaS 產品中的應用與設計

文 | 元三 網易智企資深前端開發工程師前端

1、前言

筆者所在的公司業務主要是爲企業提供全流程的企業服務和一整套 SaaS 解決方案。對於企業服務 SaaS 產品來講,客戶完成購買並不意味着產品價值已經徹底交付,由於客戶在首次購買產品時,每每須要通過一系列培訓並使用後,才能真正產生價值。所以從本質上來看幫助客戶解決在使用過程當中出現的問題是 B 端產品中提供的有償服務,是產品價值鏈條中很是重要的一環。git

本文將着重介紹開發者排查客戶反饋問題這個場景下前端日誌庫的應用,以及如何設計開發適用於此類場景的前端日誌庫。github

2、SaaS 業務下前端面臨的挑戰

筆者之前是作 C 端業務出身,自然帶着 C 端業務的思惟,以爲前端把產品交互體驗作到極致就夠了。當我這個作法套用到作 SaaS 業務上,着實吃了很多虧。B 端產品和 C 端產品在付費方式的差別、購買決策人和實際使用者不一樣、產品用途不一樣(B 端客戶購買產品的根本緣由是爲了幫助企業賺錢,C 端產品購買決策有可能只是一時衝動好玩),致使 SaaS 企業經營關注的指標和 C 端產品存在較大差別,間接致使了對研發側的導向不一樣。C 端業務前端在研發資源投入上可能爲了用戶體驗不計成本,優化網頁性能以提高用戶粘性,表如今移動互聯網、電商等行業每每關注 DAUMAUGMV 等量級指標。B 端產品的核心關注大部分可否幫助客戶提高效率,產品可否幫助客戶達成他的工做目標、可否幫他快速達成目標比產品界面是否美觀重要得多。衡量一家優秀的 SaaS 企業有一項比較重要的指標——NDR(收入留存率),對 SaaS 業務的前端開發來講,首要解決的挑戰來自如何經過軟件研發工做去提高產品易用性任務效率服務效率等指標,從而爲企業帶來提升 NDR 的分子(存量客戶的續費+增購)的效果。算法

B 端和 C 端對比

 B 端 C 端
用戶場景 清晰的目的,幫助企業提高效率和質量。 用戶目的不清晰,主要是爲了愉悅和消磨時間。
頁面交互方式 流程嚴謹、低風險、高效率 操做簡便,信息簡潔,有娛樂性、社交性
常見付費方式 按年預付 免費
經常使用經營指標 NDR、CAC DAU、MAU、GMV

值得一說的是,在這方面《雲計算軟件產品使用體驗質量 度量模型及度量方法》也提出5項指標維度用於衡量產品使用體驗,很是具備參考性。這些指標維度包括易用性任務效率滿意度一致性頁面性能。其中易用性包括易操做性、易學性、清晰性,任務效率包括功能利用率、任務完成率、任務完成耗時。基於 SaaS 產品收入可持續性的考量,SaaS 企業的目標之一是提升依靠軟件產品輸出價值的比重,下降依靠人工服務輸出價值的比重,由於只有軟件產品輸出價值邊際成本最低,才能不斷提高產品服務效率。在這一點上,純粹依靠人工服務終歸是邊際成本很是高的,所以在 SaaS 業務場景下依靠技術創新去提高解決問題的效率是前端可以提供的很是大的產品價值。數據庫

3、如何解決客戶反饋問題

當咱們把視角彙集到客戶反饋問題的解決上時,能夠先將客戶反饋問題分爲功能諮詢類、問題報障類、售前諮詢類。其中開發者主要關注的是問題報障類,也存在一些技術支持回答不了的功能諮詢類問題會流向開發者,針對這類問題通常能夠採用建設內部的問題排查系統來解決。其中前端開發者主要遇到的反饋問題既有來自於 SDK 接入這一類的諮詢,也有客戶認爲產品功能不符合預期的問題報告。編程

針對此,前端爲了有效且快速定位這些問題緣由,一方面能夠在客戶端打日誌並上報到問題排查系統之中,另外一方面,對於 S 類 A 類客戶(基於 SaaS 企業針對客戶企業規模的分層模型)的緊急問題,若有必要能夠迅速和客戶溝通,使用遠程協助之類的工具在客戶的設備中復現並定位問題緣由。對於後者,咱們設計開發了基於 Chrome 瀏覽器 Chrome DevTools 協議的遠程調試解決方案 woodpecker-remote,它可以支持網站開發者對網站用戶的 Chrome 瀏覽器直接進行遠程調試。對於前者來講,咱們設計開發了前端日誌庫 woodpecker-log 以支持將客戶端運行狀態等信息進行持久化存儲供開發者調試排查問題。後端

4、前端日誌的概念

這裏先介紹一下前端日誌的概念。一般來講通常在後端開發時常常會聽到日誌的概念,對後端來講日誌是指一種用於記錄服務端啓動、運行狀態的文件。這裏的前端日誌指的也是用於記錄客戶端運行狀態在客戶端存儲或者上傳到服務器存儲造成的日誌文件。通常前端在開發、測試環境使用 Console 記錄運行狀態就夠了,但在生產環境就須要將客戶端日誌信息發送到服務端存儲起來,方便往後排查定位用戶反饋問題時使用。前端工程化

5、傳統的前端日誌存在的問題及挑戰

  1. 前端日誌庫普及率不高,感知差,和異常、性能監控等各自林立。
  2. 打日誌不規範,各類日誌格式亂象叢生。
  3. 日誌庫自己佔用前端性能預算,在性能方面須要考慮儘可能減小對 JS 主線程佔用開銷,保障主線程儘可能空閒。一部分前端日誌庫在服務器端存儲日誌,日誌產生後須要即時上傳到服務器,需佔用帶寬,並擠佔瀏覽器同域名請求最大併發數,從而拖慢正常業務 Ajax 請求,須要平衡上報頻率和每次上報日誌大小。
  4. 大型應用(如千萬、億級用戶數的應用)容易產生巨量日誌,日誌與 Bug 之間存在的關聯度低,檢索和分析操做成本高,如使用 Elasticsearch 存儲海量日誌,kibana 查詢效率低。
  5. 日誌開發及部署不方便,這裏有一些問題,前端開發者須要提早在代碼中預埋打印日誌的代碼。不然,當須要定位問題的時候不存在相關的日誌沒法進行分析。
  6. 日誌庫缺乏問題的上下文,沒法對一個完整的會話進行追蹤。如不支持記錄用戶訪問頁面發生問題先後的用戶界面交互操做記錄,以及頁面跳轉等行爲軌跡。
  7. 問題反饋鏈路長,若是不能和產品深度集成則容易在反饋鏈路中間丟失線索,形成溝通成本高企,解決辦法能夠是在客戶上報問題時自動帶上當前的日誌信息,關聯內部的工單、Jira 等問題反饋解決系統。

6、基於 B 端業務的前端日誌庫設計

上述問題中,首要解決的是日誌和用戶反饋問題相關度的問題。核心思路是使用客戶端進行日誌存儲,在發生問題時由用戶或者程序發現進行主動上報,而不是定時定頻率上報到服務器。這裏留兩個問題:用戶如何發現問題?程序(員)如何發現問題?另外,性能問題和JS異常也是產生客戶反饋的問題來源之一,但從平常SaaS業務的客戶反饋問題來源統計來看,這兩塊並非主要來源。另外的JS異常監控、性能監控兩個領域已經有比較成熟的前端基建支持。所以,非JS異常和性能問題致使的客戶反饋問題是前端日誌庫主要覆蓋並解決的問題。瀏覽器

6.1 一些典型的須要記錄前端日誌的場景

首先在開始設計以前,先思考一下,前端會如何使用日誌庫。有這些典型場景可能須要前端記錄日誌。服務器

  1. 調用第三方服務,作最壞打算若是第三方服務不可用怎麼辦。
  2. 性能預算很低、對性能很是敏感的頁面,須要上報一些性能數據。
  3. 須要重點監控的網頁核心流程,使用 JS 斷言結果爲 false 時,須要記錄斷言失敗緣由。

對第3種場景,這裏簡單列了在程序斷言爲 false 時使用前端日誌庫記錄日誌的 Demo:

6.2 日誌庫 SDK 的可維護性

相比於幾千行代碼在單一文件內維護,將 SDK 獨立成項目並採起前端工程化方式開發更具有可維護性。前端工程化是指採用模塊化、組件化、規範化、自動化的技術方案從軟件工程的角度解決工程的質量、可維護性問題。這裏列舉了一些關鍵技術選型

  1. 編程語言

對於 SDK 相對底層的代碼來講,Typescript 語言自然提供的類型文檔具有可讀性和易讀性,靜態類型檢查能夠幫助框架或庫的使用者在代碼運行階段以前發現錯誤,智能語法感知能夠提供有用的 API 類型提示。

  1. 構建

須要考慮爲 SDK 的使用者提供多種 JS 模塊規範的支持,以 rollup 爲例,配置以下:

  1. 自動化測試

在開發階段對 SDK 的自動化測試主要關注單元測試和集成測試。單元測試是用於對模塊、函數或類進行正確性檢驗,能夠採用 jest 框架。值得注意的是,對 indexedDB 存儲和查詢進行單元測試時須要模擬數據庫,可使用 fake-indexeddb 來 Mock。集成測試的目的是將系統之間的各個模塊組裝起來並使用真正的外部依賴、訪問真正的 indexedDB 數據庫對代碼進行正確性檢驗。此例中咱們採用了 Karma + Mocha + chai 的方案,對 ChromeHeadless、FirefoxHeadless、Safari 瀏覽器進行測試。

  1. 版本控制

基於語義化版本規範 semver 進行版本控制。

  1. Demo 和文檔

6.3 使用 indexedDB 在客戶端存儲日誌

localStorage 適合對少許數據進行 key-value 存儲,在客戶端日誌存儲的場景中使用 indexedDB 更加合適,它具有如下優勢:

  • 存儲和查詢結構化數據,支持二進制
  • 支持事務
  • 異步
  • 處理大量數據

假定使用 10M 容量,300bytes 的日誌,能夠存 34952 條;最長支持循環錄製 8 天日均 4369 條。

6.4 性能開銷

  • 網絡性能(延遲、請求失敗率)——日誌長度、請求體積

    • 使用獨立域名服務器處理日誌請求 Chrome 對同一域名的併發最大鏈接數限制
    • DNS 預獲取 dns-prefetch
    • 日誌存儲前進行字符串壓縮

      • 使用基於 Gzip 算法的 JS 實現 LZMA-JS, 實測 Level6,300bytes,壓縮率79%
  • sendBeacon

    • 數據可靠異步傳輸,而且不會延遲頁面的卸載或影響下一導航的載入
  • 合併請求

    • 合併多個小體積的日誌分頁上報,單頁約 1M
  • HTTP/2 頭部壓縮
  • 運行性能

    • 全異步非阻塞式操做,存儲、檢索、上報
    • 維護存儲隊列支持批量日誌存儲操做

6.5 API 設計

SDK 初始化設置

參數 類型 釋義 默認值 是否可選
options.appKey String 實例記錄日誌時會存儲的應用名稱,用於區分不一樣應用記錄的日誌,不傳時實例使用 $anonymous 做爲應用名 $anonymous 可選
options.bytesQuota Number 設定客戶端可以使用的 indexedDB 存儲上限,單位爲 MBytes。不一樣應用共用存儲上限,超出上限後,將啓用循環記錄功能,自動刪除最先的日誌 10 可選
options.reportUrl String 傳入後 report 方法將使用該地址做爲上報日誌的服務器地址,如不傳,則須要在調用 report 時指定該參數 -- 可選
options.enableSendBeacon Boolean 開啓後使用 sendBeacon 上報日誌 FALSE 可選
options.debug Boolean 開啓後在客戶端 console 控制檯打印調試信息 FALSE 可選

實例方法

方法 釋義 示例
trace/info/warn/error/fatal 日誌記錄到客戶端 wpLog.trace(content: string);
queryByDate 按發生時間檢索日誌 wpLog.queryByDate(startDate?: number, endDate?: number);
queryByContent 按關鍵字檢索日誌 wpLog.queryByContent(content: string);
report 日誌上報到服務器 wpLog.report(startDate?: number, days?: number, reportUrl?: string, session?: boolean, env?: boolean);

6.6 線上出現問題,可是代碼中沒有打日誌怎麼辦

咱們經常須要發佈前就在代碼中設計好業務關鍵流程執行時須要打印的日誌。不然,當咱們須要定位問題的時候,才發現本身並無輸出相關的日誌,這樣就會比較被動。此時只能臨時改代碼加日誌,從新發布。有沒有一種方案,能夠在遇到問題的時候,再去代碼中相應位置加日誌,用戶執行改業務流程時就能馬上打印出相關日誌,而不用從新走一遍發佈流程。 這裏介紹一種在 woodpecker-proxy 中的實現,藉助 MutationObserver 接口監聽 script 插入 DOM 事件,改寫瀏覽器 JS 請求,將其代理到目標服務器,從而實如今目標服務器修改 JS 加入日誌代碼便可在用戶瀏覽器記錄日誌。Demo 地址:DEMO

6.7 日誌規範——分級別、分應用打印日誌

遵循良好規範記錄的日誌,有利於排查問題時可以快速根據信息級別、應用進行日誌篩選。

分級別

日誌級別 釋義
trace 主要輸出調試性質的內容。
info 記錄系統的正常運行狀態,某些重要的業務處理已經結束。
warn 發生這個級別問題時,處理過程能夠繼續,但必須對這個問題給予額外關注。
error 錯誤發生時,已經影響了用戶的正常訪問,也須要立刻被處理,可是緊急程度要低於 FATAL 級別。
fatal 致命錯誤,系統中發生了很是嚴重的問題,必須立刻有人進行處理。

分應用

因爲客戶端存儲受同源限制,日誌訪問只能在自身域名下進行。多個應用可能會在同一域名下記錄日誌,區分應用名進行存儲易於隔離不一樣應用的日誌信息。

6.8 問題的上下文須要收集哪些信息

  • 設備、瀏覽器、頁面信息
  • 關聯一次會話的用戶界面交互操做
  • 關聯一次會話的頁面跳轉

6.9 如何在收到客戶反饋時快速找到相關日誌

  1. 將用戶 id、會話 id 存儲到日誌中並創建索引。
  2. 將日誌上報功能集成到 SaaS 應用,在客戶反饋問題時自動查詢當前會話日誌並上報。
  3. 在客戶反饋問題時將用戶 id、會話 id 寫入到內部的工單系統,提 Bug 時帶到 Jira 系統。

7、將來努力的方向

  • 增強可靠性

    • 網頁崩潰時如何保障前端日誌庫依然正常工做,記錄此時的日誌?使用 Service Worker 監控網頁崩潰。
  • 更直觀的問題上下文環境

    • 採用瀏覽器錄屏方案錄製出現問題先後的用戶界面。
  • 更友好的客戶通知和告警   

    • 使用 Notification桌 面通知。

8、參考資料

相關文章
相關標籤/搜索