侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

微信小程序数据统计和错误统计的实现方法

微信(小程序)  /  管理员 发布于 5年前   400

某些情况下我们需要对小程序某些用户的行为进行数据进行统计,比如统计某个页面的UV, PV等,统计某个功能的使用情况等。好让产品对于产品的整个功能有所了解。 在网页里,我们很多人都用过谷歌统计,小程序里也有一些第三方数据统计的库, 比如腾讯的MTA等等。 但是,第三方的数据统计库要么功能太简单,满足不了需求,要么就是要收费。(留下了贫穷的泪水。) 等等,又不是你出钱,怕啥? 贵一点就贵一点呀。

嗯,说的没错。但是,公司团队内部想实现一套完整的自己的数据统计系统以满足自己的需求。所以,还是没有用第三方的。

所以,具体要统计些啥?

产品经理

  • 想知道用户都是怎么进入我们的小程序的?
  • 用户在我们小程序里那个页面停留的时间最长?平均用户停留时间是多少?
  • 想知道我们最近开发的那个功能用的人多不多?
  • 想统计小程序里的一些按钮有多少用户点击了

开发自己

  • 总是很难复现用户端出现的bug,
  • 要是可以知道用户端发生错误时,知道用户当时的用的手机型号,微信版本,网络环境,页面参数,和错误信息就好了
  • 想知道我们小程序启动时间是多少?
  • 接口在用户端的平均响应时间是多少ms? 哪些接口报错了

针对产品经理的需求,我们可以知道,Ta想要的是就是数据统计要实现的功能。对于开发来说,我们关注的更多就是错误统小程序性能这块的东西。

好,到这里,我们需求是明白了。就是要实现一套既能统计普通的埋点数据,也要能统计到小程序里一些特殊触发的事件,比如appLaunch, appHide 等,还要可以统计错误。

好,那先来看看如何实现产品的需求吧

用户进入小程序可以在 小程序 onLaunch 回调里拿到参数 的scene 值,这样就可以知道用户是怎么进入小程序的了。小case, 难不到我。

嗯,第一个需求实现了,那如何统计第二个呢?如何统计某个页面的停留时间呢?

这也难不倒我,用户在进入页面时会触发onShow 事件, 同样,在离开页面(或者切后台时)会触发onHide事件,我只需要在onShow里记录一下时间,同时在onHide 里也记录一下时间,把两个时间一减就可以了。

Page({  data: {  beginTime: 0,  endTime: 0  },  onShow: function() {   // Do something when page show.   this.setData({   beginTime: new Date().getTime()   })  },  onHide: function() {   // Do something when page hide.   let stayTime = new Date().getTime() - this.beginTime;   // 这个就是用户在这个页面的停留时间了  }, })

等等,这样确实实现了需求,万一产品要统计所有也面的停留时长? 那我们岂不要在每一个页面都这样写一遍?有没有更好的方法呢?

好,接下来就是数据统计实现的要点了,即拦截微信原生事件,这样可以在某个特殊事件触发时,做一些我们统计的事情。同时,还要拦截微信发生网络请求的方法,这样可以拿到网络请求相关的数据,最后,为了能统计到错误,还需要拦截微信发生错误的方法。

1.特殊事件的监听

App(Object object)

注册小程序。接受一个 Object 参数,其指定小程序的生命周期回调等。

App() 必须在 app.js 中调用,必须调用且只能调用一次。不然会出现无法预期的后果。

  • 拦截全局的事件:
  • 下面是小程序官方文档对于App 注册方法的文档:
App({ onLaunch (options) { // Do something initial when launch. }, onShow (options) { // Do something when show. }, onHide () { // Do something when hide. }, onError (msg) { console.log(msg) }, globalData: 'I am global data'}) 

假如我们要在小程序onLaunch 时打印一句hello Word,我们有哪些方法实现?

方法1:

直接写在onLaunch方法里

onLaunch (options) {  console.log('hello World') }

方法2:

使用 monkey patch方法猴子补丁(monkey patch)

猴子补丁主要有以下几个用处:

  1. 在运行时替换方法、属性等
  2. 在不修改第三方代码的情况下增加原来不支持的功能
  3. 在运行时为内存中的对象增加patch而不是在磁盘的源代码中增加

举个栗子,假如我们在console.log 方法里都先打印出当前的时间戳,我们可以这样:

var oldLog = console.logconsole.log = function() { oldLog.call(this, new Date().getTime()) oldLog.apply(this, arguments)}

同理,我们针对onLaunch 进行猴子补丁

var oldAp = AppApp = function(options) { var oldOnLaunch = options.onLaunch options['onLaunch'] = function(t) { // 做一些我们自己想做的事情 console.log('hello word....') // 调用原来的onLaunch 方法 oldOnLaunch.call(this, t) }  // 调用原来的App 方法 oldApp(options)  // 想像一下,小程序内部调用onLaunch 方法应该是这样子的: options.onLaunch(params)}// 问题,有的时候,我们可能没有注册某一个事件,比如页面的onShow, 所有,我们在替换的时候还需要判断一下参数是否传了对应的方法Page({ onLoad (options) {}, onHide (options) {}})// 针对这种情况,我们需要这样写var oldPage = PagePage = function(options) { if (options['onShow']) { // 如过有注册onShow 这个回调 var oldOnShow = options.onShow // onShow 方法调用时都是 传了一个对象 options['onShow'] = function(t) {  // doSomething()  oldOnShow.call(this, t) } } // 调用原来的Page 方法。 oldPage.apply(null, [].slice.call(arguments)) // 注意: 下面这两种写都会报错: VM23356:1 Options is not object: {"0":{}} in pages/Badge.js 问题具体原因暂时未找到。 // oldPage.call(null, arguments) // oldPage(arguments)}

通过上面的方法,我们可以拦截了 App 方法注册的一些全局方法,比如 onLaunch , onShow, onHide, 和Page 注册的事件如 onShow, onHide, onLoad, onPullDownRefresh, 等页面注册事件。

2.网络请求的监听

思路: 拦截微信的请求事件。

let Request = {  request: function (e) {  let success = e[0].success,   fail = e[0].fail,   beginTime = smaUtils.getTime(),   endTime = 0  // 拦截请求成功方法  e[0].success = function () {   endTime = smaUtils.getTime()   const performance = {   type: constMap.performance,   event: eventMap.wxRequest,   url: e[0].url,   status: arguments[0].statusCode,   begin: beginTime,   end: endTime,   total: endTime - beginTime   }   smaUtils.logInfo('success performance:', performance)   // 这里做上报的事情   // SMA.performanceReport(performance)   success && success.apply(this, [].slice.call(arguments))  }  // 拦截请求失败方法  e[0].fail = function () {   endTime = smaUtils.getTime()   const performance = {   type: constMap.performance,   event: eventMap.wxRequest,   url: e[0].url,   status: arguments[0].statusCode,   begin: beginTime,   end: endTime,   total: endTime - beginTime   }   smaUtils.logInfo('fail performance:', performance)   // 这里做上报的事情   // SMA.performanceReport(performance)   fail && fail.apply(this, [].slice.call(arguments))  }  }, }   // 替换微信相关属性 let oldWx = wx,  newWx = {} for (var p in wx) {  if (Request[p]) {  let p2 = p.toString()  newWx[p2] = function () {   Request[p2](arguments)   // 调用原来的wx.request 方法   oldWx[p2].apply(oldWx, [].slice.call(arguments))  }  } else {  newWx[p] = oldWx[p]  } } // eslint-disable-next-line wx = newWx

疑惑:为什么要使用替换整个wx对象的方法呢? 不直接用我们的request 方法 替换 wx.request 方法

var oldRequest = wx.requestwx.request = function(e) { // doSomething(); console.log('请求拦截操作...') oldRequest.call(this, e); // 调用老的request方法}// 结果报错了:// TypeError: Cannot set property request of [object Object] which has only a getter

3.错误的监听

3.1 拦截App里注册的 onError事件

var oldAp = AppApp = function(options) { var oldOnError = options.onErrr options['onErrr'] = function(t) { // 做一些我们自己想做的事情 console.log('统计错误....', t) // 调用原来的onLaunch 方法 oldOnError.call(this, t) }  // 调用原来的App 方法 oldApp(options)}

3.2 拦截 conole.error

console.error = function() {  var e = [].slice.call(arguments)  if (!e.length) { return true }  const currRoute = smaUtils.getPagePath()  // 统计错误事件  // SMA.errorReport({event: eventMap.onError, route: currRoute, errrMsg: arguments[0]})  smaUtils.logInfo('捕捉到error 事件,', e)  oldError.apply(console, e) }

至此,我们已经有能力在小程序发起请求时,发生错误时,生命周期或者特殊函数回调时,我们都能在里面做一些我们想要的数据统计功能了。

说了这么多大家估计也看累了。鉴于篇幅,具体的代码就不在这里贴了。

最终实现的数据统计模块大致实现了以下功能:

  • 普通埋点信息上报功能
  • 错误信息上报功能
  • 性能数据上报功能
  • 具体的上报时机支持配置
  • 支持指定网络环境上报
  • 支持统计数据缓存到微信本地功能

整个统计代码的配置文件如下:

const wxaConfig = { project: 'myMiniProgram', // 项目名称 trackUrl: 'https://youhost.com/batch', // 后台数据统计接口 errorUrl: 'https://youhost.com/batch', // 后台错误上报接口 performanceUrl: 'https://youhost.com/batch', // 后台性能上报接口 version: '0.1', prefix: '_wxa_', priority: ['track', 'performance', 'error'], // 发送请求的优先级,发送时,会依次发送 useStorage: true, // 是否开启storage缓存 debug: false, // 是否开启调试(显示log) autoTrack: true, // 自动上报 onShow, onHide, 分享等 内置事件 errorReport: false, // 是否开启错误上报 performanceReport: false, // 接口性能上报 maxReportNum: 20, // 当次上报最大条数 intervalTime: 15, // 定时上报的时间间隔,单位 s, 仅当开启了定时上报有效。 networkList: ['wifi', '4g', '3g'], // 允许上报的网络环境 opportunity: 'pageHide' // pageHide、appHide、realTime(实时上报)、timing(定时上报) 上报的时机,四选一}export default wxaConfig

具体上报时,上报的数据结构大致长这样:

项目已传到GitHub -> GitHub传送门-wxa

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:

  • 微信小程序表单验证form提交错误提示效果
  • 微信小程序表单验证错误提示效果
  • 微信小程序 setData使用方法及常用错误解决办法
  • 微信小程序 出现错误:{"baseresponse":{"errcode":-80002,"errmsg":""}}解决办法
  • 微信小程序 支付功能开发错误总结
  • 微信小程序 加载 app-service.js 错误解决方法
  • 微信小程序错误this.setData报错及解决过程


  • 上一条:
    微信小程序利用Canvas绘制图片和竖排文字详解
    下一条:
    微信小程序入口场景的问题集合与相关解决方法
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 微信模板消息改版后发送规则记录(微信订阅消息参数值内容限制说明)(1个评论)
    • 微信支付v3对接所需工具及命令(0个评论)
    • 2023年9月1日起:微信小程序必须备案才能上线运营(0个评论)
    • 腾讯官方客服回应了:微信好友上限约10000个!(1个评论)
    • 2023年做微信小程序的老铁注意:新增收费项、微信小程序获取手机号也收费了(2个评论)
    • 近期文章
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2017-10
    • 2018-01
    • 2020-03
    • 2021-06
    • 2021-10
    • 2022-03
    • 2023-02
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-10
    • 2023-11
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客