埋点数据采集方案
为什么要设计这个程序?
埋点上报所需的数据可能来自四面八方,为了不影响业务,我们采用采集数据的形式单独维护埋点所需的数据,而非从不同地方传进来。
初步想法
封装一个类,主要有采集和上报两个方法,通过事件名为key来对应收集的数据。
class Track {
constructor() {
this.eventDataMap = new Map();
}
collect(eventName, eventData) {
this.eventDataMap.set(eventName, eventData);
}
report(eventName) {
const eventData = this.eventDataMap.get(eventName);
fetch('xxx', {
event_name: eventName,
event_data: eventData,
}).then(() => {
this.eventDataMap.delete(eventName);
});
}
}
export default new Track();
问题
以上程序只适合一对一场景,也就是一个eventName对应一次上报。
track.collect('EVENT_A', {tab: 'A'});
track.report('EVENT_A');
track.report('EVENT_A');
第二次上报的时候数据就没了
问题的本质
想要的是一对一,实际是一对多。
思考
-
如果是一个事件名对应一处上报,那就简单了,它的生命周期就是收集数据、上报、回收数据。
-
但如果一个事件名对应多处上报,那就不知道何时回收数据了。
例如:
eventName: ‘login_click’
eventData: {btn_name:‘我的、注册、发送验证码…’, page_source:‘xxx’}
一个事件会对应不同的传参
收集数据的目的?
达到埋点数据和业务数据之间的解耦,到实际上报处读取数据进行上报。
解决
因为收集的可能是公共数据,不知道何时回收该公共数据,那他就不应该被回收。
额外
如何收集一个页面来源参数“page_source”
比如点击一个按钮,跳转到另一个页面,需要记录这个按钮的名称。
如果你的页面层级只有两级,那么只需要全局维护一个“page_source”变量即可。
如果有更深的层级则不行,此时的“page_source”就是一对一的关系了,所以可以维护一个map,使页面与page_source一一对应。
一点伪代码
<Button
name={'按钮名称'}
...
/>
const Button=({name})=>{
return <button
onClick={()=>{
track.tempPageSource=name
}}
/>
}
routeChange={()=>{
const currentName=getCurrentRoute().name
track.pageSourceMap.set(currentName,track.pageSource)