前端監控系統Sentry搭建

Keelvin發表於2020-04-03

導語


本文將結合工作,描述一下前端監控系統Sentry搭建過程中,背景、設計、實現、思考四個方面的感悟及問題。


背景

監控是什麼

監控從字面含義來看包含兩方面內容:監,監測的是程式碼;控,控制的是質量。監控是工具而不是目的,不是為了具有功能而監控,而是要通過監控,真正瞭解頁面執行情況,以達到程式碼執行質量可控的目的。

監控不同於統計,統計關注的是一段時間內訪問情況的一個總和,對於實時性要求並不那麼高,可以延遲上報、累計上報;監控則恰恰相反,關注的是頁面執行時的情況。

整個大前端角度來講,監控的場景很多。比如:服務端監控介面的穩定性和效能;客戶端監控crash和APP效能;對Web前端來講,更加關注線上執行時的效能和報錯。

監控對於線上線下來說都是有意義的,線下我們可以支援自動化測試,上線前就發現程式碼執行時的一些明顯錯誤,這個可以做為線下防退化的參考依據。線上環境則更加複雜,不同的地域、裝置、網路、瀏覽框架等諸多因素,導致同樣的程式碼不同環境中執行時,結果可能會良莠不齊。我們希望瞭解這些情況,評估頁面哪裡需要優化。

搭建的緣由

公司內部現有統計平臺,如thunder,spy等通用的平臺,即可以收集效能指標,也可以收集前端異常資訊,但是收集的異常資訊大多做統計用途,關注有多少報錯資訊,或者某類錯誤有多少類別,一般不會包含具體報錯的詳細資訊。

前端還有一個特點,靜態資源會混淆後壓縮,如果執行錯誤,拿到的報錯堆疊資訊沒有太大含義,只會報第一行報了xx錯誤,假設有sourcemap,我們也只能藉助Chrome Devtools來看具體是哪兒錯誤,但往往線上的報錯,我們很難復現。

通過前面提到的兩個問題的收集:統計平臺報錯資訊收集不夠詳細,無法根據報錯反解原始碼錯誤行數,我們選擇基於開源Sentry在百度雲上搭建了一套前端異常監控服務。


設計

方案選擇

先來介紹一下Sentry功能。

Sentry是一個集中式日誌管理系統。可以做以下事情,而且是相比於其他系統做的不錯的地方。

  1. 豐富的SDK。不同語言、不同專案通過整合SDK。拿JS舉例,不僅僅收集詳細的使用者裝置資訊,而且記錄了使用者的操作行為,通過點選了XX按鈕,導致的報錯
  2. 根據收集的資料,進行報警配置,進而實現監控的閉環。
  3. 支援標籤功能,比如我們可以通過給錯誤統一攔截,增加標記CUID,後期在後臺平臺中同過CUID進行錯誤過濾
  4. 易於操作的後臺。Sentry提供了一套後臺管理系統,簡單易行
  5. API支援。所有操作介面都提供了API服務,使用者可以基於API進行介面自定義
  6. 活躍的社群。Sentry小組在Github上非常活躍,之前提Issuse 基本都是當天回覆解決的。


再來看下K8S

首先提一下當下流行的Docker(是一個開源的應用容器引擎),Docker有一句口號:Build Once , Run Anywhere. 也就是說一個環境可以通過一次編譯釋出,在任何支援Docker的環境中可以快速跑起來,這解決我們日常部署環境的痛苦。但是大家實踐的時候發現,如果想要將Docker應用於具體的業務實現,是存在困難的——編排、管理和排程等各個方面,都不容易。所以K8S(全稱:kubernetes,基於容器的叢集管理平臺)應運而生,應用於廣大的實際專案中


介紹一下百度雲。

廣告一波自家的提供的雲服務平臺:百度雲。百度雲提供了豐富的基礎服務支援,比如強大的容器服務CCE,域名解析分發服務ITM,資料分析服務Sugar等。我們可以基於百度雲提供的服務快速達成想要實現的內容。

  1. CCE提供基礎的K8S容器環境
  2. ITM 智慧域名解析排程,支援根據不同地域、網路選擇不同機房機器
  3. Sugar 可以根據資料庫資料,進行定製化報表拖拽式構建


整體架構

本身Sentry支援原始碼部署和容器(Docker、K8S)部署兩種方式,考慮到穩定性,想要實現多機器多機房部署、負載均衡、智慧排程等實際問題,基於百度雲提供的K8S服務,容器化部署了Sentry,如圖1。


前端監控系統Sentry搭建

圖1 :Sentry 百度雲部署架構


結合業務,繼續看一下Senty在整體專案中地位置,如圖2。


前端監控系統Sentry搭建

圖2 :專案整體架構圖

這種架構下的Sentry服務,有幾個優勢:

  1. 節省大量人力。基於百度雲K8S運維省去了 日常機器運維、資料庫、流量排程等人力成本;
  2. 節省大量機器。K8S運維,可以機器動態根據業務執行的情況,進行擴縮容;
  3. 基於開源專案,社群豐富,問題有群體討論,問題解決迅速;
  4. 覆蓋業務廣,核心的服務提供了資料收集和分析的能力,接入層可以自定義實現。


實現

平臺在梳理清楚了上面流程的基礎上,很快就搭建了起來。但是在平臺試執行活成中,監控的每個環節,不同程度的暴露除了一些問題。針對監控的每個流程環節,再次做了進一步的分析和優化。下面針對主要環節進行說明。

打點上報

監控資訊上報,主要依賴於SDK。以前端為例,Sentry本身提供了一個SDK,需要在頁面載入過程中,優先載入,進而實現儘可能多的錯誤捕獲。

<html>
	<head>
	<title>監控報警</title>
	<script src="https://xx/sentry.js"></script>
	</head>

	<body>
	......
	<body>
</html>複製程式碼



實踐過程中,發現打包後的sentry.js 有20K左右,如果放到頂部,對於追求頁面效能的頁面來講,是災難性的,因為JS放在頂部載入會阻塞頁面的渲染。於是這對這種情況,進行了SDK後置優化。

<html>
	<head>
	<title>監控報警</title>
	<script>
		let estack = err => {
			return win[ers].length < 10 ? win[ers].push(err) : false;
		};

		win.onerror = (a, b, c, d, error) => {
			estack(error);
			return true;
		};

		win.addEventListener('unhandledrejection', error => {
			error.preventDefault();
			estack(error);
			return true;
		});
	<script>
	</head>

	<body>
	<script src="https://xx/sentry.plus.js" async ></script>
	<body>
</html>複製程式碼



  1. 自定義攔截error和promise錯誤,頁面載入結束後,統一進行錯誤上報
  2. 擴充套件sentry.js,升級為sentry.plus.js ,支援發現原有錯誤的收集,進行資料詳細上報。

通過SDK的改造,大大減少了頁面對於效能方面的擔憂,更加放心的使用Sentry服務。

日誌採集

SDK整合之後,日誌採集通過一個POST介面請求實現。頁面執行時,如果報錯,會自動觸發通過介面傳送資料。

這時候是否需要支援取樣,成了一個需要考慮的問題。因為如果沒有采樣,同時趕上較大的業務量,極大概率觸發日誌採集功能,大量日誌上報,而有用資訊較少。這時候取樣就解決了這個問題。SDK本身是支援取樣的,初始化的時候,只需要進行簡單的配置

Sentry.init({
	dsn:'xxx',
	sample: 0.5 
});複製程式碼


這個抽樣,指的是專案執行時,每次觸發報錯後,是否要進行錯誤上報的一個概率。但是對於追求頁面效能的頁面來講,通常往往希望的是,SDK小流量接入。儘可能少的去影響所有頁面。我們目前頁面基於Php的Smarty模板進行的首屏渲染,所以改造了上報採集的方法:

{%assign var="random" value="{%math equation=rand(1,100)/100%}"|string_format:"%.2f"%}
{%assign var="sample" value="0.5"|string_format:"%.2f"%}
{%if $random < $sample%}
<script type="text/javascript" src="https://xx/sentry.plus.js?v={%$smarty.now%}" crossorigin="anonymous"></script>
{%/if%}複製程式碼


通過改造,又跟進一步減少了監控程式碼對業務的影響,業務更加方便的接入。


日誌儲存

本身Sentry使用的是PostgreSQL,K8S部署時,資料庫這裡通過配置,使用百度雲提供的資料庫服務。

postgresql:
  enabled: false
  nameOverride: sentry-postgresql
  postgresqlDatabase: sentry
  postgresqlHost: 192.168.1.1
  postgresqlPassword: xxx123
  postgresqlPort: 3306
  postgresqlUsername: sentrydb複製程式碼


資料庫的費用也是挺貴的,佔據了整體1/3資源的消費。業務接入的越多,儲存資料量越大,一開始買的50G空間,很快就滿了。

資料到底要不要,我分析了一下:對於報錯本身的資料,尤其是每個錯誤的詳細資訊,沒必要儲存那麼久,但是對於報表性質的內容,如報錯總體情況的同環比,需要儲存更早以前結果的。

第一種方法,土豪的做法:資料庫擴容,繼續增加投入購買。這種就是資金預算投入;

第二種做法:根據現有,收集錯誤的內容,把需要做報表的結果計算後單獨儲存,然後定期資料庫清理,比如可以起一個指令碼,進行定期請裡10天前資料。


這裡有一個小插曲,Sentry官方其實提供了清理資料庫的API,可以通過命令進行清理:

// 進入容器
docker exec -ti xxxx /bin/bash
// 清理
sentry cleanup  --days 0複製程式碼


資料雖然清理了,但是發現PG資料庫的容量沒有釋放,這是因為cleanup的使用delete命令刪除postgresql資料,但postgrdsql對於delete, update等操作,只是將對應行標誌為DEAD,並沒有真正釋放磁碟空間。通過以下命令,徹底清空。


sudo -u postgres vacuumdb -U postgres -d sentry -t nodestore_node -v -f --analyze複製程式碼


報表展現

前面也提到過,Sentry提供了簡單友好的後臺管理系統。專案概況中,可以體現資料的報表展現。如圖3。

前端監控系統Sentry搭建

圖3:大盤展現

實踐過程中,尤其是給老闆彙報的時候,發現只有這樣的一個展現報表是不夠的。經過調研發現百度雲提供Sugar服務。可以直接連結資料庫,對想要的資料自定義進行資料聚合,產出對應報表。這個產出需求還在調研中,不過產出的效果是非常令人期待的。配置內容如圖4,預期效果如圖5。


前端監控系統Sentry搭建

圖4:配置內容

前端監控系統Sentry搭建

圖5:預期效果

監控報警

做為監控的閉環,我們可以在Sentry後臺中,根據不同的規則,設定郵件報警。Sentry官方建議的郵件服務也不停在變更,最初的Exim4改為了mailgun,綜合考慮費用的問題,我們最終還是選擇docker搭建Exim4,然後郵件內容通過申請公司郵件安全組,白名單放開傳送郵件的機器。最終實現了錯誤資訊及時通知業務的功能。效果如圖6。


前端監控系統Sentry搭建

圖6:監控效果

以上就是在具體實踐過程中,關鍵路徑遇到的一些問題,分享給大家。


思考

監控的意義

盈利

公司的目的是盈利。一方面公司要控制成本,我們可以看到投入QA人力日益削減,另一方面又需要我們線上執行的程式碼更加穩定,有什麼辦法可以做到呢?一個高效的方法就是加強監控。

效率

通過監控,可以快速自主地發現問題。

可以將收集上來的資料進行分類篩選,然後設定報警告知。根據我們監控內容,設定不同的閾值,當達到閾值的時候,第一時間有效的通知到對應的研發人員,進行分析和修復。


通過監控,可以全方位瞭解頁面執行情況。

通過資訊收集,可以獲取到使用者訪問的區域、機型、APP版本等基礎使用者資訊,同時也可收集到頁面執行時的效能,要知道效能就是金錢(開啟速度一定程度上會影響使用者的去留)。


通過監控,可以指導後期專案開發。

經過一段時間的沉澱,我們收集過的錯誤,可以繪製出一個報表,統計出我們某段時間內問題產生的原因、報錯、解決方案。

規範

從研發流程上來看(如下圖所示),我們的專案不是完成上線就萬事大吉。需要監控頁面線上執行情況,根據監控的資料及時進行復盤,迴圈迭代優化,形成持續的研發閉環生態。

以上這些監控的意義,是日後流程機制的指南,是研發同學的行為準則,也是老闆、高工某些關鍵時刻做決策的參考內容之一。通過監控,更加直觀地、全方位立體化地瞭解產品。

中臺戰略

中臺是公司內部最近技術方面的戰略方向。在我看來:監控可以輸出一箇中臺的方案,各部門基於中臺服務進行定製化擴充套件

其實我們這裡分享的Sentry系統,就可以作為公司內部的一箇中臺服務進行輸出。各部門可以根據業務去定製SDK,也可以根據資料需求,自定義報表和報警。整個Sentry黑盒對外提供API服務,因為K8S帶來的便利性,只需要對應部門提供預算,申請機器,往K8S上面增加縮減即可。

市面上其實已經存在很多不同種類的監控工具。比如:frontjs、arms、嶽鷹等,但是很遺憾,發現大多是收費的。公司層面的產品,資料體量相對較大(但這方面的投入往往是值得的),有時資料產出較慢,結果往往階段性地被新產品替代,廠內現在有一些針對前端的監控平臺,諸如:天幕等,可能資料的採集、儲存、過濾、展現、報警等監控過程中的每個環節,都需要需要耗費的人力和財力,這些都還缺少一些中臺的思路。

總結

通過搭建和實現監控的整個過程,一方面充分體會到了雲服務提供的技術給產品帶來的便利,一定是未來的方向;另一方面,脫離業務的技術是不靠譜的,技術服務於業務,我們實現的技術一定要在業務中進行驗證,才會促進技術更加完善,更加解決業務的實際問題。



相關文章