매립 포인트 시스템에 대한 사전 탐색

coldplay.xixi
풀어 주다: 2020-09-15 16:24:55
앞으로
2588명이 탐색했습니다.

매립 포인트 시스템에 대한 사전 탐색

관련 학습 권장사항: javascript 비디오 튜토리얼

머리말

최근에는 이전 시리즈를 보충할 시간을 찾기가 어렵습니다. 이제 도약을 시작합니다

영화 속 시스템

에 집중해야 하는 이유

프론트엔드 개발 시즈라이온 즐겁게 코딩하고 있으며, 비즈니스와 UI의 별도 개발, 다양한 디자인 패턴, 알고리즘 최적화, 완벽함을 매우 자랑스럽게 생각합니다. 코드작성(노동법세계최초), BUG가 없고, 프로그램이 완벽하고, 호환성 1위, 코드 입력 및 저항이 가능하고, 품질이 높습니다. 퇴근 후 쉽게 출근하여 집에 가서 아기를 돌볼 수 있습니다.

실제로는

사실 개발 환경과 프로덕션 환경이 같지 않고, 아무리 테스트 과정이 완벽해도 테스트를 놓치는 경우가 있기 마련입니다. 사용자의 클라이언트 환경, 네트워크 환경 등 일련의 불확실한 요소의 존재를 고려합니다. 그래서 개발 과정에서 세 가지 주요 원칙을 꼭 기억해야 합니다. (

말도 안 되는 소리만 하고 있어요

)

    완벽한 코드는 없고, 발견되지 않은 버그만 있을 뿐입니다
  1. 테스트 환경을 절대 믿지 마세요
  2. , 있습니다. 어떤 종류의 테스트 환경도 없습니다. 모든 온라인 상황이 커버됩니다온라인에서 피드백이 없다면 의심하지 마세요. 문제는 아주 깊게 숨겨져 있어야 합니다
  3. 매장 포인트 시스템이 무엇인가요?

매장 포인트는 카메라와 같습니다. 도시에서 제품 관점에서 제품에 대한 사용자의 행동 궤적을 모니터링하여 제품 반복 및 프로젝트 안정성의 기반을 제공할 수 있다고 생각하세요.

데이터 수집의 기본 차원은 누구, 언제, 어디서, 어떻게, 무엇입니까

. 프런트 엔드 개발을 위해 페이지 리소스 로딩 성능, 예외 등을 모니터링하고, 페이지 경험 및 상태 지수를 제공하고, 후속 성능 최적화를 위한 기반을 제공하고, 예외 및 발생 시나리오를 적시에 보고할 수 있습니다. 이를 통해 적시에 문제를 수정하고 프로젝트 품질을 향상시킬 수 있습니다.

매장 포인트는 크게 3가지로 나눌 수 있습니다.

    추적 없는 매매 포인트
  1. - 페이지 진입 및 퇴장, 이벤트 클릭 등 페이지의 모든 정보가 무차별적으로 수집됩니다. 유용한 정보를 얻으려면 데이터 플러시가 필요합니다
  2. 시각적 매립 포인트
  3. - 생성된 페이지 구조를 바탕으로 특정 포인트를 획득하고, 별도로 포인트를 매립하여 분석합니다.
  4. 비즈니스 코드에 대한 수동 매립 포인트
  5. - 특정하고 복잡한 업종에 따라 커버할 수 없는 부분을 제거합니다.
일반적인 시나리오장점불충분

대부분의 경우 추적 없는 매설점을 통해 모든 정보 데이터를 수집한 후 시각적 매설점과 협력하여 특정 지점을 구체적으로 찾아내면 대부분의 매설점 정보가 이에 따라 분석될 수 있습니다.

특별한 상황에서는 비즈니스 코드를 더 추가하여 포인트를 수동으로 묻어 특별한 시나리오를 처리할 수 있습니다(대부분의 경우 강력한 비즈니스 및 정상적인 클릭 및 새로 고침 이벤트는 보고해야 하는 정보와 관련이 없습니다)

Bury SDK 개발

Bury Point 데이터 수집 및 분석

  • 이벤트 기본 데이터
    • 이벤트 시간
    • 발생 시 페이지 정보 스냅샷
  • Page
    • Page PV, UV
    • 사용자 페이지 길이 stay
    • 페이지 점프 이벤트
    • 페이지가 배경으로 들어갑니다
    • 사용자가 페이지를 떠납니다
  • 사용자 정보
    • 사용자 uid
    • 사용자 기기 지문
    • 기기 정보
    • ip
    • 포지셔닝
  • 사용자 작업 동작
    • 사용자 클릭
      • 대상 클릭
  • 페이지 AJAX 요청
    • 요청 성공
    • 요청 실패
    • 요청 시간 초과
  • 페이지 오류 보고
    • 리소스 로드 오류 보고
    • JS 실행 오류 보고
  • 새로운 리소스 로딩 성능
  • Pictures
  • Script
  • 페이지 로딩 성능

위 데이터는 3차원

  • ·LEVEL을 통해 숨겨진 이벤트를 정의합니다. 묻힌 데이터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

function NewXHR() {  var realXHR: any = new OldXHR(); // 代理模式里面有提到过
  realXHR.id = guid()  const oldSend = realXHR.send;

  realXHR.send = function (body) {
    oldSend.call(this, body)    //记录埋点
  }
  realXHR.addEventListener('load', function () {    //记录埋点
  }, false);
  realXHR.addEventListener('abort', function () {    //记录埋点
  }, false);

  realXHR.addEventListener('error', function () {    //记录埋点
  }, false);
  realXHR.addEventListener('timeout', function () {    //记录埋点
  }, false);  return realXHR;
}复制代码
로그인 후 복사

代理 Fetch

 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
    })
  }复制代码
로그인 후 복사

监听页面的 PVUV

在进入页面时,我们通过算法生成一个唯一 session id,作为这次埋点行为的全局 id,上报用户 id,设备指纹,设备信息。在用户未登录的情况下,通过设备指纹来计算 UV,通过 session id计算 PV

异常捕获

异常就是干扰程序的正常流程的不寻常事故

RUNTIME ERROR

JS中可以通过 window.onerrorwindow.addEventListener('error', callback) 捕捉运行时异常,一般使用window.onerror,它兼容性更好。

window.onerror = function(message, url, lineno, columnNo, error) {    const lowCashMessage = message.toLowerCase()    if(lowCashMessage.indexOf('script error') > -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,跨域资源共享),如下步骤
    • <srcipt src="another domain/main.js" cossorigin="anonymous"></script>
    • 修改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 在异步异常时无法通过 onerrorunhandledrejectionINFO: 일부 사용자 작업, 요청 성공, 리소스 로딩 등 일반 데이터 기록

🎜ERROR: JS 오류 보고, 인터페이스 오류 보고 등 데이터 오류 유형 기록🎜🎜DEBUG: 예약된 개발자는 수동 호출을 사용하여 버그를 제거하기 위해 데이터 레코드를 반환할 수 있습니다🎜🎜WARN: 개발자가 수동 호출을 사용하여 반환하도록 예약되어 있습니다. 비정상적인 사용자 행위에 대한 데이터 기록🎜🎜🎜🎜CATEGORY: 매장지 데이터의 분류를 설명합니다.🎜🎜TRACK: 매장지 SDK 객체의 라이프사이클이 전체 매장지 데이터를 관리합니다. 포인트 데이터. 🎜🎜WILL_MOUNT: SDK 객체가 초기화 및 로드되려고 하며 기본 ID가 생성되고 모든 관련 이벤트가 추적됩니다. 🎜🎜DID_MOUNTED: sdk 객체가 완료되었습니다. 주로 비동기적으로 기기 지문을 획득하는 등입니다. 작업 완료🎜🎜🎜🎜AJAX: AJAX 관련 데이터🎜🎜ERROR: 페이지의 예외 관련 데이터🎜🎜 PERFORMANCE: 성능 관련 데이터에 대한 정보 🎜🎜OPERATION: 사용자 작업 관련 데이터🎜🎜🎜🎜EVENT_NAME: 특정 이벤트 이름🎜🎜🎜🎜에 따르면 위의 차원을 사용하면 다음 아키텍처를 간단하게 설계할 수 있습니다🎜🎜 <그림>매립 포인트 시스템에 대한 사전 탐색
🎜위 그림의 구조에 따라 다음과 같은 구체적인 코드 개발을 진행합니다🎜

현재 브라우저에는 프록시 요청에 대한 두 가지 주요 요청 방법이 있습니다. 하나는 XMLHttpRequest이고 다른 하나는 Fetch입니다. 코드>. 🎜

프록시 XMLHttpRequest

window.addEventListener("unhandledrejection", event => {  throw event.reason
});复制代码
로그인 후 복사
로그인 후 복사

프록시 가져오기

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)复制代码
로그인 후 복사
로그인 후 복사

페이지의 PV, UV를 모니터링합니다🎜🎜페이지에 들어갈 때 알고리즘을 통해 고유한 세션 ID를 이 매립 행위 Global ID로 생성합니다. , 사용자 ID, 장치 지문, 장치 정보를 보고합니다. 사용자가 로그인하지 않은 경우 UV는 기기 지문을 통해 계산되고 PVsession id를 통해 계산됩니다. 🎜

예외 포착🎜🎜예외는 프로그램의 정상적인 흐름을 방해하는 비정상적인 사고입니다🎜

런타임 오류

🎜 JS에서는 window.onerrorwindow.addEventListener('error', callback)를 통해 런타임 예외를 캡처할 수 있습니다. >window가 사용됩니다. onerror는 호환성이 더 좋습니다. 🎜
window.addEventListener(&#39;click&#39;, (event) => {    //记录埋点}, true)复制代码
로그인 후 복사
로그인 후 복사

스크립트 오류

🎜여기에서는 주로 스크립트 페이지에 로드된 타사 교차 도메인으로 인해 발생하는 스크립트 오류를 필터링했습니다. 타사 CDN에서 호스팅되는 js 스크립트와 같은 오류를 보고합니다. 이러한 유형의 문제는 해결하기가 더 어렵습니다. 해결 방법은 다음과 같습니다. 🎜🎜🎜다음과 같이 CORS(교차 원본 리소스 공유, 도메인 간 리소스 공유)를 엽니다. 🎜🎜<srcipt src="another domain/main.js" cossorigin ="anonymous"></script>🎜🎜Access-Control-Allow-Origin 수정: * | 도메인 이름 지정🎜🎜🎜🎜 try catch 사용 code >
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;  // 记录埋点})复制代码
로그인 후 복사
로그인 후 복사
🎜🎜

Promise Reject

🎜js는 비동기 예외가 발생하는 경우 onerror 메서드로 캡처할 수 없습니다. 발생, Promise에서 객체가 거부되고 동시에 처리되지 않는 경우 위의 방법으로는 🎜 에러가 발생하고 catch되지 않으므로 별도의 처리 이벤트를 추가해야 합니다. 🎜
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培训栏目!


코드 매장지
Visual 매장지점 보이지 않는 매장지점
보이지 않는 매장지점은 커버할 수 없습니다. 그 비즈니스 데이터가 필요한 간단하고 표준화된 페이지 시나리오 간단하고 표준화된 페이지 시나리오,
비즈니스 데이터 명확성 낮은 개발 비용, 운영자가 관련 매장 지점을 직접 구성 가능 구성이 필요 없으며 데이터가 추적할 수 있음
데이터 추적 불가, 높은 개발 비용 비즈니스 데이터 연결 불가, 데이터 추적 불가 데이터 양이 많아 비즈니스 데이터 연결 불가

위 내용은 매립 포인트 시스템에 대한 사전 탐색의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:juejin.im
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿