目錄
#前言
為什麼需要埋點系統
電影中
現實中
什麼是埋點系統
埋點SDK 開發
埋點資料收集分析
#在進入頁面時,我們透過演算法產生一個唯一
異常就是乾擾程式的正常流程的不尋常事故
<srcipt src= "another domain/main.js" cossorigin="anonymous"></script>
资源加载异常
监听用户行为
页面路由变化
监听页面离开
SDK 架构
数据流
项目结构
参考
结尾
首頁 web前端 js教程 初探埋點系統

初探埋點系統

Sep 15, 2020 pm 04:24 PM
javascript

初探埋點系統

相關學習推薦:javascript影片教學

#前言

最近雜七雜八的事情比較多,難得花時間彌補之前的系列,欠大家的埋設系列現在開始走起來

為什麼需要埋點系統

電影中

前端開發攻城獅開開心心的coding,非常自豪的進行了業務、UI 分離開發,各種設計模式、算法優化輪番上陣,代碼寫的Perfect(勞資代碼天下第一),沒有BUG,程序完美,兼容性No. 1,程式碼能打能抗品質高。下班輕鬆打卡,回家看娃。

現實中

實際上,開發環境與生產環境並不能等同,並且測試的過程再完善,依然會有漏測的情況存在。考慮到使用者使用客戶端環境、網路環境等等一系列的不確定因素存在。

所以在開發過程中一定要記得三大原則(我胡詌的

  1. 沒有完美的程式碼,只有沒發現的BUG
  2. 絕對不要相信測試環境,沒有一種測試環境都涵蓋所有線上情況
  3. 如果線上沒有一點回饋,不要懷疑,問題應該藏得很深、很深

什麼是埋點系統

埋點就像城市中的攝像頭,從產品的角度考慮,它可以監控到用戶在我們產品裡的行為軌跡,為產品的迭代、專案的穩定性提供依據,WHO、WHEN、WHERE、HOW、WHAT 是埋點擷取資料的基礎維度

對前端開發而言,可以監控頁面資源載入效能,異常等等,提供了頁面體驗和健康指數,為後續效能最佳化提供依據,及時回報異常和發生場景。從而能夠及時修正問題,提升專案品質等。

埋點可以大概分為三類:

  1. 無痕埋點 - 無差別收集頁面所有資訊包括頁面進出、事件點擊等等,需要進行資料沖洗才能取得有用資訊
  2. 視覺化埋點 - 根據產生的頁面結構取得特定點位,單獨埋點分析
  3. 業務程式碼手動埋點 - 根據具體複雜的業務,除掉上述兩種不能涵蓋的地方進行業務代碼埋點

程式碼埋點 視覺化埋點 無痕埋點
典型場景 無痕埋點無法覆寫到,例如需要業務資料 簡單規範的頁面場景 #簡單規範的頁面場景,
優勢 業務資料明確 開發成本低,營運人員可直接進行相關埋點配置 無需配置,資料可回溯
不足 資料不可回溯,開發成本高 無法關聯業務數據,資料不可回溯 資料量較大,無法關聯業務資料

大部分情況,我們可以透過無痕埋點收集到所有的資訊數據,再配合可視化埋點,能夠具體定位到某一個點位,這樣大部分的埋點資訊都據此分析出來。

在特殊情況下,可以多加上業務代碼手動埋點,處理一下特別的場景(大部分情況是走強業務與正常的點擊,刷新事件無關需要上報的信息)

埋點SDK 開發

埋點資料收集分析

  • 事件基本資料
    • 事件發生時間
    • 發生時頁面資訊快照
  • 頁面
    • 頁面PV,UV
    • 用戶頁面停留時間
    • 頁面跳轉事件
    • 頁面進入後台
    • 使用者離開頁面
  • 使用者資訊
    • 使用者uid
    • 使用者裝置指紋
    • 裝置資訊
    • ip
    • 定位
  • 使用者操作行為
    • 使用者點選
      • #點選目標
    ##頁面AJAX 請求
  • #請求成功
    • #請求失敗
    • 請求逾時
##頁面報錯

資源載入錯誤

JS 執行報錯
  • 資源載入新效能
    • 圖片腳本
    • 頁面載入效能
    • 上面的資料透過
    • 3 個維度來定義埋點事件
    • ·LEVEL : 描述埋點資料的日誌等級
  • INFO
  • :某些使用者操作,請求成功,資源載入等等正常的資料記錄
      ERROR
    • : JS報錯,介面報錯等等錯誤類型的資料記錄
        DEBUG
      • : 預留開發人員透過手動呼叫的方式回傳排除bug的資料記錄
      • WARN
      • : 預留開發人員透過手動呼叫的方式回傳非正常使用者行為的的資料記錄
      ##CATEGORY
    • :描述埋點資料的分類
    • TRACK
    • : 埋點SDK物件的生命週期管理整個埋點資料。
    • WILL_MOUNT
    • :sdk物件即將初始化加載,產生一個預設ID,追蹤全部相關事件
    • DID_MOUNTED
    • :sdk物件初始化完成,主要獲取設備指紋等等的非同步操作完成
    AJAX
  • : AJAX相關資料
  • ERROR
  • :頁面中的例外相關資料

PERFORMANCE: 關於效能相關資料

初探埋點系統#OPERATION
: 使用者操作相關資料

#EVENT_NAME
:具體的事件名稱

根據上述的維度,我們可以簡單設計如下的架構

##根據上圖的架構,再進行下面的具體程式碼開發

##在瀏覽器中現在主要有2種請求方式,一個是

XMLHttpRequest

, 一個是Fetch代理XMLHttpRequest<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>function NewXHR() { var realXHR: any = new OldXHR(); // 代理模式里面有提到过 realXHR.id = guid() const oldSend = realXHR.send; realXHR.send = function (body) { oldSend.call(this, body) //记录埋点 } realXHR.addEventListener(&amp;#39;load&amp;#39;, function () { //记录埋点 }, false); realXHR.addEventListener(&amp;#39;abort&amp;#39;, function () { //记录埋点 }, false); realXHR.addEventListener(&amp;#39;error&amp;#39;, function () { //记录埋点 }, false); realXHR.addEventListener(&amp;#39;timeout&amp;#39;, function () { //记录埋点 }, false); return realXHR; }复制代码</pre><div class="contentsignin">登入後複製</div></div>代理Fetch<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'> const oldFetch = window.fetch; function newFetch(url, init) { const fetchObj = { url: url, method: method, body: body, } ajaxEventTrigger.call(fetchObj, AJAX_START); return oldFetch.apply(this, arguments).then(function (response) { if (response.ok) { //记录埋点 } else { //上报错误 } return response }).catch(function (error) { fetchObj.error = error //记录埋点 throw error }) }复制代码</pre><div class="contentsignin">登入後複製</div></div>監聽頁面的

PV

UV

#在進入頁面時,我們透過演算法產生一個唯一

session id

,作為這次埋點行為的全域id,回報用戶id,裝置指紋,裝置資訊。在使用者未登入的情況下,透過裝置指紋來計算 UV,透過 session id計算 PV異常捕獲

異常就是乾擾程式的正常流程的不尋常事故

RUNTIME ERRORJS中可以通過

window.onerror
  • window.addEventListener('error', callback) 捕捉運行時異常,一般使用window.onerror
      ,它相容性更好。
    • window.onerror = function(message, url, lineno, columnNo, error) {    const lowCashMessage = message.toLowerCase()    if(lowCashMessage.indexOf(&#39;script error&#39;) > -1) {      return
          }    const detail = {      url: url    
            filename: filename,      columnNo: columnNo,      lineno: lineno,      stack: error.stack,      message: message
          }    //记录埋点}复制代码
      登入後複製
      Script Error
    • 在這裡我們過濾了
    • Script Error, 它產生的原因主要是頁面中載入的第三方跨域腳本報錯,例如託管在第三方CDN 中的js
    • 腳本。這類問題比較難以檢驗。解決的方法有:
  • 開啟CORS(Cross Origin Resource Sharing,跨域資源共享),如下步驟

修改Access-Control-Allow-Origin: * | 指定網域名稱

#使用###try catch###
  <script scr="crgt.js"></script> //加载crgt脚本,window.crgt = {getUser: () => string}
  try{      window.crgt.getUser();
  }catch(error) {      throw error // 输出正确的错误堆栈
  }复制代码
登入後複製
##########Promise reject#########js### 在非同步異常時無法通過###onerror### 方法捕獲,當Promise 物件在reject 時,同時並沒有進行處理時 會拋出一個 ###unhandledrejection### 的錯誤,並不會被上述的方法所捕獲,所以需要添加單獨的處理事件。 ###
window.addEventListener("unhandledrejection", event => {  throw event.reason
});复制代码
登入後複製

资源加载异常

在浏览器中,可以通过 window.addEventListener(&#39;error&#39;, callback) 的方式监听资源加载异常,比如 js 或者 css 脚本文件丢失。

window.addEventListener(&#39;error&#39;, (event) => {  if (event.target instanceof HTMLElement) {    const target = parseDom(event.target, [&#39;src&#39;]);    const detail = {      target: target,      path: parseXPath(target),
    }    //  记录埋点
  }
}, true)复制代码
登入後複製

监听用户行为

通过 addEventListener click 监听 click 事件

window.addEventListener(&#39;click&#39;, (event) => {    //记录埋点}, true)复制代码
登入後複製

在这里通过组件的 displaName 来定位元素的位置,displaName 表示组件的文件目录,比如 src/components/Form.js 文件导出的组件 FormItem 通过 babel plugin 自动添加属性 @components/Form.FormItem,或者使用者主动给组件添加 static 属性 displayName

页面路由变化

  • hashRouter 监听页面hash变化,对hash进行解析
window.addEventListener(&#39;hashchange&#39;, event => {  const { oldURL, newURL } = event;  const oldURLObj = url.parseUrl(oldURL);  const newURLObj = url.parseUrl(newURL);  const from = oldURLObj.hash && url.parseHash(oldURLObj.hash);  const to = newURLObj.hash && url.parseHash(newURLObj.hash);  if(!from && !to ) return;  // 记录埋点})复制代码
登入後複製

监听页面离开

通过 addEventListener beforeunload 监听离开页面事件

window.addEventListener(&#39;beforeunload&#39;, (event) => {    //记录埋点})复制代码
登入後複製

SDK 架构

class Observable {    constructor(observer) {
        observer(this.emit)
    }
    emit = (data) => {        this.listeners.forEach(listener => {
            listener(data)
        })
    }
    listeners = [];
    
    subscribe = (listener) => {        this.listeners.push(listeners);        return () => {            const index = this.listeners.indexOf(listener);            if(index === -1) {                return false
            }            
            this.listeners.splice(index, 1);            return true;
        }
     }
}复制代码
登入後複製
const clickObservable = new Observable((emit) => {    window.addEventListener(&#39;click&#39;, emit)
})复制代码
登入後複製

然而在处理 ajax,需要将多种数据组合在一起,需要进行 merg 操作,则显得没有那么优雅,也很难适应后续复杂的数据流的操作。

const ajaxErrorObservable = new Observable((emit) => {    window.addEventListener(AJAX_ERROR, emit)
})const ajaxSuccessObservable = new Observable((emit) => {    window.addEventListener(AJAX_SUCCESS, emit)
})const ajaxTimeoutObservable = new Observable((emit) => {    window.addEventListener(AJAX_TIMEOUT, emit)
})复制代码
登入後複製

可以选择 RxJS 来优化代码

export const ajaxError$ = fromEvent(window, &#39;AJAX_ERROR&#39;, true)export const ajaxSuccess$ = fromEvent(window, &#39;AJAX_SUCCESS&#39;, true)export const ajaxTimeout$ = fromEvent(window, &#39;AJAX_TIMEOUT&#39;, true)复制代码
登入後複製
ajaxError$.pipe(
    merge(ajaxSuccess$, ajaxTimeout$), 
    map(data=> (data) => ({category: &#39;ajax&#39;, data; data}))
    subscribe(data => console.log(data))复制代码
登入後複製

通过 merge, map 两个操作符完成对数据的合并和处理。

数据流

初探埋點系統

项目结构

  • core
    • event$ 数据流合并
    • snapshot 获取当前设备快照,例如urluserIDrouter
    • track 埋点类,组合数据流和日志。
  • logger
    • logger 日志类
      • info
      • warn
      • debug
      • error
  • observable
    • ajax
    • beforeUpload
    • opeartion
    • routerChange
    • logger
    • track

参考

  • www.alibabacloud.com/help/zh/doc…

结尾

自建埋点系统是一个需要前后端一起合作的事情,如果人力不足的情况下,建议使用第三方分析插件,例如 Sentry 就能足够满足大部分日常使用

但还是建议多了解,在第三方插件出现不能满足业务需求的时候,可以顶上。

想了解更多编程学习,敬请关注php培训栏目!

以上是初探埋點系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript與WebSocket:打造高效率的即時影像處理系統 JavaScript與WebSocket:打造高效率的即時影像處理系統 Dec 17, 2023 am 08:41 AM

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數

See all articles