前言
相信大部分做浙政钉应用的朋友都必然要经历一次“埋点部分成功”的坑,怎么排查?对于老司机可能没有难度,但是对于第一次做浙政钉应用的新手司机来说,就会有一种无从下手的感觉。因为你感觉一切都是按照文档上来的啊,偷偷告诉我你是不是有这种感觉?哈哈哈...
不论大家的埋点都是怎么操作的,这里我也介绍一下我这边的埋点,希望对那些埋点还没有成功还在苦恼的朋友来说,可以提供一些帮助,早日脱离埋点的坑。
提示:我这边采用的是vue的单页面的开发方式,对于其它开发方式仅供参考。
埋点分类
浙政钉埋点代码分为:
- 稳定性监控代码(Emas):稳定性监控代码(Emas)只需要在首页加入
- 流量分析代码(A+):流量分析代码(A+)每个页面都需要加入。
- 通用采集SDK
- 基础埋点
- 用户信息埋点
稳定性监控代码(Emas)相信基本上都没有什么难度,贴在首页即可。流量分析代码就需要将它封装到一个js中,然后每个页面调用一下即可。
稳定性监控代码(Emas)
这个埋点几乎没有难度,一般应用在审批上架后,浙政钉应用技术人员会给提交审批单的人(一般是业主单位)发送一个文件,文件中包含了:
- 应用名称
- 应用标识
- 正式的App Key
- 正式的 App Secret
- 业主单位的浙政钉租户Id
- 正式环境的浙政钉域名
- 以及埋点的代码
- 稳定性监控
- 通用采集SDK
- 基础埋点
- 用户信息埋点
我们只用把其中稳定性监控代码贴到首页(index.html)head内即可,因为该稳定性代码中,已经包含了正式的 bid
和 signkey
。比如:
<script src='https://wpk-gate.zjzwfw.gov.cn/static/wpk-jssdk.1.0.2/wpkReporter.js' crossorigin='true'></script>
<script>
try {
const config = {
bid: 'xxxxxxxxxx',
signkey: 'xxxxxxxxxxx',
gateway: 'https://wpk-gate.zjzwfw.gov.cn'
};
const wpk = new wpkReporter(config);
wpk.installAll();
window._wpk = wpk;
} catch (err) {
console.error('WpkReporter init fail', err);
}
</script>
流量分析代码(A+)
流量分析代码每个页面都要加,但是“通用采集SDK”这块由于是固定值,所以放在首页即可。
通用采集SDK
接下来是通用采集SDK的埋点,这一步几乎也是没有难点。都是一些固定代码,我们只用跟着贴在稳定性监控代码的后边即可。比如:
(function(w, d, s, q, i) {
w[q] = w[q] || [];
var f = d.getElementsByTagName(s)[0],j = d.createElement(s);
j.async = true;
j.id = 'beacon-aplus';
j.src = 'https://alidt.alicdn.com/alilog/mlog/aplus_cloud.js';
f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'aplus_queue');
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['aplus-rhost-v', 'alog.zjzwfw.gov.cn']
});
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['aplus-rhost-g', 'alog.zjzwfw.gov.cn']
});
var u = navigator.userAgent
var isAndroid = u.indexOf('Android') > -1
var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/)
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['appId', isAndroid ? '28302650' : isIOS ? '28328447' : '47130293']
});
大概就是酱紫了
基础埋点和用户信息埋点
相信只要是埋点出问题的同学基本上都是这里的问题,由于这两块埋点代码每个页面都需要,所以我们将这两块代码封装到一个js文件中,每次路由切换的时候就调用一下即可。
基础埋点
// 单页应用 或 “单个页面”需异步补充PV日志参数还需进行如下埋点:
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['aplus-waiting', 'MAN']
});//
// 单页应用路由切换后 或 在异步获取到pv日志所需的参数后再执行sendPV:
aplus_queue.push({
'action':'aplus.sendPV',
'arguments':[{
is_auto: false
}, {
// 当前你的应用信息,此两行请勿修改
sapp_id: 'xxxx',
sapp_name: 'xxxxxx',
//自定义PV参数key-value键值对(只能是这种平铺的json,不能做多层嵌套),
page_id: '页面ID,与page 参数配合使用,保证唯一性',
page_name: '页面中文名称',
page_url: '页面URL'
}]
})
分析:
- sapp_id:该值在浙政钉给的正式配置文件中可以找到
- sapp_name:同上
- page_id:每个页面的唯一ID,可以使用页面组件名称,因为它也项目中也是唯一的
- page_name:每个页面的中文名称,vue中页面的中文名即可
- page_url:页面Url,vue中传该页面的路由即可
我这边的处理方式是,先在路由那边每个页面路由添加一个meta,包含了id和title两个属性,这样每个页面调用封装方法的时候只用把路由传过去就可以取到 page_id、page_name、page_url。比如:
封装的方法:
我这边创建了一个 baseAplus.js 文件,具体内容如下,有两点需要注意:
- settings 是一个配置文件,我把sapp_id和sapp_name写在了其中
- local-cache 是封装的一个缓存类,首次打开应用的时候将获取到的浙政钉用户信息缓存到localStorage中, getUserInfoCache 就是获取缓存的用户信息。
- 会员昵称和会员ID的埋点中,注意大小写,浙政钉文档上返回的是小驼峰,我这边后端反序列化的成了大驼峰,这里需要注意。具体看你们那边情况。
import GLOBAL from '../settings'
import { getUserInfoCache } from './local-cache'
/**
* 添加基础埋点
* @param {object} route 路由
*/
export function addBaseAplus(route) {
//基础埋点
// 单页应用 或 “单个页面”需异步补充PV日志参数还需进行如下埋点:
aplus_queue.push({
action: "aplus.setMetaInfo",
arguments: ["aplus-waiting", "MAN"],
});
// 单页应用路由切换后 或 在异步获取到pv日志所需的参数后再执行sendPV:
aplus_queue.push({
action: "aplus.sendPV",
arguments: [
{
is_auto: false,
},
{
// 当前你的应用信息,此两行请勿修改
sapp_id: GLOBAL.sapp_id,
sapp_name: GLOBAL.sapp_name,
// 自定义PV参数key-value键值对(只能是这种平铺的json,不能做多层嵌套),如:
page_id: route.meta.id,
page_name: route.meta.title,
page_url: route.path,
},
],
});
//用户信息埋点
// 如采集用户信息是异步行为需要先执行这个BLOCK埋点
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['_hold', 'BLOCK']
});
let userInfo = getUserInfoCache();
// 设置会员昵称
aplus_queue.push({
action: "aplus.setMetaInfo",
arguments: ["_user_nick", userInfo.NickNameCn]
});
// 设置会员ID
aplus_queue.push({
action: "aplus.setMetaInfo",
arguments: ["_user_id", userInfo.AccountId]
});
// dd.getUUID().then(res => {
// aplus_queue.push({
// action: "aplus.setMetaInfo",
// arguments: ["_dev_id", "设备ID是业务定义的,用于定义唯一的设备标识。这个目前没有要求,可不设置。"]
// });
// })
// 如采集用户信息是异步行为,需要先设置完用户信息后再执行这个START埋点
// 此时被block住的日志会携带上用户信息逐条发出
aplus_queue.push({
action: 'aplus.setMetaInfo',
arguments: ['_hold', 'START']
});
}
页面调用
每个页面都要这样调用!!!
每个页面都要这样调用!!!
每个页面都要这样调用!!!
埋点部分成功
完成埋点后,等待浙政钉埋点数据的更新,群里说通常是下午五六点的样子。然后可以到 宜搭 上查看埋点情况。
稳定性监控基本上都能成功,如果流量分析中引用出现在左边则说明成功,如果出现在右边则说明只有部分成功,就需要排查了。比如:
成功示例:
失败示例:
排查方法
可以参考 https://www.yuque.com/docs/share/a2ca4143-dba7-4b8e-8bf5-f0746a7214c3#ljnli 文档中,上报日志API块文档。
但是对于那些没有排查过的同学来说,按照文档中的方法看到了日志也不知道对不对,就像该文档的评论中说的那样“听君一席话,如听一席话”,写的不是一般的难懂。
其实,新同学只是不知道日志的关注点是什么,搞懂这个就可以了。这个其实在文档中的“埋点注意h事项及FAQ”中已经有提及。
16)
我们可以一个一个排除:
- 确保前边“基础埋点和用户信息埋点”一节中封装的方法在每个页面都有调用。
- page_id、page_name、page_url、用户信息等参数的排查。确保page_id唯一(检查路由配置)、page_url和page_name按照要求填写。
- 确保用户信息有上报,其实大部分可能都是因为 _user_id 为空导致的。
由于本地无法通过 dd.getAuthCode({})
获取免登授权码,该方法只能在浙政钉环境或专有钉钉环境可以调用,所以也就无法在本地获取用户信息。
但是我们可以在后端获取浙政钉用户信息接口处添加一个日志,记录一下传进来的免登授权码,然后把该值写到前端,绕过 dd.getAuthCode({})
方法,直接调用获取用户信息接口,这样本地就可以拿到浙政钉或专有钉钉的用户信息了。然后就可以按照 语雀文档 上说的那样获取到上报日志。查看(page_id、page_name、page_url和用户信息)这几项是否有传即可。
等理解后,是不是发现其实也没那么难。
写在最后
如果你觉的哪里写的不清楚的,可以提出来,我尽量再补充一下,尽量每个人都可以看的懂。
如果这篇文章解决了您的埋点问题,麻烦给个赞。
踩过坑,才会觉得如果有个人能给予指点,那是多么幸福的一件事啊!
最后,看着桌面上掉落的头发,感觉自己又变强许多!!
如果您觉得这篇文章有帮助到你,欢迎推荐,也欢迎关注我的公众号。