前端異常監(jiān)控解決方案研究

本文出自 Tencent CDC前端異常監(jiān)控解決方案研究

前端監(jiān)控包括行為監(jiān)控椿胯、異常監(jiān)控皮仁、性能監(jiān)控等述么,本文主要討論異常監(jiān)控蝌数。對(duì)于前端而言,和后端處于同一個(gè)監(jiān)控系統(tǒng)中度秘,前端有自己的監(jiān)控方案顶伞,后端也有自己等監(jiān)控方案,但兩者并不分離剑梳,因?yàn)橐粋€(gè)用戶在操作應(yīng)用過(guò)程中如果出現(xiàn)異常唆貌,有可能是前端引起,也有可能是后端引起垢乙,需要有一個(gè)機(jī)制锨咙,將前后端串聯(lián)起來(lái),使監(jiān)控本身統(tǒng)一于監(jiān)控系統(tǒng)追逮。因此酪刀,即使只討論前端異常監(jiān)控粹舵,其實(shí)也不能?chē)?yán)格區(qū)分前后端界限,而要根據(jù)實(shí)際系統(tǒng)的設(shè)計(jì)骂倘,在最終的報(bào)表中體現(xiàn)出監(jiān)控對(duì)開(kāi)發(fā)和業(yè)務(wù)的幫助眼滤。

一般而言,一個(gè)監(jiān)控系統(tǒng)历涝,大致可以分為四個(gè)階段:日志采集柠偶、日志存儲(chǔ)、統(tǒng)計(jì)與分析睬关、報(bào)告和警告诱担。

image.png

采集階段:收集異常日志,先在本地做一定的處理电爹,采取一定的方案上報(bào)到服務(wù)器蔫仙。

存儲(chǔ)階段:后端接收前端上報(bào)的異常日志,經(jīng)過(guò)一定處理丐箩,按照一定的存儲(chǔ)方案存儲(chǔ)摇邦。

分析階段:分為機(jī)器自動(dòng)分析和人工分析。機(jī)器自動(dòng)分析屎勘,通過(guò)預(yù)設(shè)的條件和算法施籍,對(duì)存儲(chǔ)的日志信息進(jìn)行統(tǒng)計(jì)和篩選,發(fā)現(xiàn)問(wèn)題概漱,觸發(fā)報(bào)警丑慎。人工分析,通過(guò)提供一個(gè)可視化的數(shù)據(jù)面板瓤摧,讓系統(tǒng)用戶可以看到具體的日志數(shù)據(jù)竿裂,根據(jù)信息,發(fā)現(xiàn)異常問(wèn)題根源照弥。

報(bào)警階段:分為告警和預(yù)警腻异。告警按照一定的級(jí)別自動(dòng)報(bào)警,通過(guò)設(shè)定的渠道这揣,按照一定的觸發(fā)規(guī)則進(jìn)行悔常。預(yù)警則在異常發(fā)生前,提前預(yù)判给赞,給出警告机打。

1 前端異常

前端異常是指在用戶使用Web應(yīng)用時(shí)無(wú)法快速得到符合預(yù)期結(jié)果的情況,不同的異常帶來(lái)的后果程度不同塞俱,輕則引起用戶使用不悅姐帚,重則導(dǎo)致產(chǎn)品無(wú)法使用吏垮,使用戶喪失對(duì)產(chǎn)品的認(rèn)可障涯。

1.1 前端異常分類(lèi)

根據(jù)異常代碼的后果的程度罐旗,對(duì)前端異常的表現(xiàn)分為如下幾類(lèi)

image.png

a. 出錯(cuò)

界面呈現(xiàn)的內(nèi)容與用戶預(yù)期的內(nèi)容不符,例如點(diǎn)擊進(jìn)入非目標(biāo)界面唯蝶,數(shù)據(jù)不準(zhǔn)確九秀,出現(xiàn)的錯(cuò)誤提示不可理解,界面錯(cuò)位粘我,提交后跳轉(zhuǎn)到錯(cuò)誤界面等情況鼓蜒。這類(lèi)異常出現(xiàn)時(shí),雖然產(chǎn)品本身功能還能正常使用征字,但用戶無(wú)法達(dá)成自己目標(biāo)都弹。

b. 呆滯

界面出現(xiàn)操作后沒(méi)有反應(yīng)的現(xiàn)象,例如點(diǎn)擊按鈕無(wú)法提交匙姜,提示成功后無(wú)法繼續(xù)操作畅厢。這類(lèi)異常出現(xiàn)時(shí),產(chǎn)品已經(jīng)存在界面級(jí)局部不可用現(xiàn)象氮昧。

c. 損壞

界面出現(xiàn)無(wú)法實(shí)現(xiàn)操作目的的現(xiàn)象框杜,例如點(diǎn)擊無(wú)法進(jìn)入目標(biāo)界面,點(diǎn)擊無(wú)法查看詳情內(nèi)容等袖肥。這類(lèi)異常出現(xiàn)時(shí)咪辱,應(yīng)用部分功能無(wú)法被正常使用。

d. 假死

界面出現(xiàn)卡頓椎组,無(wú)法對(duì)任何功能進(jìn)行使用的現(xiàn)象油狂。例如用戶無(wú)法登陸導(dǎo)致無(wú)法使用應(yīng)用內(nèi)功能,由于某個(gè)遮罩層阻擋且不可關(guān)閉導(dǎo)致無(wú)法進(jìn)行任何后續(xù)操作寸癌。這類(lèi)異常出現(xiàn)時(shí)选调,用戶很可能殺死應(yīng)用。

e. 崩潰

應(yīng)用出現(xiàn)經(jīng)常性自動(dòng)退出或無(wú)法操作的現(xiàn)象灵份。例如間歇性crash仁堪,網(wǎng)頁(yè)無(wú)法正常加載或加載后無(wú)法進(jìn)行任何操作。這類(lèi)異常持續(xù)出現(xiàn)填渠,將直接導(dǎo)致用戶流失弦聂,影響產(chǎn)品生命力。

1.2 異常錯(cuò)誤原因分類(lèi)

前端產(chǎn)生異常的原因主要分5類(lèi):

原因 案例 頻率
邏輯錯(cuò)誤 1) 業(yè)務(wù)邏輯判斷條件錯(cuò)誤 2) 事件綁定順序錯(cuò)誤3) 調(diào)用棧時(shí)序錯(cuò)誤4) 錯(cuò)誤的操作js對(duì)象 經(jīng)常
數(shù)據(jù)類(lèi)型錯(cuò)誤 1) 將null視作對(duì)象讀取property 2) 將undefined視作數(shù)組進(jìn)行遍歷 3) 將字符串形式的數(shù)字直接用于加運(yùn)算 4) 函數(shù)參數(shù)未傳 經(jīng)常
語(yǔ)法句法錯(cuò)誤 較少
網(wǎng)絡(luò)錯(cuò)誤 1) 慢 2) 服務(wù)端未返回?cái)?shù)據(jù)但仍200氛什,前端按正常進(jìn)行數(shù)據(jù)遍歷 3) 提交數(shù)據(jù)時(shí)網(wǎng)絡(luò)中斷 4) 服務(wù)端500錯(cuò)誤時(shí)前端未做任何錯(cuò)誤處理 偶爾
系統(tǒng)錯(cuò)誤 1) 內(nèi)存不夠用 2) 磁盤(pán)塞滿3) 殼不支持API4) 不兼容 較少

2 異常采集

2.1 采集內(nèi)容

當(dāng)異常出現(xiàn)的時(shí)候莺葫,我們需要知道異常的具體信息,根據(jù)異常的具體信息來(lái)決定采用什么樣的解決方案枪眉。在采集異常信息時(shí)捺檬,可以遵循4W原則:

WHO did WHAT and get WHICH exception in WHICH environment?

a. 用戶信息

出現(xiàn)異常時(shí)該用戶的信息,例如該用戶在當(dāng)前時(shí)刻的狀態(tài)贸铜、權(quán)限等堡纬,以及需要區(qū)分用戶可多終端登錄時(shí)聂受,異常對(duì)應(yīng)的是哪一個(gè)終端。

b. 行為信息

用戶進(jìn)行什么操作時(shí)產(chǎn)生了異常:所在的界面路徑烤镐;執(zhí)行了什么操作蛋济;操作時(shí)使用了哪些數(shù)據(jù);當(dāng)時(shí)的API吐了什么數(shù)據(jù)給客戶端炮叶;如果是提交操作碗旅,提交了什么數(shù)據(jù);上一個(gè)路徑镜悉;上一個(gè)行為日志記錄ID等祟辟。

c. 異常信息

產(chǎn)生異常的代碼信息:用戶操作的DOM元素節(jié)點(diǎn);異常級(jí)別侣肄;異常類(lèi)型川尖;異常描述;代碼stack信息等茫孔。

d. 環(huán)境信息

網(wǎng)絡(luò)環(huán)境叮喳;設(shè)備型號(hào)和標(biāo)識(shí)碼;操作系統(tǒng)版本缰贝;客戶端版本馍悟;API接口版本等。

字段 類(lèi)型 解釋
requestId String 一個(gè)界面產(chǎn)生一個(gè)requestId
traceId String 一個(gè)階段產(chǎn)生一個(gè)traceId剩晴,用于追蹤和一個(gè)異常相關(guān)的所有日志記錄
hash String 這條log的唯一標(biāo)識(shí)碼锣咒,相當(dāng)于logId,但它是根據(jù)當(dāng)前日志記錄的具體內(nèi)容而生成的
time Number 當(dāng)前日志產(chǎn)生的時(shí)間(保存時(shí)刻)
userId String
userStatus Number 當(dāng)時(shí)赞弥,用戶狀態(tài)信息(是否可用/禁用)
userRoles Array 當(dāng)時(shí)毅整,前用戶的角色列表
userGroups Array 當(dāng)時(shí),用戶當(dāng)前所在組绽左,組別權(quán)限可能影響結(jié)果
userLicenses Array 當(dāng)時(shí)悼嫉,許可證,可能過(guò)期
path String 所在路徑拼窥,URL
action String 進(jìn)行了什么操作
referer String 上一個(gè)路徑戏蔑,來(lái)源URL
prevAction String 上一個(gè)操作
data Object 當(dāng)前界面的state、data
dataSources Array<Object> 上游api給了什么數(shù)據(jù)
dataSend Object 提交了什么數(shù)據(jù)
targetElement HTMLElement 用戶操作的DOM元素
targetDOMPath Array<HTMLElement> 該DOM元素的節(jié)點(diǎn)路徑
targetCSS Object 該元素的自定義樣式表
targetAttrs Object 該元素當(dāng)前的屬性及值
errorType String 錯(cuò)誤類(lèi)型
errorLevel String 異常級(jí)別
errorStack String 錯(cuò)誤stack信息
errorFilename String 出錯(cuò)文件
errorLineNo Number 出錯(cuò)行
errorColNo Number 出錯(cuò)列位置
errorMessage String 錯(cuò)誤描述(開(kāi)發(fā)者定義)
errorTimeStamp Number 時(shí)間戳
eventType String 事件類(lèi)型
pageX Number 事件x軸坐標(biāo)
pageY Number 事件y軸坐標(biāo)
screenX Number 事件x軸坐標(biāo)
screenY Number 事件y軸坐標(biāo)
pageW Number 頁(yè)面寬度
pageH Number 頁(yè)面高度
screenW Number 屏幕寬度
screenH Number 屏幕高度
eventKey String 觸發(fā)事件的鍵
network String 網(wǎng)絡(luò)環(huán)境描述
userAgent String 客戶端描述
device String 設(shè)備描述
system String 操作系統(tǒng)描述
appVersion String 應(yīng)用版本
apiVersion String 接口版本

這是一份非常龐大的日志字段表鲁纠,它幾乎囊括了一個(gè)異常發(fā)生時(shí)总棵,能夠?qū)Ξ惓V茉猸h(huán)境進(jìn)行詳細(xì)描述的所有信息。不同情況下改含,這些字段并不一定都會(huì)收集情龄,由于我們會(huì)采用文檔數(shù)據(jù)庫(kù)存儲(chǔ)日志,因此,并不影響它的實(shí)際存儲(chǔ)結(jié)果骤视。

2.2 異常捕獲

前端捕獲異常分為全局捕獲和單點(diǎn)捕獲鞍爱。全局捕獲代碼集中,易于管理尚胞;單點(diǎn)捕獲作為補(bǔ)充,對(duì)某些特殊情況進(jìn)行捕獲帜慢,但分散笼裳,不利于管理。

a粱玲、全局捕獲

通過(guò)全局的接口躬柬,將捕獲代碼集中寫(xiě)在一個(gè)地方,可以利用的接口有:

  • window.addEventListener(‘error’) / window.addEventListener(“unhandledrejection”) / document.addEventListener(‘click’) 等
  • 框架級(jí)別的全局監(jiān)聽(tīng)抽减,例如aixos中使用interceptor進(jìn)行攔截允青,vue、react都有自己的錯(cuò)誤采集接口
  • 通過(guò)對(duì)全局函數(shù)進(jìn)行封裝包裹卵沉,實(shí)現(xiàn)在在調(diào)用該函數(shù)時(shí)自動(dòng)捕獲異常
  • 對(duì)實(shí)例方法重寫(xiě)(Patch)颠锉,在原有功能基礎(chǔ)上包裹一層,例如對(duì)console.error進(jìn)行重寫(xiě)史汗,在使用方法不變的情況下也可以異常捕獲

b琼掠、單點(diǎn)捕獲

在業(yè)務(wù)代碼中對(duì)單個(gè)代碼塊進(jìn)行包裹,或在邏輯流程中打點(diǎn)停撞,實(shí)現(xiàn)有針對(duì)性的異常捕獲:

  • try…catch
  • 專(zhuān)門(mén)寫(xiě)一個(gè)函數(shù)來(lái)收集異常信息瓷蛙,在異常發(fā)生時(shí),調(diào)用該函數(shù)
  • 專(zhuān)門(mén)寫(xiě)一個(gè)函數(shù)來(lái)包裹其他函數(shù)戈毒,得到一個(gè)新函數(shù)艰猬,該新函數(shù)運(yùn)行結(jié)果和原函數(shù)一模一樣,只是在發(fā)生異常時(shí)可以捕獲異常

2.3 跨域腳本異常

由于瀏覽器安全策略限制埋市,跨域腳本報(bào)錯(cuò)時(shí)冠桃,無(wú)法直接獲取錯(cuò)誤的詳細(xì)信息,只能得到一個(gè)Script Error道宅。例如腊满,我們會(huì)引入第三方依賴(lài),或者將自己的腳本放在CDN時(shí)培己。

解決Script Error的方法:

方案一:

  • 將js內(nèi)聯(lián)到HTML中
  • 將js文件與HTML放在同域下

方案二:

  1. 為頁(yè)面上script標(biāo)簽添加crossorigin屬性
  2. 被引入腳本所在服務(wù)端響應(yīng)頭中碳蛋,增加 Access-Control-Allow-Origin 來(lái)支持跨域資源共享

2.4 異常錄制

對(duì)于一個(gè)異常,僅僅擁有該異常的信息還不足以完全抓住問(wèn)題的本質(zhì)省咨,因?yàn)楫惓0l(fā)生的位置肃弟,并不一定是異常根源所在的位置。我們需要對(duì)異常現(xiàn)場(chǎng)進(jìn)行還原笤受,才能復(fù)原問(wèn)題全貌穷缤,甚至避免類(lèi)似問(wèn)題在其他界面中發(fā)生。這里需要引進(jìn)一個(gè)概念箩兽,就是“異常錄制”津肛。錄制通過(guò)“時(shí)間”“空間”兩個(gè)維度記錄異常發(fā)生前到發(fā)生的整個(gè)過(guò)程,對(duì)于找到異常根源更有幫助汗贫。

image.png

上圖表示身坐,當(dāng)異常發(fā)生時(shí),異常的根源可能離我們很遠(yuǎn)落包,我們需要回到異常發(fā)生的現(xiàn)場(chǎng)部蛇,找到異常根源。就像現(xiàn)實(shí)生活中破案一樣咐蝇,如果有監(jiān)控?cái)z影機(jī)對(duì)案發(fā)過(guò)程的錄影涯鲁,對(duì)破案來(lái)說(shuō)更加容易。如果僅僅關(guān)注異常本身有序,要找到異常的根源抹腿,需要憑借運(yùn)氣,但有了異常錄制的幫助旭寿,找到根源就更加容易幢踏。

所謂的“異常錄制”,實(shí)際上就是通過(guò)技術(shù)手段许师,收集用戶的操作過(guò)程房蝉,對(duì)用戶的每一個(gè)操作都進(jìn)行記錄,在發(fā)生異常時(shí)微渠,把一定時(shí)間區(qū)間內(nèi)的記錄重新運(yùn)行搭幻,形成影像進(jìn)行播放,讓調(diào)試者無(wú)需向用戶詢問(wèn)逞盆,就能看到用戶當(dāng)時(shí)的操作過(guò)程檀蹋。

image.png

上圖是來(lái)自阿里的一套異常錄制還原方案示意圖,用戶在界面上的操作產(chǎn)生的events和mutation被產(chǎn)品收集起來(lái)云芦,上傳到服務(wù)器俯逾,經(jīng)過(guò)隊(duì)列處理按順序存放到數(shù)據(jù)庫(kù)中。當(dāng)需要進(jìn)行異常重現(xiàn)的時(shí)候舅逸,將這些記錄從數(shù)據(jù)庫(kù)中取出桌肴,采用一定的技術(shù)方案,順序播放這些記錄琉历,即可實(shí)現(xiàn)異常還原坠七。

2.5 異常級(jí)別

一般而言水醋,我們會(huì)將收集信息的級(jí)別分為info,warn彪置,error等拄踪,并在此基礎(chǔ)上進(jìn)行擴(kuò)展。

當(dāng)我們監(jiān)控到異常發(fā)生時(shí)拳魁,可以將該異常劃分到“重要——緊急”模型中分為A惶桐、B、C潘懊、D四個(gè)等級(jí)姚糊。有些異常,雖然發(fā)生了卦尊,但是并不影響用戶的正常使用叛拷,用戶其實(shí)并沒(méi)有感知到舌厨,雖然理論上應(yīng)該修復(fù)岂却,但是實(shí)際上相對(duì)于其他異常而言,可以放在后面進(jìn)行處理裙椭。

image.png

下文會(huì)討論告警策略躏哩,一般而言,越靠近右上角的異常會(huì)越快通知揉燃,保證相關(guān)人員能最快接收到信息扫尺,并進(jìn)行處理。A級(jí)異常需要快速響應(yīng)炊汤,甚至需要相關(guān)負(fù)責(zé)人知悉正驻。

在收集異常階段,可根據(jù)第一節(jié)劃分的異常后果來(lái)判斷異常的嚴(yán)重程度抢腐,在發(fā)生異常時(shí)選擇對(duì)應(yīng)的上報(bào)方案進(jìn)行上報(bào)姑曙。

3 整理與上報(bào)方案

前文已經(jīng)提到,除了異常報(bào)錯(cuò)信息本身迈倍,我們還需要記錄用戶操作日志伤靠,以實(shí)現(xiàn)場(chǎng)景復(fù)原。這就涉及到上報(bào)的量和頻率問(wèn)題啼染。如果任何日志都立即上報(bào)宴合,這無(wú)異于自造的DDOS攻擊。因此迹鹅,我們需要合理的上報(bào)方案卦洽。下文會(huì)介紹4種上報(bào)方案,但實(shí)際我們不會(huì)僅限于其中一種斜棚,而是經(jīng)常同時(shí)使用逐样,對(duì)不同級(jí)別的日志選擇不同的上報(bào)方案。

3.1 前端存儲(chǔ)日志

我們前面提到,我們并不單單采集異常本身日志脂新,而且還會(huì)采集與異常相關(guān)的用戶行為日志挪捕。單純一條異常日志并不能幫助我們快速定位問(wèn)題根源,找到解決方案争便。但如果要收集用戶的行為日志级零,又要采取一定的技巧,而不能用戶每一個(gè)操作后滞乙,就立即將該行為日志傳到服務(wù)器奏纪,對(duì)于具有大量用戶同時(shí)在線的應(yīng)用,如果用戶一操作就立即上傳日志斩启,無(wú)異于對(duì)日志服務(wù)器進(jìn)行DDOS攻擊序调。因此,我們先將這些日志存儲(chǔ)在用戶客戶端本地兔簇,達(dá)到一定條件之后发绢,再同時(shí)打包上傳一組日志。

那么垄琐,如何進(jìn)行前端日志存儲(chǔ)呢边酒?我們不可能直接將這些日志用一個(gè)變量保存起來(lái),這樣會(huì)擠爆內(nèi)存狸窘,而且一旦用戶進(jìn)行刷新操作墩朦,這些日志就丟失了,因此翻擒,我們自然而然想到前端數(shù)據(jù)持久化方案氓涣。

目前,可用的持久化方案可選項(xiàng)也比較多了陋气,主要有:Cookie劳吠、localStorage、sessionStorage恩伺、IndexedDB赴背、webSQL 、FileSystem 等等晶渠。那么該如何選擇呢凰荚?我們通過(guò)一個(gè)表來(lái)進(jìn)行對(duì)比:

存儲(chǔ)方式 cookie localStorage sessionStorage IndexedDB webSQL FileSystem
類(lèi)型 key-value key-value NoSQL SQL
數(shù)據(jù)格式 string string string object
容量 4k 5M 5M 500M 60M
進(jìn)程 同步 同步 同步 異步 異步
檢索 key key key, index field
性能 讀快寫(xiě)慢 讀慢寫(xiě)快

綜合之后,IndexedDB是最好的選擇褒脯,它具有容量大便瑟、異步的優(yōu)勢(shì),異步的特性保證它不會(huì)對(duì)界面的渲染產(chǎn)生阻塞番川。而且IndexedDB是分庫(kù)的到涂,每個(gè)庫(kù)又分store凰锡,還能按照索引進(jìn)行查詢黄伊,具有完整的數(shù)據(jù)庫(kù)管理思維,比localStorage更適合做結(jié)構(gòu)化數(shù)據(jù)管理。但是它有一個(gè)缺點(diǎn)抄谐,就是api非常復(fù)雜窃爷,不像localStorage那么簡(jiǎn)單直接皂冰。針對(duì)這一點(diǎn)贿讹,我們可以使用hello-indexeddb這個(gè)工具,它用Promise對(duì)復(fù)雜api進(jìn)行來(lái)封裝伐谈,簡(jiǎn)化操作烂完,使IndexedDB的使用也能做到localStorage一樣便捷。另外诵棵,IndexedDB是被廣泛支持的HTML5標(biāo)準(zhǔn)抠蚣,兼容大部分瀏覽器,因此不用擔(dān)心它的發(fā)展前景履澳。

接下來(lái)嘶窄,我們究竟應(yīng)該怎么合理使用IndexedDB,保證我們前端存儲(chǔ)的合理性呢奇昙?

image.png

上圖展示了前端存儲(chǔ)日志的流程和數(shù)據(jù)庫(kù)布局护侮。當(dāng)一個(gè)事件敌完、變動(dòng)储耐、異常被捕獲之后,形成一條初始日志滨溉,被立即放入暫存區(qū)(indexedDB的一個(gè)store)什湘,之后主程序就結(jié)束了收集過(guò)程,后續(xù)的事只在webworker中發(fā)生晦攒。在一個(gè)webworker中闽撤,一個(gè)循環(huán)任務(wù)不斷從暫存區(qū)中取出日志,對(duì)日志進(jìn)行分類(lèi)脯颜,將分類(lèi)結(jié)果存儲(chǔ)到索引區(qū)中哟旗,并對(duì)日志記錄的信息進(jìn)行豐富,將最終將會(huì)上報(bào)到服務(wù)端的日志記錄轉(zhuǎn)存到歸檔區(qū)栋操。而當(dāng)一條日志在歸檔區(qū)中存在的時(shí)間超過(guò)一定天數(shù)之后闸餐,它就已經(jīng)沒(méi)有價(jià)值了,但是為了防止特殊情況矾芙,它被轉(zhuǎn)存到回收區(qū)舍沙,再經(jīng)歷一段時(shí)間后,就會(huì)被從回收區(qū)中清除剔宪。

3.2 前端整理日志

上文講到拂铡,在一個(gè)webworker中對(duì)日志進(jìn)行整理后存到索引區(qū)和歸檔區(qū)壹无,那么這個(gè)整理過(guò)程是怎樣的呢?

由于我們下文要講的上報(bào)感帅,是按照索引進(jìn)行的斗锭,因此,我們?cè)谇岸说娜罩菊砉ぷ魇颍饕褪歉鶕?jù)日志特征拒迅,整理出不同的索引。我們?cè)谑占罩緯r(shí)她倘,會(huì)給每一條日志打上一個(gè)type璧微,以此進(jìn)行分類(lèi),并創(chuàng)建索引硬梁,同時(shí)通過(guò)object-hashcode計(jì)算每個(gè)log對(duì)象的hash值前硫,作為這個(gè)log的唯一標(biāo)志。

  • 將所有日志記錄按時(shí)序存放在歸檔區(qū)荧止,并將新入庫(kù)的日志加入索引
  • BatchIndexes:批量上報(bào)索引(包含性能等其他日志)屹电,可一次批量上報(bào)100條
  • MomentIndexes:即時(shí)上報(bào)索引,一次全部上報(bào)
  • FeedbackIndexes:用戶反饋索引跃巡,一次上報(bào)一條
  • BlockIndexes:區(qū)塊上報(bào)索引危号,按異常/錯(cuò)誤(traceId,requestId)分塊素邪,一次上報(bào)一塊
  • 上報(bào)完成后外莲,被上報(bào)過(guò)的日志對(duì)應(yīng)的索引刪除
  • 3天以上日志進(jìn)入回收區(qū)
  • 7天以上的日志從回收區(qū)清除

rquestId:同時(shí)追蹤前后端日志。由于后端也會(huì)記錄自己的日志兔朦,因此偷线,在前端請(qǐng)求api的時(shí)候,默認(rèn)帶上requestId沽甥,后端記錄的日志就可以和前端日志對(duì)應(yīng)起來(lái)声邦。

traceId:追蹤一個(gè)異常發(fā)生前后的相關(guān)日志。當(dāng)應(yīng)用啟動(dòng)時(shí)摆舟,創(chuàng)建一個(gè)traceId亥曹,直到一個(gè)異常發(fā)生時(shí),刷新traceId恨诱。把一個(gè)traceId相關(guān)的requestId收集起來(lái)媳瞪,把這些requestId相關(guān)的日志組合起來(lái),就是最終這個(gè)異常相關(guān)的所有日志胡野,用來(lái)對(duì)異常進(jìn)行復(fù)盤(pán)材失。

image.png

上圖舉例展示了如何利用traceId和requestId找出和一個(gè)異常相關(guān)的所有日志。在上圖中硫豆,hash4是一條異常日志龙巨,我們找到hash4對(duì)應(yīng)的traceId為traceId2笼呆,在日志列表中,有兩條記錄具有該traceId旨别,但是hash3這條記錄并不是一個(gè)動(dòng)作的開(kāi)始诗赌,因?yàn)閔ash3對(duì)應(yīng)的requestId為reqId2,而reqId2開(kāi)始于hash2秸弛,因此铭若,我們實(shí)際上要把hash2也加入到該異常發(fā)生的整個(gè)復(fù)盤(pán)備選記錄中〉堇溃總結(jié)起來(lái)就是叼屠,我們要找出同一個(gè)traceId對(duì)應(yīng)的所有requestId對(duì)應(yīng)的日志記錄,雖然有點(diǎn)繞绞铃,但稍理解就可以明白其中的道理镜雨。

我們把這些和一個(gè)異常相關(guān)的所有日志集合起來(lái),稱(chēng)為一個(gè)block儿捧,再利用日志的hash集合荚坞,得出這個(gè)block的hash,并在索引區(qū)中建立索引菲盾,等待上報(bào)颓影。

3.3 上報(bào)日志

上報(bào)日志也在webworker中進(jìn)行,為了和整理區(qū)分懒鉴,可以分兩個(gè)worker诡挂。上報(bào)的流程大致為:在每一個(gè)循環(huán)中,從索引區(qū)取出對(duì)應(yīng)條數(shù)的索引疗我,通過(guò)索引中的hash咆畏,到歸檔區(qū)取出完整的日志記錄南捂,再上傳到服務(wù)器吴裤。

按照上報(bào)的頻率(重要緊急度)可將上報(bào)分為四種:

a. 即時(shí)上報(bào)

收集到日志后,立即觸發(fā)上報(bào)函數(shù)溺健。僅用于A類(lèi)異常麦牺。而且由于受到網(wǎng)絡(luò)不確定因素影響,A類(lèi)日志上報(bào)需要有一個(gè)確認(rèn)機(jī)制鞭缭,只有確認(rèn)服務(wù)端已經(jīng)成功接收到該上報(bào)信息之后剖膳,才算完成。否則需要有一個(gè)循環(huán)機(jī)制岭辣,確保上報(bào)成功吱晒。

b. 批量上報(bào)

將收集到的日志存儲(chǔ)在本地,當(dāng)收集到一定數(shù)量之后再打包一次性上報(bào)沦童,或者按照一定的頻率(時(shí)間間隔)打包上傳仑濒。這相當(dāng)于把多次合并為一次上報(bào)叹话,以降低對(duì)服務(wù)器的壓力。

c. 區(qū)塊上報(bào)

將一次異常的場(chǎng)景打包為一個(gè)區(qū)塊后進(jìn)行上報(bào)墩瞳。它和批量上報(bào)不同驼壶,批量上報(bào)保證了日志的完整性,全面性喉酌,但會(huì)有無(wú)用信息热凹。而區(qū)塊上報(bào)則是針對(duì)異常本身的,確保單個(gè)異常相關(guān)的日志被全部上報(bào)泪电。

d. 用戶主動(dòng)提交

在界面上提供一個(gè)按鈕般妙,用戶主動(dòng)反饋bug。這有利于加強(qiáng)與用戶的互動(dòng)相速。

或者當(dāng)異常發(fā)生時(shí)股冗,雖然對(duì)用戶沒(méi)有任何影響,但是應(yīng)用監(jiān)控到了和蚪,彈出一個(gè)提示框止状,讓用戶選擇是否愿意上傳日志。這種方案適合涉及用戶隱私數(shù)據(jù)時(shí)攒霹。

即時(shí)上報(bào) 批量上報(bào) 區(qū)塊上報(bào) 用戶反饋
時(shí)效 立即 定時(shí) 稍延時(shí) 延時(shí)
條數(shù) 一次全部上報(bào) 一次100條 單次上報(bào)相關(guān)條目 一次1條
容量
緊急 緊急重要 不緊急 不緊急但重要 不緊急

即時(shí)上報(bào)雖然叫即時(shí)怯疤,但是其實(shí)也是通過(guò)類(lèi)似隊(duì)列的循環(huán)任務(wù)去完成的,它主要是盡快把一些重要的異常提交給監(jiān)控系統(tǒng)催束,好讓運(yùn)維人員發(fā)現(xiàn)問(wèn)題集峦,因此,它對(duì)應(yīng)的緊急程度比較高抠刺。

批量上報(bào)和區(qū)塊上報(bào)的區(qū)別:批量上報(bào)是一次上報(bào)一定條數(shù)塔淤,比如每2分鐘上報(bào)1000條,直到上報(bào)完成速妖。而區(qū)塊上報(bào)是在異常發(fā)生之后高蜂,馬上收集和異常相關(guān)的所有日志,查詢出哪些日志已經(jīng)由批量上報(bào)上報(bào)過(guò)了罕容,剔除掉备恤,把其他相關(guān)日志上傳,和異常相關(guān)的這些日志相對(duì)而言更重要一些锦秒,它們可以幫助盡快復(fù)原異陈恫矗現(xiàn)場(chǎng),找出發(fā)生異常的根源旅择。

用戶提交的反饋信息惭笑,則可以慢悠悠上報(bào)上去。

為了確保上報(bào)是成功的,在上報(bào)時(shí)需要有一個(gè)確認(rèn)機(jī)制沉噩,由于在服務(wù)端接收到上報(bào)日志之后铺敌,并不會(huì)立即存入數(shù)據(jù)庫(kù),而是放到一個(gè)隊(duì)列中屁擅,因此偿凭,前后端在確保日志確實(shí)已經(jīng)記錄進(jìn)數(shù)據(jù)庫(kù)這一點(diǎn)上需要再做一些處理。

image.png

上圖展示了上報(bào)的一個(gè)大致流程派歌,在上報(bào)時(shí)弯囊,先通過(guò)hash查詢,讓客戶端知道準(zhǔn)備要上報(bào)的日志集合中胶果,是否存在已經(jīng)被服務(wù)端保存好的日志匾嘱,如果已經(jīng)存在,就將這些日志去除早抠,避免重復(fù)上報(bào)霎烙,浪費(fèi)流量。

3.4 壓縮上報(bào)數(shù)據(jù)

一次性上傳批量數(shù)據(jù)時(shí)蕊连,必然遇到數(shù)據(jù)量大悬垃,浪費(fèi)流量,或者傳輸慢等情況甘苍,網(wǎng)絡(luò)不好的狀態(tài)下尝蠕,可能導(dǎo)致上報(bào)失敗。因此载庭,在上報(bào)之前進(jìn)行數(shù)據(jù)壓縮也是一種方案看彼。

對(duì)于合并上報(bào)這種情況,一次的數(shù)據(jù)量可能要十幾k囚聚,對(duì)于日 pv 大的站點(diǎn)來(lái)說(shuō)靖榕,產(chǎn)生的流量還是很可觀的。所以有必要對(duì)數(shù)據(jù)進(jìn)行壓縮上報(bào)顽铸。lz-string是一個(gè)非常優(yōu)秀的字符串壓縮類(lèi)庫(kù)茁计,兼容性好,代碼量少跋破,壓縮比高簸淀,壓縮時(shí)間短,壓縮率達(dá)到驚人的60%毒返。但它基于LZ78壓縮,如果后端不支持解壓舷手,可選擇gzip壓縮拧簸,一般而言后端會(huì)默認(rèn)預(yù)裝gzip,因此男窟,選擇gzip壓縮數(shù)據(jù)也可以盆赤,工具包pako中自帶了gzip壓縮贾富,可以嘗試使用。

4 日志接收與存儲(chǔ)

4.1 接入層與消息隊(duì)列

一般通過(guò)提供獨(dú)立的日志服務(wù)器接收客戶端日志牺六,接收過(guò)程中颤枪,要對(duì)客戶端日志內(nèi)容的合法性、安全性等進(jìn)行甄別淑际,防止被人攻擊畏纲。而且由于日志提交一般都比較頻繁,多客戶端同時(shí)并發(fā)的情況也常見(jiàn)春缕。通過(guò)消息隊(duì)列將日志信息逐一處理后寫(xiě)入到數(shù)據(jù)庫(kù)進(jìn)行保存也是比較常用的方案盗胀。

image.png

上圖為騰訊BetterJS的架構(gòu)圖,其中“接入層”和“推送中心”就是這里提到的接入層和消息隊(duì)列锄贼。BetterJS將整個(gè)前端監(jiān)控的各個(gè)模塊進(jìn)行拆分票灰,推送中心承擔(dān)了將日志推送到存儲(chǔ)中心進(jìn)行存儲(chǔ)和推送給其他系統(tǒng)(例如告警系統(tǒng))的角色,但我們可以把接收日志階段的隊(duì)列獨(dú)立出來(lái)看宅荤,在接入層和存儲(chǔ)層之間做一個(gè)過(guò)渡屑迂。

4.2 日志存儲(chǔ)系統(tǒng)

存儲(chǔ)日志是一個(gè)臟活累活,但是不得不做冯键。對(duì)于小應(yīng)用屈糊,單庫(kù)單表加優(yōu)化就可以應(yīng)付。一個(gè)成規(guī)模的應(yīng)用琼了,如果要提供更標(biāo)準(zhǔn)高效的日志監(jiān)控服務(wù)逻锐,常常需要在日志存儲(chǔ)架構(gòu)上下一些功夫。目前業(yè)界已經(jīng)有比較完備的日志存儲(chǔ)方案雕薪,主要有:Hbase系昧诱,Dremel系,Lucene系等所袁≌档担總體而言,日志存儲(chǔ)系統(tǒng)主要面對(duì)的問(wèn)題是數(shù)據(jù)量大燥爷,數(shù)據(jù)結(jié)構(gòu)不規(guī)律蜈亩,寫(xiě)入并發(fā)高,查詢需求大等前翎。一般一套日志存儲(chǔ)系統(tǒng)稚配,要解決上面這些問(wèn)題,就要解決寫(xiě)入的緩沖港华,存儲(chǔ)介質(zhì)按日志時(shí)間選擇道川,為方便快速讀取而設(shè)計(jì)合理的索引系統(tǒng)等等。

由于日志存儲(chǔ)系統(tǒng)方案比較成熟,這里就不再做更多討論冒萄。

4.3 搜索

日志的最終目的是要使用臊岸,由于一般日志的體量都非常大,因此尊流,要在龐大的數(shù)據(jù)中找到需要的日志記錄帅戒,需要依賴(lài)比較好的搜索引擎。Splunk是一套成熟的日志存儲(chǔ)系統(tǒng)崖技,但它是付費(fèi)使用的逻住。按照Splunk的框架,Elk是Splunk的開(kāi)源實(shí)現(xiàn)响疚,Elk是ElasticSearch鄙信、Logstash、Kibana的結(jié)合忿晕,ES基于Lucene的存儲(chǔ)装诡、索引的搜索引擎;logstash是提供輸入輸出及轉(zhuǎn)化處理插件的日志標(biāo)準(zhǔn)化管道践盼;Kibana提供可視化和查詢統(tǒng)計(jì)的用戶界面鸦采。

5 日志統(tǒng)計(jì)與分析

一個(gè)完善的日志統(tǒng)計(jì)分析工具需要提供各方面方便的面板,以可視化的方式給日志管理員和開(kāi)發(fā)者反饋信息咕幻。

5.1 用戶緯度

同一個(gè)用戶的不同請(qǐng)求實(shí)際上會(huì)形成不同的story線渔伯,因此,針對(duì)用戶的一系列操作設(shè)計(jì)唯一的request id是有必要的肄程。同一個(gè)用戶在不同終端進(jìn)行操作時(shí)锣吼,也能進(jìn)行區(qū)分。用戶在進(jìn)行某個(gè)操作時(shí)的狀態(tài)蓝厌、權(quán)限等信息玄叠,也需要在日志系統(tǒng)中予以反應(yīng)。

5.2 時(shí)間維度

一個(gè)異常是怎么發(fā)生的拓提,需要將異常操作的前后story線串聯(lián)起來(lái)觀察读恃。它不單單涉及一個(gè)用戶的一次操作,甚至不限于某一個(gè)頁(yè)面代态,而是一連串事件的最終結(jié)果寺惫。

5.3 性能維度

應(yīng)用運(yùn)行過(guò)程中的性能情況,例如蹦疑,界面加載時(shí)間西雀,api請(qǐng)求時(shí)長(zhǎng)統(tǒng)計(jì),單元計(jì)算的消耗必尼,用戶呆滯時(shí)間蒋搜。

5.4 運(yùn)行環(huán)境維度

應(yīng)用及服務(wù)所運(yùn)行的環(huán)境情況篡撵,例如應(yīng)用所在的網(wǎng)絡(luò)環(huán)境判莉,操作系統(tǒng)豆挽,設(shè)備硬件信息等,服務(wù)器cpu券盅、內(nèi)存狀況帮哈,網(wǎng)絡(luò)、寬帶使用情況等锰镀。

5.4 細(xì)粒度代碼追蹤

異常的代碼stack信息娘侍,定位到發(fā)生異常的代碼位置和異常堆棧。

5.6 場(chǎng)景回溯

通過(guò)將異常相關(guān)的用戶日志連接起來(lái)泳炉,以動(dòng)態(tài)的效果輸出發(fā)生異常的過(guò)程憾筏。

6 監(jiān)控與通知

對(duì)異常進(jìn)行統(tǒng)計(jì)和分析只是基礎(chǔ),而在發(fā)現(xiàn)異常時(shí)可以推送和告警花鹅,甚至做到自動(dòng)處理氧腰,才是一個(gè)異常監(jiān)控系統(tǒng)應(yīng)該具備的能力。

6.1 自定義觸發(fā)條件的告警

a. 監(jiān)控實(shí)現(xiàn)

當(dāng)日志信息進(jìn)入接入層時(shí)刨肃,就可以觸發(fā)監(jiān)控邏輯古拴。當(dāng)日志信息中存在較為高級(jí)別的異常時(shí),也可以立即出發(fā)告警真友。告警消息隊(duì)列和日志入庫(kù)隊(duì)列可以分開(kāi)來(lái)管理黄痪,實(shí)現(xiàn)并行。

對(duì)入庫(kù)日志信息進(jìn)行統(tǒng)計(jì)盔然,對(duì)異常信息進(jìn)行告警桅打。對(duì)監(jiān)控異常進(jìn)行響應(yīng)。所謂監(jiān)控異常愈案,是指:有規(guī)律的異常一般而言都比較讓人放心挺尾,比較麻煩的是突然之間的異常。例如在某一時(shí)段突然頻繁接收到D級(jí)異常刻帚,雖然D級(jí)異常是不緊急一般重要潦嘶,但是當(dāng)監(jiān)控本身發(fā)生異常時(shí),就要提高警惕崇众。

b. 自定義觸發(fā)條件

除了系統(tǒng)開(kāi)發(fā)時(shí)配置的默認(rèn)告警條件掂僵,還應(yīng)該提供給日志管理員可配置的自定義觸發(fā)條件。

  • 日志內(nèi)含有什么內(nèi)容時(shí)
  • 日志統(tǒng)計(jì)達(dá)到什么度顷歌、量時(shí)
  • 向符合什么條件的用戶告警

6.2 推送渠道

可選擇的途徑有很多锰蓬,例如郵件、短信眯漩、微信芹扭、電話麻顶。

6.3 推送頻率

針對(duì)不同級(jí)別的告警,推送的頻率也可以進(jìn)行設(shè)定舱卡。低風(fēng)險(xiǎn)告警可以以報(bào)告的形式一天推送一次辅肾,高風(fēng)險(xiǎn)告警10分鐘循環(huán)推送,直到處理人手動(dòng)關(guān)閉告警開(kāi)關(guān)轮锥。

6.4 自動(dòng)報(bào)表

對(duì)于日志統(tǒng)計(jì)信息的推送矫钓,可以做到自動(dòng)生成日?qǐng)?bào)、周報(bào)舍杜、月報(bào)新娜、年報(bào)并郵件發(fā)送給相關(guān)群組。

6.5 自動(dòng)產(chǎn)生bug工單

當(dāng)異常發(fā)生時(shí)既绩,系統(tǒng)可以調(diào)用工單系統(tǒng)API實(shí)現(xiàn)自動(dòng)生成bug單概龄,工單關(guān)閉后反饋給監(jiān)控系統(tǒng),形成對(duì)異常處理的追蹤信息進(jìn)行記錄饲握,在報(bào)告中予以展示私杜。

7 修復(fù)異常

7.1 sourcemap

前端代碼大部分情況都是經(jīng)過(guò)壓縮后發(fā)布的,上報(bào)的stack信息需要還原為源碼信息互拾,才能快速定位源碼進(jìn)行修改歪今。

發(fā)布時(shí),只部署js腳本到服務(wù)器上颜矿,將sourcemap文件上傳到監(jiān)控系統(tǒng)寄猩,在監(jiān)控系統(tǒng)中展示stack信息時(shí),利用sourcemap文件對(duì)stack信息進(jìn)行解碼骑疆,得到源碼中的具體信息田篇。

但是這里有一個(gè)問(wèn)題,就是sourcemap必須和正式環(huán)境的版本對(duì)應(yīng)箍铭,還必須和git中的某個(gè)commit節(jié)點(diǎn)對(duì)應(yīng)泊柬,這樣才能保證在查異常的時(shí)候可以正確利用stack信息,找到出問(wèn)題所在版本的代碼诈火。這些可以通過(guò)建立CI任務(wù)兽赁,在集成化部署中增加一個(gè)部署流程,以實(shí)現(xiàn)這一環(huán)節(jié)冷守。

7.2 從告警到預(yù)警

預(yù)警的本質(zhì)是刀崖,預(yù)設(shè)可能出現(xiàn)異常的條件,當(dāng)觸發(fā)該條件時(shí)異常并沒(méi)有真實(shí)發(fā)生拍摇,因此亮钦,可以趕在異常發(fā)生之前對(duì)用戶行為進(jìn)行檢查,及時(shí)修復(fù)充活,避免異撤淅颍或異常擴(kuò)大蜡娶。

怎么做呢?其實(shí)就是一個(gè)統(tǒng)計(jì)聚類(lèi)的過(guò)程映穗。將歷史中發(fā)生異常的情況進(jìn)行統(tǒng)計(jì)窖张,從時(shí)間、地域男公、用戶等不同維度加以統(tǒng)計(jì)荤堪,找出規(guī)律合陵,并將這些規(guī)律通過(guò)算法自動(dòng)加入到預(yù)警條件中枢赔,當(dāng)下次觸發(fā)時(shí),及時(shí)預(yù)警拥知。

7.3 智能修復(fù)

自動(dòng)修復(fù)錯(cuò)誤踏拜。例如,前端要求接口返回?cái)?shù)值低剔,但接口返回了數(shù)值型的字符串速梗,那么可以有一種機(jī)制,監(jiān)控系統(tǒng)發(fā)送正確數(shù)據(jù)類(lèi)型模型給后端襟齿,后端在返回?cái)?shù)據(jù)時(shí)姻锁,根據(jù)該模型控制每個(gè)字段的類(lèi)型。

8 異常測(cè)試

8.1 主動(dòng)異常測(cè)試

撰寫(xiě)異常用例猜欺,在自動(dòng)化測(cè)試系統(tǒng)中位隶,加入異常測(cè)試用戶。在測(cè)試或運(yùn)行過(guò)程中开皿,每發(fā)現(xiàn)一個(gè)異常涧黄,就將它加入到原有的異常用例列表中。

8.2 隨機(jī)異常測(cè)試

模擬真實(shí)環(huán)境赋荆,在模擬器中模擬真實(shí)用戶的隨機(jī)操作笋妥,利用自動(dòng)化腳本產(chǎn)生隨機(jī)操作動(dòng)作代碼,并執(zhí)行窄潭。

定義異常春宣,例如彈出某個(gè)彈出框,包含特定內(nèi)容時(shí)嫉你,就是異常月帝。將這些測(cè)試結(jié)果記錄下來(lái),再聚類(lèi)統(tǒng)計(jì)分析均抽,對(duì)防御異常也很有幫助嫁赏。

9 部署

9.1 多客戶端

一個(gè)用戶在不同終端上登錄,或者一個(gè)用戶在登錄前和登錄后的狀態(tài)油挥。通過(guò)特定算法生成requestID潦蝇,通過(guò)該requestId可以確定某個(gè)用戶在獨(dú)立客戶端上的一系列操作款熬,根據(jù)日志時(shí)序,可以梳理出用戶產(chǎn)生異常的具體路徑攘乒。

9.2 集成便捷性

前端寫(xiě)成包贤牛,全局引用即可完成大部分日志記錄、存儲(chǔ)和上報(bào)则酝。在特殊邏輯里面殉簸,可以調(diào)用特定方法記錄日志。

后端與應(yīng)用本身的業(yè)務(wù)代碼解耦沽讹,可以做成獨(dú)立的服務(wù)般卑,通過(guò)接口和第三方應(yīng)用交互。利用集成部署爽雄,可以將系統(tǒng)隨時(shí)進(jìn)行擴(kuò)容蝠检、移植等操作。

9.3 管理系統(tǒng)的可擴(kuò)展

整套系統(tǒng)可擴(kuò)展挚瘟,不僅服務(wù)單應(yīng)用叹谁,可支持多個(gè)應(yīng)用同時(shí)運(yùn)行。同一個(gè)團(tuán)隊(duì)下的所有應(yīng)用都可以利用同一個(gè)平臺(tái)進(jìn)行管理乘盖。

9.4 日志系統(tǒng)權(quán)限

不同的人在訪問(wèn)日志系統(tǒng)時(shí)權(quán)限不同焰檩,一個(gè)訪問(wèn)者只能查看自己相關(guān)的應(yīng)用,有些統(tǒng)計(jì)數(shù)據(jù)如果比較敏感订框,可以單獨(dú)設(shè)置權(quán)限析苫,敏感數(shù)據(jù)可脫敏。

10 其他

10.1 性能監(jiān)控

異常監(jiān)控主要針對(duì)代碼級(jí)別的報(bào)錯(cuò)布蔗,但也應(yīng)該關(guān)注性能異常藤违。性能監(jiān)控主要包括:

  • 運(yùn)行時(shí)性能:文件級(jí)、模塊級(jí)纵揍、函數(shù)級(jí)顿乒、算法級(jí)
  • 網(wǎng)絡(luò)請(qǐng)求速率
  • 系統(tǒng)性能

10.2 API Monitor

后端API對(duì)前端的影響也非常大,雖然前端代碼也控制邏輯泽谨,但是后端返回的數(shù)據(jù)是基礎(chǔ)璧榄,因此對(duì)API的監(jiān)控可以分為:

  • 穩(wěn)定性監(jiān)控
  • 數(shù)據(jù)格式和類(lèi)型
  • 報(bào)錯(cuò)監(jiān)控
  • 數(shù)據(jù)準(zhǔn)確性監(jiān)控

10.3 數(shù)據(jù)脫敏

敏感數(shù)據(jù)不被日志系統(tǒng)采集。由于日志系統(tǒng)的保存是比較開(kāi)放的吧雹,雖然里面的數(shù)據(jù)很重要骨杂,但是在存儲(chǔ)上大部分日志系統(tǒng)都不是保密級(jí),因此雄卷,如果應(yīng)用涉及了敏感數(shù)據(jù)搓蚪,最好做到:

  • 獨(dú)立部署,不和其他應(yīng)用共享監(jiān)控系統(tǒng)
  • 不采集具體數(shù)據(jù)丁鹉,只采集用戶操作數(shù)據(jù)妒潭,在重現(xiàn)時(shí)悴能,通過(guò)日志信息可以取出數(shù)據(jù)api結(jié)果來(lái)展示
  • 日志加密,做到軟硬件層面的加密防護(hù)
  • 必要時(shí)雳灾,可采集具體數(shù)據(jù)的ID用于調(diào)試漠酿,場(chǎng)景重現(xiàn)時(shí),用mock數(shù)據(jù)替代谎亩,mock數(shù)據(jù)可由后端采用假的數(shù)據(jù)源生成
  • 對(duì)敏感數(shù)據(jù)進(jìn)行混淆

結(jié)語(yǔ)

本文主要是對(duì)前端異常監(jiān)控的整體框架進(jìn)行了研究炒嘲,沒(méi)有涉及到具體的技術(shù)實(shí)現(xiàn),涉及前端部分和后臺(tái)部分以及與整個(gè)問(wèn)題相關(guān)的一些知識(shí)點(diǎn)匈庭,主要關(guān)注前端部分夫凸,它和后端的監(jiān)控有重疊部分也有分支部分,需要在一個(gè)項(xiàng)目中不斷實(shí)踐嚎花,總結(jié)出項(xiàng)目本身的監(jiān)控需求和策略寸痢。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市紊选,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌道逗,老刑警劉巖兵罢,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異滓窍,居然都是意外死亡卖词,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)吏夯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)此蜈,“玉大人,你說(shuō)我怎么就攤上這事噪生●烧裕” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵跺嗽,是天一觀的道長(zhǎng)战授。 經(jīng)常有香客問(wèn)我,道長(zhǎng)桨嫁,這世上最難降的妖魔是什么植兰? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮璃吧,結(jié)果婚禮上楣导,老公的妹妹穿的比我還像新娘。我一直安慰自己畜挨,他們只是感情好筒繁,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開(kāi)白布彬坏。 她就那樣靜靜地躺著,像睡著了一般膝晾。 火紅的嫁衣襯著肌膚如雪栓始。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,071評(píng)論 1 285
  • 那天血当,我揣著相機(jī)與錄音幻赚,去河邊找鬼。 笑死臊旭,一個(gè)胖子當(dāng)著我的面吹牛落恼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播离熏,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼佳谦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了滋戳?” 一聲冷哼從身側(cè)響起钻蔑,我...
    開(kāi)封第一講書(shū)人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎奸鸯,沒(méi)想到半個(gè)月后咪笑,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡娄涩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年窗怒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蓄拣。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扬虚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出球恤,到底是詐尸還是另有隱情辜昵,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布碎捺,位于F島的核電站路鹰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏收厨。R本人自食惡果不足惜晋柱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望诵叁。 院中可真熱鬧雁竞,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至进栽,卻和暖如春德挣,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背快毛。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工格嗅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唠帝。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓屯掖,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親襟衰。 傳聞我的和親對(duì)象是個(gè)殘疾皇子贴铜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容