基于webfunny实现的监控,埋点

107 阅读4分钟

背景:

  1. 监控,埋点体系的不完善,导致排查线上问题不能做到及时响应,定位不精准;
  2. 自定义场景欠缺,产品无法看到想要的数据模型;
  3. 用户行为分析能力欠缺,导致没法更好的提升用户体验;
  4. 缺少丰富的图表展现,导致没法直观的分析各项指标;

意义:

  1. 精准定位线上问题,及时响应;

  2. 收集数据信息,跟踪应用使用情况,进一步优化产品;

  3. 提供运营数据支撑;

  4. 分析用户行为,更好的满足用户需求;

主要内容

  • 监控接入
  • 自定义上报错误日志
  • 上报日志如何串联服务端
  • 动态注入探针代码
  • 埋点的诉求,标准定义
  • 埋点的具体实现(浏览量,曝光,点击)
  • 接入钉钉告警群

监控(h5/pc/web)

步骤一:探针代码引入项目

image.png

image.png

步骤二:设置全局变量wmUserInfo

image.png

用户进入系统设置默认的wmUserInfo,当用户登录或者用户信息发生变化时,更新用户信息

步骤一,二已经实现监控上报,如果需要自定义上报,请往下看:

步骤三: 自定义上报错误

  • 定义上报接口(upMylog)参数,封装全局自定义上报方法

image.png

  • 触发自定义上报

image.png

关于前段错误日志上报如何串联到服务端?

通过全局http拦截捕获到异常阶段,发起自定义上报,携带uniqueId

image.png

image.png

通过查找错误日志中的uniqueId,关联服务端

image.png

动态注入探针代码?

目前每个项目只有一套探针(生产),日志上报和埋点上报原则上只有在生产环境需要注入,故采用动态注入探针代码的方式,具体实现:

creatHtmlPlugin中采用inject注入index.html模版相应数据

image.png

埋点(h5/pc/web)

诉求

  • 无法灵活定义想要的场景
  • 缺少丰富的图表展示
  • 百度统计埋点的数据列表居多,很难直观的查到想要的数据

**
**

制定规则: 基于元素点击和曝光以及页面浏览基本可以满足当前的业务场景埋点

image.png

基础的数据图表: pv,uv,下单转化率,注册转化率,注册人数,应用的平均使用时间,日活,全栈流量等等

页面访问量,下单量等等

image.png

如何设置一个卡片,举个栗子:

image.png

如何在项目中接入埋点?

步骤一: 引入基于点位新建的sdk代码

image.png

参考 监控--步骤(一) 引入探针代码

步骤二: 定义全局的webFunnyEvent

image.png 步骤三: 上报埋点

  • 自定义指令实现元素点击和显示埋点

image.png

image.png

  • 路由拦截实现浏览量埋点

image.png

image.png

  • 元素曝光埋点
`/*`

` ``* @Description:`

` ``* @Author: yangxiao`

` ``* @Date: 2023-07-11 17:14:12`

` ``* @LastEditTime: 2023-07-11 19:00:04`

` ``* @LastEditors: yangxiao`

` ``*/`

`import ``'intersection-observer'``;`

 

 

`IntersectionObserver.prototype.POLL_INTERVAL = 300; ``// 节流时间为300毫秒`

 

`class Exposure {`

`  ``// _observerArr = [];`

`  ``constructor(maxNum) {`

`    ``this``.maxNum = maxNum;`

`    ``this``._observer = ``null``; ``// 监听对象`

`    ``this``.exposureList = {}; ``// 存储监听对象想要操作的数据,例如统计数据`

`    ``this``.init();`

`  ``}`

`  ``init() {`

`    ``console.log(``'exposure init!'``);`

`    ``const self = ``this``;`

`    ``this``._observer = ``new` `IntersectionObserver(``function` `(entries, observer) {`

`      ``// console.log(entries,'entriesentriesentries');`

`      ``// console.log(observer);`

 

`      ``entries.forEach(entry => {`

`        ``const id = entry.target.attributes[``'data-id'``].value || ``''``; ``// 可以通过id记录标示数据,id需唯一`

`        ``const exposureData = self.exposureList[id] || {};`

`        ``// 如果被监听元素显示在视窗内,并且有数据,没有开始时间,则添加开始时间,用作计算被监听元素在视窗停留的时间`

`        ``if` `(entry.isIntersecting && JSON.stringify(exposureData) !== ``'{}'` `&& !exposureData.start_time) {`

`          ``self.exposureList[id] = Object.assign(exposureData, {`

`            ``start_time: Date.now(),`

`          ``});`

`        ``}`

`        ``// 如果监听元素,从视窗消失,并且有统计数据,并且有开始时间`

`        ``if` `(!entry.isIntersecting && JSON.stringify(exposureData) !== ``'{}'` `&& exposureData.start_time) {`

`          ``const end_time = Date.now();`

`      ``// 如果被监听元素在视窗停留的时间大于300毫秒,则上报数据`

`          ``if` `(end_time - exposureData.start_time > 300) {`

`            ``let upData = {`

`              ``info: self.exposureList[id].info,`

`              ``time:end_time - exposureData.start_time`

`            ``}`

`            ``window.webfunnyEvent(15).trackEvent({`

`              ``puGuangXinXi: JSON.stringify(upData), ``// 曝光信息 | 类型:文本 | 描述:曝光信息`

`              ``puGuangId: id, ``// 曝光ID | 类型:文本 | 描述:曝光ID`

`            ``});`

`            ``console.log(``'触发曝光上报'``)`

`          ``}`

`          ``delete` `exposureData[``'start_time'``];`

`          ``self.exposureList[id] = exposureData;`

`        ``}`

`      ``});`

`    ``}, {`

`      ``root: ``null``, ```// 所监听对象的具体祖先元素,未传入值或值为`null`,则默认使用顶级文档的视窗。``

`      ``rootMargin: ``'0px 0px 0px 0px'``, ``// 计算交叉时添加到根(root)边界盒bounding box的矩形偏移量, 可以有效的缩小或扩大根的判定范围从而满足计算需要`

`      ``threshold: 0, ``// 一个包含阈值的列表, 按升序排列, 列表中的每个阈值都是监听对象的交叉区域与边界区域的比率。`

`    ``});`

`  ``}`

`  ``add(el, value, vnode) {`

`    ``if` `(``this``._observer) {`

`      ``console.log(``'add----:'``,value)`

`      ``// 使IntersectionObserver开始监听一个目标元素。`

`      ``this``._observer.observe(el);`

`      ``this``.exposureList[el.dataset.id] = {`

`        ``...value,`

`      ``};`

`    ``}`

`  ``}`

`  ``remove() {`

`    ``// 使IntersectionObserver对象停止监听工作`

`    ``this``._observer.disconnect();`

`  ``}`

`}`

`export ``default` `Exposure;`

<封装曝光指令>

image.png <调用曝光指令>

image.png 钉钉群告警接入

  • 创建警报规则

image.png

  • 设置警报规则,通知人员,webhook地址等等

image.png

  • webhook地址:钉钉群添加自定义机器人,获取webhook地址

image.png

注:如果无法接收到警报,设置关键词为 警报

image.png

**
**