日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

一文搞懂得物前端監控

來源: 責編: 時間:2023-11-08 22:40:20 292觀看
導讀一背景得物的服務端監控是比較全面和有效的,除了上報原始日志數據,還通過數據分析制定線上告警機制,調用鏈路分析,而針對前端項目這一塊,還是不夠全面的。對前端線上問題感應不及時,靠人肉發現,沒有告警機制等問題,所以就有個

一背景

得物的服務端監控是比較全面和有效的,除了上報原始日志數據,還通過數據分析制定線上告警機制,調用鏈路分析,而針對前端項目這一塊,還是不夠全面的。對前端線上問題感應不及時,靠人肉發現,沒有告警機制等問題,所以就有個前端監控這個項目。前端監控也確實很有必要,我們需要對線上的頁面有個全面的把控,而至于怎么做監控,做數據上報,以及數據分析,如何針對監控數據分析出有用的核心鏈路的告警等也能有個全面的認識。本文主要是介紹得物針對監控做了哪些事情以及對前端底層監控手段做個總結。

二監控類型

前端監控的范圍很廣,如監控性能,監控異常,監控告警等一系列的維度來確保我們的頁面和功能是正常的,在出現問題時研發可以及時做出響應,及時追蹤,定位問題。wig28資訊網——每日最新資訊28at.com

wig28資訊網——每日最新資訊28at.com

性能監控

wig28資訊網——每日最新資訊28at.com

目前前端平臺在性能監控和異常監控是分開的,性能監控有專門 SDK,去做上報和分析,聯合得物 App 端上一起做了性能優化和數據分析,這塊是獨立的。主要包括性能的上報,以及性能的優化手段。下圖是前端性能監控方面的數據展示效果。

圖片圖片wig28資訊網——每日最新資訊28at.com

總體來說性能監控是做的比較大的,而且監控對提高頁面的秒開是有實際優化指導意義的,離線包、預請求等都是優化手段。wig28資訊網——每日最新資訊28at.com

wig28資訊網——每日最新資訊28at.com

異常告警監控

wig28資訊網——每日最新資訊28at.com

針對異常監控也有單獨的平臺和 SDK 去承接和上報,下圖來展示收集一些異常信息,對異常信息進行分類,再通過設置告警機制來通知開發人員及時發現問題:

圖片圖片wig28資訊網——每日最新資訊28at.com

這些錯誤類的信息不一定是我們都需要關注的,有些疑難雜癥,但是有不影響頁面展示和功能的報錯,也是可以忽略的,要知道不是所有的錯誤都能被解決的,這個時候我們可以只關注那些影響我們頁面核心功能的部分,針對這部分做一個告警配置,例如:wig28資訊網——每日最新資訊28at.com

圖片圖片wig28資訊網——每日最新資訊28at.com

針對告警信息,再進一步對錯誤進行分析,找到能解決的問題,達到對頁面穩定性的把控。wig28資訊網——每日最新資訊28at.com

wig28資訊網——每日最新資訊28at.com

日常巡檢監控

wig28資訊網——每日最新資訊28at.com

還有一種比較特殊的場景,針對運營活動做的營銷會場,在各個配置的坑位去做巡檢,提前發現會場是否正常,有沒有白屏、API 異常等提前發現,然后聯系相應的人去人工處理。這種監控模式對于要投放出去的頁面做提前檢查是很有效果的,事實證明也確實如此,提前避免了很多線上問題,很厲害。

圖片圖片wig28資訊網——每日最新資訊28at.com

三監控知識梳理

上面幾個大類型的監控都是前端同學在監控方面做的努力和成果,涉及到的知識點也很多,同樣對于業務的把控和理解也很深入,很值得學習并了解,后面的內容就是針對監控做個梳理總結,了解下大致的實現方式。

wig28資訊網——每日最新資訊28at.com

前端監控的必要性

  • 用戶在訪問頁面的時候大致會經歷下面的階段:
  • 向服務端請求獲取靜態資源;
  • 瀏覽器加載資源;

資源加載成功之后頁面渲染繼續運行。wig28資訊網——每日最新資訊28at.com

這些階段都有報錯的可能,而前端要做的就是監控后面這階段:資源加載和頁面交互。wig28資訊網——每日最新資訊28at.com

做前端監控也有很多其他好處, 例如:wig28資訊網——每日最新資訊28at.com

  • 第一時間上報異常,解決問題;
  • 能夠比較完整的重現問題用戶的操作全流程路徑,方便開發者復現問題,定位問題;
  • 針對頁面的 PV、UV 等信息可以為產品和運營做推廣決策提供數據依據。

前端監控是很有必要的,通過監控,我們能在線上應用異常時,第一時間收到反饋,并及時止損。對業務的發展是有正向作用的。wig28資訊網——每日最新資訊28at.com

wig28資訊網——每日最新資訊28at.com

前端監控目標

wig28資訊網——每日最新資訊28at.com

保證穩定性(錯誤監控)

錯誤監控包括 JavaScript 代碼錯誤、Promsie 錯誤、接口(XHR,Fetch)錯誤、資源加載錯誤(Script,Link等)等,這些錯誤大多會導致頁面功能異常甚至白屏。wig28資訊網——每日最新資訊28at.com

提升用戶體驗(性能監控)

性能監控包括頁面的加載時間、接口響應時間等,側面反應了用戶體驗的好壞。wig28資訊網——每日最新資訊28at.com

  • 加載時間:頁面運行時各個階段的加載時間;
  • TTFB(Time To First Byte)(首字節時間):瀏覽器發起第一個請求到數據返回第一個字節所消耗的時間,這個時間包含了網絡請求時間、后端處理時間;
  • FP(First Paint)(首次繪制):首次繪制包括了任何用戶自定義的背景繪制,它是將第一個像素點繪制到屏幕的時刻;
  • FCP(First Content Paint)(首次內容繪制):首次內容繪制是瀏覽器將第一個 DOM 渲染到屏幕的時間,可以是任何文本、圖像、SVG 等的時間;
  • FMP(First Meaningful paint)(首次有意義繪制):首次有意義繪制是頁面可用性的量度標準;
  • LCP(Largest Contentful Paint):視窗內最大的圖片或者文本渲染的時間,當最大的內容塊渲染完的時候,基本上主內容都加載完了,與現有的頁面加載指標相比,與用戶體驗的相關性更好;
  • FID(First Input Delay)(首次輸入延遲):用戶首次和頁面交互到頁面響應交互的時間;
  • 卡頓:指超過 50ms 的長任務,具體的指標可以根據頁面的內容進行調節,一般 50ms 人眼就能感覺到卡頓。

針對業務進行統計

  • PV:Page View 即頁面瀏覽量或點擊量;
  • UV:指訪問某個站點的不同 IP 地址的人數;
  • 頁面的停留時間:用戶在每一個頁面的停留時間。

wig28資訊網——每日最新資訊28at.com

前端監控的流程

wig28資訊網——每日最新資訊28at.com

前端埋點(通過 SDK 給頁面的 DOM 都加上標記)

  • 數據上報(收集,存儲)
  • 分析和計算(將采集到的數據進行加工匯總)
  • 可視化展示(按照緯度將數據展示)
  • 監控報警(發現異常后按一定的條件觸發報警)

wig28資訊網——每日最新資訊28at.com

wig28資訊網——每日最新資訊28at.com

前端埋點方案

代碼埋點

代碼埋點,就是項目中引入埋點 SDK,手動在業務代碼中標記,觸發埋點事件進行上報。比如頁面中的某一個模塊的點擊事件,會在點擊事件的監聽中加入觸發埋點的代碼 this.$track('事件名', { 需要上傳的業務數據 }),將數據上報到服務器端。wig28資訊網——每日最新資訊28at.com

  • 優點:能夠在任何時刻,更精確的發送需要的數據信息,上報數據更靈活;
  • 缺點:工作量大,代碼侵入太強,過于耦合業務代碼,一次埋點的更改就要引起發版之類的操作。

這個方案也是我們實際項目中現有的方案。wig28資訊網——每日最新資訊28at.com

可視化埋點

通過可視化交互的手段,代替代碼埋點,可以新建、編輯、修改埋點。在組件和頁面的維度進行埋點的設計。wig28資訊網——每日最新資訊28at.com

將業務代碼和埋點代碼分離,提供一個可視化交互的頁面,輸入為業務代碼,通過這個可視化系統,可以在業務代碼中自定義的增加埋點事件,最后輸出的代碼耦合了業務代碼和埋點代碼。wig28資訊網——每日最新資訊28at.com

這個方案是可以解決第一種代碼埋點的痛點,也是我們目前正準備做的方案。wig28資訊網——每日最新資訊28at.com

無痕埋點

前端的任意一個事件都被綁定一個標識,所有的事件都被記錄下來,通過定期上傳記錄文件,配合文件解析,解析出來我們想要的數據,并生成可視化報告。wig28資訊網——每日最新資訊28at.com

無痕埋點的優點是采集全量數據,不會出現漏埋和誤埋等現象。缺點是給數據傳輸和服務器增加壓力,也無法靈活定制數據結構。針對業務數據的準確性不高。wig28資訊網——每日最新資訊28at.com

wig28資訊網——每日最新資訊28at.com

wig28資訊網——每日最新資訊28at.com

監控腳本

日志存儲

前端的埋點上報需要存儲起來,這個可以使用阿里云的日志服務,不需要投入開發就可以采集。wig28資訊網——每日最新資訊28at.com

新建一個項目比如:xxx-monitorwig28資訊網——每日最新資訊28at.com

新建一個存儲日志,根據阿里云的要求發起請求,攜帶需要上報的數據:wig28資訊網——每日最新資訊28at.com

http://${project}.${host}/logstores/${logStore}/trackwig28資訊網——每日最新資訊28at.com

圖片圖片wig28資訊網——每日最新資訊28at.com

代碼中調用 Track 上報日志:wig28資訊網——每日最新資訊28at.com

日志的上報可以封裝成公共的調用方式, monitor/utils/里面放所有的工具方法;wig28資訊網——每日最新資訊28at.com

tracker.js 的實現就是按照阿里云的上報格式發送請求,并帶上處理好的需要上報的業務數據即可,下面的都是固定的,在日志服務建好:wig28資訊網——每日最新資訊28at.com

圖片圖片wig28資訊網——每日最新資訊28at.com

實現一個 Tracker 類導出類的實例即可,這樣在監控的核心代碼中直接調用 tracker.send(data),核心實現代碼如下:wig28資訊網——每日最新資訊28at.com

// monitor/utils/get/track.js...class SendTrackLoger {  constructor() {    this.url = `http://${project}.${host}/logstores/${logStore}/track`    this.xhr = new XMLHttpRequest()  }  send(data = {}, callback) {    const logData = {...logData}    for(let key in logs) {      if (typeof logs[key] === 'number') {        logs[key] = `${logs[key]}` // 這是阿里云的要求,字段不能是數字類型      }    }    let body = JSON.stringify({      __logs__: [logs]    })    this.xhr.open('POST', this.url, true)    this.xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8')    this.xhr.setRequestHeader('x-log-apiversion', '0.6.0')    this.xhr.setRequestHeader('x-log-bodyrawsize', body.length)    this.xhr.onload = function() {      if (this.status >= 200 && this.status <= 300 || this.status === 304) {        callback && callback()      }    }    this.xhr.onerror = function(error) {      console.log(error)    }    this.xhr.send(body)  }}export default new SendTrackLoger()

這里展示的是自定義要上報的數據字段:wig28資訊網——每日最新資訊28at.com

圖片圖片wig28資訊網——每日最新資訊28at.com

監控錯誤

前端需要監控的錯誤有兩類:wig28資訊網——每日最新資訊28at.com

  • Javascript 錯誤(JS 錯誤,Promise 異常)
  • 監聽 Error 錯誤(資源加載錯誤)

腳本實現

新建一個 fronend-monitor  項目,這個項目就相當于我們的工程項目,監控的核心實現可以寫到項目里面,也可以抽成 SDK 的形式 Import 引入進來,這里先寫到項目中。wig28資訊網——每日最新資訊28at.com

webpack.config.js 用來打包項目,做接口數據 Mock,測試 XHR 請求監控接口錯誤等。wig28資訊網——每日最新資訊28at.com

const path = require('path')const HtmlWebpackPlugin = xxxmodule.exports = {  mode: 'development',  context: process.cwd(),  entry:'./src/index.js',  output: {    path: path.resolve(__dirname, 'dist'),    filename: 'monitor.js'  },  devServer: {    contentBase: path.resolve(__dirname, 'dist'),    before(router) {      router.get('/success', function(req, res) {        res.json({ id: 1 })      })      router.post('/error', function(req, res) {        res.sendStatus(500)      })    },  },  module: {},  plugins: [    new HtmlWebpackPlugin({      template: './src/index.html',      inject: "head"    })  ]}

新建一個 src/index.html 在這個里面寫一些問題代碼,然后測試監控的錯誤捕獲。wig28資訊網——每日最新資訊28at.com

// src/index.html<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta name="viewport" cnotallow="width=device-width, initial-scale=1.0">  <title>monitor</title></head><body>  <input id="jsErrorBtn" type="button" value="js 代碼錯誤" notallow="btnClick()" />  <input id="promiseErrorBtn" type="button" value="promise 錯誤" notallow="promiseClick()" />  <input id="successBtn" type="button" value="成功 ajax 請求" notallow="successAjax()" />  <input id="errorBtn" type="button" value="失敗 ajax 請求" notallow="errorAjax()" />  <script>    function btnClick() {      window.goods.type = 2    }    function promiseClick() {      new Promise((resolve, reject) => {        resolve(1)      }, () => {        console.log(123)      })    }    function successAjax() {      var xhr = new XMLHttpRequest()      xhr.open('GET', '/success',  true)      xhr.responseType = 'json'      xhr.onload = function () {        console.log(xhr.response)      }      xhr.send()    }    function errorAjax() {      var xhr = new XMLHttpRequest()      xhr.open('POST', '/error',  true)      xhr.responseType = 'json'      xhr.onload = function() {        console.log(xhr.response)      }      xhr.onerror = function(err) {        console.log(err)      }      xhr.send('name=123')    }</script></body></html>

上報未捕獲的 Javascript 錯誤

Javascript 錯誤分為 2 種:語法錯誤,資源家加載錯誤,這些錯誤都會被 window.addEventListener('error', function(event) {})捕獲,來判斷是否是資源加載錯誤。wig28資訊網——每日最新資訊28at.com

window.addEventListener('error', function(event) {    // 如果 target 是script link 等資源    if (event.target && (event.target.src || event.target.href)) {      const element = getElement(event.target || event.path)      tracker.send({        ...        title: document.title,        url: location.href,        timestamp: event.timeStamp,        userAgent: navigator.userAgent,        type: 'resourceError',        ...      })    } else {      tracker.send({        ...        title: document.title,        url: location.href,        timestamp: event.timeStamp,        userAgent: navigator.userAgent,        type: 'jsError',        ...      })    }  }, true)

代碼中未被捕獲的 Promise 錯誤,要監聽 unhandledrejection 事件 window.addEventListener('unhandledrejection', function(event) {})。wig28資訊網——每日最新資訊28at.com

// 監聽未捕獲的 promise 錯誤  window.addEventListener('unhandledrejection', function(event) {    // PromiseRejectionEvent    let message = ''    let stack = ''    const reason =  event.reason    let filename = ''    let lineno = ''    let colno = ''    if (reason) {      message = reason.message      stack = reason.stack      const match = stack.match(//s+at/s+(.+):(/d+):(/d+).+/)      filename = match[1]      lineno = match[2]      colno = match[3]    }    tracker.send({      ...      title: document.title,      url: location.href,      timestamp: event.timeStamp,      userAgent: navigator.userAgent,      type: 'promiseError',      ...    })  }, true)

接口異常上報

接口異常上報主要是攔截請求,攔截 XMLHttpRequest 對象,改寫 XHR 的 Open 和 Send 方法,將需要上報的數據發到阿里云存儲,監聽 Load,Error,Abort 事件,上報數據:wig28資訊網——每日最新資訊28at.com

// src/monitor/lib/xhr.jsimport tracker from '../utils/tracker'export default function injectXHR() {  // 獲取 window 上的 XMLHttpRequest 對象  const XMLHttpRequest = window.XMLHttpRequest  // 保存舊的open, send函數  const prevOpen = XMLHttpRequest.prototype.open  const prevSend = XMLHttpRequest.prototype.send  // 不可使用箭頭函數,不然會找不到 this 實例  XMLHttpRequest.prototype.open = function (method, url, async, username, password) {    // 重寫open,攔截請求    // 不攔截 track 本身以及 socket, 直接放行    if (!url.match(/logstores/) && !url.match(/sockjs/)) {      this.logData = { method, url, async, username, password }    }    return prevOpen.apply(this, arguments)  }  XMLHttpRequest.prototype.send = function (body) {    // 重寫 send,攔截有 logData 的請求,獲取 body 參數    if (this.logData) {      this.logData.body = body      let startTime = Date.now()      function handler(type) {        return function (event) {          // event: ProgressEvent          let duration = Date.now() - startTime          let status = this.status          let statusText = this.statusText          console.log(event)          tracker.send({            type: 'xhr',            eventType: type,            pathname: this.logData.url,            status: `${status} ${statusText}`,            duration: `${duration}`, // 接口響應時長            response: this.response ? JSON.stringify(this.response) : '',            params: body || '',          })        }      }      this.addEventListener('load', handler('load'), false)      this.addEventListener('error', handler('error'), false)      this.addEventListener('abort', handler('abort'), false)    }    return prevSend.apply(this, arguments)  }}

監控白屏

白屏就是頁面上什么東西也沒有,在頁面加載完成之后,如果頁面上的空白點很多,就說明頁面是白屏的,需要上報,這個上報的時機是:document.readyState === 'complete' 表示文檔和所有的子資源已完成加載,表示load(window.addEventListener('load')狀態事件即將被觸發。wig28資訊網——每日最新資訊28at.com

document.readyState 有三個值:loading(document正在加載),interactive(可交互,表示正在加載的狀態結束,但是圖像,樣式和框架之類的子資源仍在加載),complete 就是完成,所以監控白屏需要在文檔都加載完成的情況下觸發。wig28資訊網——每日最新資訊28at.com

// src/monitor/utils/onload.jsexport function onload(callback) {  if (document.readyState === 'complete') {    callback()  } else {    window.addEventListener('onload', callback)  }}

監控白屏的思路主要是:可以將可視區域中心點作為坐標軸的中心,在X、Y軸上各分 10 個點,找出這個 20 個坐標點上最上層的 DOM 元素,如過這些元素是包裹元素,空白點數就加一,包裹元素可以自定義比如 Html Body App Root Container Content 等,空白點數大于 0 就上報白屏日志。wig28資訊網——每日最新資訊28at.com

export default function computedBlankScreen() {  // 包裹玉元素列表  const wrapperSelectors = ['body', 'html', '#root', '#App']  // 空白節點的個數  let emptyPoints = 0  // 判斷20個點處的元素是否是包裹元素  function isWrapper(element) {    const selector = getSelector(element)    console.log(selector)    if (wrapperSelectors.indexOf(selector) >= 0) { // 表示是在包裹元素里面,空白點就要加一      emptyPoints++    }  }  onload(function() {    let xElements, yElements    for (let i = 0; i <=9; i++) {      xElements = document.elementFromPoint(window.innerWidth * i / 10, window.innerHeight / 2)      yElements = document.elementFromPoint(window.innerHeight * i / 10, window.innerWidth / 2)      // document.elementFromPoint 返回的是某一個坐標點的由到外的html元素的集合      isWrapper(xElements[0])      isWrapper(yElements[0])    }    if (emptyPoints >= 0) {      let centerPoint = document.elementFromPoint(window.innerWidth / 2, window.innerHeight / 2)      tracker.send()    }  })}

監控卡頓

用戶交互的響應時間如果大于某一個時間,用戶就會感覺卡頓。可以定一個時間比如 100 毫秒,就代表響應時間長,會卡頓。wig28資訊網——每日最新資訊28at.com

PerformanceObserver 構造函數使用給定的觀察者 Callback 生成新的PerformanceObserver 對象,當通過 Observe() 方法注冊條目類型(需要監控的類型)的性能條目被記錄下來時,會調用該觀察者回調。wig28資訊網——每日最新資訊28at.com

所以可以 new PerformanceObserver 來監控 longTask,監控的資源加載如果超過 100 毫秒就表示卡頓,可以瀏覽器空閑(requestIdleCallback)的時候上報數據。wig28資訊網——每日最新資訊28at.com

....export default function longTask() {  new PerformanceObserver(function(list) {    list.getEntries().forEach(function(entry) {      if (entry.duration > 100) {        // 瀏覽器空閑的時候上報        requestIdleCallback(() => {          tracker.send({            type: 'longTask',            eventType: lastEvent.type,            startTime: formatTime(entry.startTime),            duration: formatTime(entry.duration),          });        });      }    })  }).observe({ entryTypes: ['longtask']})}

性能指標

PerformanceObserver.observe 方法用于觀察傳入的參數中指定的性能條目類型的集合。當記錄一個指定類型的性能條目時,性能監測對象的回調函數將會被調用。performance.timing 記錄了從輸入 URL 到頁面加載完成的所有的時間,從這些字段中可以提取對對頁面性能的監控,通過分析這些指標來優化頁面的體驗,比如統計 FMP、LCP 等,具體可以查看 MDN。wig28資訊網——每日最新資訊28at.com

統計pv (頁面的停留時間)

navigator.connection 對象獲取網絡連接的信息:effectiveType(網絡類型),RTT(估算餓往返時間)等,還能通過監聽 window.addEventListener('unload')事件計算用戶在頁面的停留時間。wig28資訊網——每日最新資訊28at.com

import tracker from '../util/tracker';export function pv() {    var connection = navigator.connection;    tracker.send({        type: 'pv',        networkType: connection.effectiveType,  // 網絡類型        rtt: connection.rtt, // 往返時間        screen: `${window.screen.width}x${window.screen.height}` // 設備分辨率    });    let startTime = Date.now();    window.addEventListener('unload', () => {        let stayTime = Date.now() - startTime; // 頁面停留時間        tracker.send({            type: 'stayTime',            stayTime        });    }, false);}

四、總結

前端監控是一個成熟業務線的標配,目前最多的場景是監控 JS 錯誤,接口請求和性能優化,然后根據日志信息進行分析分類的可視化展示,在發生異常的時候通知到相應的業務開發,監控的性能指標給頁面的體驗優化提供數據對比和優化的方向。

wig28資訊網——每日最新資訊28at.com

參考文章:

  • https://juejin.cn/post/6939703198739333127
  • https://wicg.github.io/largest-contentful-paint/
  • https://developer.mozilla.org/zh-CN/docs/Web/API/PerformanceObserver/PerformanceObserver
  • https://developer.mozilla.org/zh-CN/docs/Web/API/Long_Tasks_API
  • https://developer.mozilla.org/zh-CN/docs/Web/API/PerformanceTiming
  • https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator

本文鏈接:http://www.www897cc.com/showinfo-26-17850-0.html一文搞懂得物前端監控

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 想要微信小程序+Uniapp?XBoot開源項目助你快速開發!

下一篇: 十個Python中的數據類型技巧

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 宁阳县| 冷水江市| 徐水县| 沂源县| 谢通门县| 越西县| 沙雅县| 吕梁市| 衢州市| 汶川县| 桓仁| 桃园市| 乌拉特前旗| 锦屏县| 鲁甸县| 南郑县| 宜兰县| 庄浪县| 轮台县| 舞阳县| 汝州市| 太仆寺旗| 大埔区| 宝清县| 白山市| 温宿县| 乌审旗| 阜宁县| 客服| 肥乡县| 河池市| 天水市| 荆州市| 玛沁县| 右玉县| 元谋县| 康保县| 沈阳市| 怀安县| 鱼台县| 武功县|