文 | 元三 網易智企資深前端開發工程師前端
筆者所在的公司業務主要是爲企業提供全流程的企業服務和一整套 SaaS 解決方案。對於企業服務 SaaS 產品來講,客戶完成購買並不意味着產品價值已經徹底交付,由於客戶在首次購買產品時,每每須要通過一系列培訓並使用後,才能真正產生價值。所以從本質上來看幫助客戶解決在使用過程當中出現的問題是 B 端產品中提供的有償服務,是產品價值鏈條中很是重要的一環。git
本文將着重介紹開發者排查客戶反饋問題這個場景下前端日誌庫的應用,以及如何設計開發適用於此類場景的前端日誌庫。github
筆者之前是作 C 端業務出身,自然帶着 C 端業務的思惟,以爲前端把產品交互體驗作到極致就夠了。當我這個作法套用到作 SaaS 業務上,着實吃了很多虧。B 端產品和 C 端產品在付費方式的差別、購買決策人和實際使用者不一樣、產品用途不一樣(B 端客戶購買產品的根本緣由是爲了幫助企業賺錢,C 端產品購買決策有可能只是一時衝動好玩),致使 SaaS 企業經營關注的指標和 C 端產品存在較大差別,間接致使了對研發側的導向不一樣。C 端業務前端在研發資源投入上可能爲了用戶體驗不計成本,優化網頁性能以提高用戶粘性,表如今移動互聯網、電商等行業每每關注 DAU、MAU、GMV 等量級指標。B 端產品的核心關注大部分可否幫助客戶提高效率,產品可否幫助客戶達成他的工做目標、可否幫他快速達成目標比產品界面是否美觀重要得多。衡量一家優秀的 SaaS 企業有一項比較重要的指標——NDR(收入留存率),對 SaaS 業務的前端開發來講,首要解決的挑戰來自如何經過軟件研發工做去提高產品易用性、任務效率、服務效率等指標,從而爲企業帶來提升 NDR 的分子(存量客戶的續費+增購)的效果。算法
B 端 | C 端 | |
---|---|---|
用戶場景 | 清晰的目的,幫助企業提高效率和質量。 | 用戶目的不清晰,主要是爲了愉悅和消磨時間。 |
頁面交互方式 | 流程嚴謹、低風險、高效率 | 操做簡便,信息簡潔,有娛樂性、社交性 |
常見付費方式 | 按年預付 | 免費 |
經常使用經營指標 | NDR、CAC | DAU、MAU、GMV |
值得一說的是,在這方面《雲計算軟件產品使用體驗質量 度量模型及度量方法》也提出5項指標維度用於衡量產品使用體驗,很是具備參考性。這些指標維度包括易用性、任務效率、滿意度、一致性、頁面性能。其中易用性包括易操做性、易學性、清晰性,任務效率包括功能利用率、任務完成率、任務完成耗時。基於 SaaS 產品收入可持續性的考量,SaaS 企業的目標之一是提升依靠軟件產品輸出價值的比重,下降依靠人工服務輸出價值的比重,由於只有軟件產品輸出價值邊際成本最低,才能不斷提高產品服務效率。在這一點上,純粹依靠人工服務終歸是邊際成本很是高的,所以在 SaaS 業務場景下依靠技術創新去提高解決問題的效率是前端可以提供的很是大的產品價值。數據庫
當咱們把視角彙集到客戶反饋問題的解決上時,能夠先將客戶反饋問題分爲功能諮詢類、問題報障類、售前諮詢類。其中開發者主要關注的是問題報障類,也存在一些技術支持回答不了的功能諮詢類問題會流向開發者,針對這類問題通常能夠採用建設內部的問題排查系統來解決。其中前端開發者主要遇到的反饋問題既有來自於 SDK 接入這一類的諮詢,也有客戶認爲產品功能不符合預期的問題報告。編程
針對此,前端爲了有效且快速定位這些問題緣由,一方面能夠在客戶端打日誌並上報到問題排查系統之中,另外一方面,對於 S 類 A 類客戶(基於 SaaS 企業針對客戶企業規模的分層模型)的緊急問題,若有必要能夠迅速和客戶溝通,使用遠程協助之類的工具在客戶的設備中復現並定位問題緣由。對於後者,咱們設計開發了基於 Chrome 瀏覽器 Chrome DevTools 協議的遠程調試解決方案 woodpecker-remote,它可以支持網站開發者對網站用戶的 Chrome 瀏覽器直接進行遠程調試。對於前者來講,咱們設計開發了前端日誌庫 woodpecker-log 以支持將客戶端運行狀態等信息進行持久化存儲供開發者調試排查問題。後端
這裏先介紹一下前端日誌的概念。一般來講通常在後端開發時常常會聽到日誌的概念,對後端來講日誌是指一種用於記錄服務端啓動、運行狀態的文件。這裏的前端日誌指的也是用於記錄客戶端運行狀態在客戶端存儲或者上傳到服務器存儲造成的日誌文件。通常前端在開發、測試環境使用 Console 記錄運行狀態就夠了,但在生產環境就須要將客戶端日誌信息發送到服務端存儲起來,方便往後排查定位用戶反饋問題時使用。前端工程化
上述問題中,首要解決的是日誌和用戶反饋問題相關度的問題。核心思路是使用客戶端進行日誌存儲,在發生問題時由用戶或者程序發現進行主動上報,而不是定時定頻率上報到服務器。這裏留兩個問題:用戶如何發現問題?程序(員)如何發現問題?另外,性能問題和JS異常也是產生客戶反饋的問題來源之一,但從平常SaaS業務的客戶反饋問題來源統計來看,這兩塊並非主要來源。另外的JS異常監控、性能監控兩個領域已經有比較成熟的前端基建支持。所以,非JS異常和性能問題致使的客戶反饋問題是前端日誌庫主要覆蓋並解決的問題。瀏覽器
首先在開始設計以前,先思考一下,前端會如何使用日誌庫。有這些典型場景可能須要前端記錄日誌。服務器
對第3種場景,這裏簡單列了在程序斷言爲 false 時使用前端日誌庫記錄日誌的 Demo:
相比於幾千行代碼在單一文件內維護,將 SDK 獨立成項目並採起前端工程化方式開發更具有可維護性。前端工程化是指採用模塊化、組件化、規範化、自動化的技術方案從軟件工程的角度解決工程的質量、可維護性問題。這裏列舉了一些關鍵技術選型:
對於 SDK 相對底層的代碼來講,Typescript 語言自然提供的類型文檔具有可讀性和易讀性,靜態類型檢查能夠幫助框架或庫的使用者在代碼運行階段以前發現錯誤,智能語法感知能夠提供有用的 API 類型提示。
須要考慮爲 SDK 的使用者提供多種 JS 模塊規範的支持,以 rollup 爲例,配置以下:
在開發階段對 SDK 的自動化測試主要關注單元測試和集成測試。單元測試是用於對模塊、函數或類進行正確性檢驗,能夠採用 jest 框架。值得注意的是,對 indexedDB 存儲和查詢進行單元測試時須要模擬數據庫,可使用 fake-indexeddb 來 Mock。集成測試的目的是將系統之間的各個模塊組裝起來並使用真正的外部依賴、訪問真正的 indexedDB 數據庫對代碼進行正確性檢驗。此例中咱們採用了 Karma + Mocha + chai 的方案,對 ChromeHeadless、FirefoxHeadless、Safari 瀏覽器進行測試。
基於語義化版本規範 semver 進行版本控制。
localStorage 適合對少許數據進行 key-value 存儲,在客戶端日誌存儲的場景中使用 indexedDB 更加合適,它具有如下優勢:
假定使用 10M 容量,300bytes 的日誌,能夠存 34952 條;最長支持循環錄製 8 天日均 4369 條。
網絡性能(延遲、請求失敗率)——日誌長度、請求體積
日誌存儲前進行字符串壓縮
sendBeacon
合併請求
運行性能
參數 | 類型 | 釋義 | 默認值 | 是否可選 |
---|---|---|---|---|
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); |
咱們經常須要發佈前就在代碼中設計好業務關鍵流程執行時須要打印的日誌。不然,當咱們須要定位問題的時候,才發現本身並無輸出相關的日誌,這樣就會比較被動。此時只能臨時改代碼加日誌,從新發布。有沒有一種方案,能夠在遇到問題的時候,再去代碼中相應位置加日誌,用戶執行改業務流程時就能馬上打印出相關日誌,而不用從新走一遍發佈流程。 這裏介紹一種在 woodpecker-proxy 中的實現,藉助 MutationObserver 接口監聽 script 插入 DOM 事件,改寫瀏覽器 JS 請求,將其代理到目標服務器,從而實如今目標服務器修改 JS 加入日誌代碼便可在用戶瀏覽器記錄日誌。Demo 地址:DEMO。
遵循良好規範記錄的日誌,有利於排查問題時可以快速根據信息級別、應用進行日誌篩選。
分級別
日誌級別 | 釋義 |
---|---|
trace | 主要輸出調試性質的內容。 |
info | 記錄系統的正常運行狀態,某些重要的業務處理已經結束。 |
warn | 發生這個級別問題時,處理過程能夠繼續,但必須對這個問題給予額外關注。 |
error | 錯誤發生時,已經影響了用戶的正常訪問,也須要立刻被處理,可是緊急程度要低於 FATAL 級別。 |
fatal | 致命錯誤,系統中發生了很是嚴重的問題,必須立刻有人進行處理。 |
分應用
因爲客戶端存儲受同源限制,日誌訪問只能在自身域名下進行。多個應用可能會在同一域名下記錄日誌,區分應用名進行存儲易於隔離不一樣應用的日誌信息。
增強可靠性
更直觀的問題上下文環境
更友好的客戶通知和告警