实现思路
我们的目的是在不引入外部SDK,业务代码方完全无感知的情况下实现页面的日志采集功能。由于在Vue中每一次的页面跳转都会进入路由的beforeEach和afterEach钩子函数,因此我们将借助路由实现业务代码无感知的埋点功能。
在此之前,需要保证项目中除了日志服务之外其他的请求都会经过一个入口方法,因为
我们会将日志信息进行聚合,避免发送过多的请求以减轻日志服务器的压力。
客户端交互日志采集
我们将要借助vuex来保存用户的页面交互日志。
export default { state: { templates: "1", // 交互日志 log: { info: "demo", actionData: [] }, }, getters: { templates(state) { return state.templates; }, log(state) { return state.log } }, mutations: { templatesMu(state, val) { if (val) { state.templates = val;// 改变vuex中的templates为设置的皮肤 } }, logMu(state, val) { if(val) { state.log.actionData.push(val); } } }, actions: { } }
其中的log中的actionData用来存储用户的交互日志信息。每一次用户的操作都会调用mutations中的logMu将信息存放进去。
// 数据直接请求 export const apiData = (config)=>{ // 用户操作之后将操作的信息存进actionData store.commit("logMu", {url: config.url, time: new Date().getTime()}) config.url = '/zuul'+ config.url config = checkConfig(config) return axios.request(config) }
客户端浏览日志采集
正常情况下我们会在进入页面时发送日志信息,但是用户在每个页面的停留时间我们将很难统计到。因此考虑在离开页面时发送日志信息,并且在页面跳转时将上一个页面的一些信息也一并加入日志信息中。
客户端日志发送
在Vue中我们将在router.afterEach钩子函数里做这个操作。
// 路由跳转之后 router.afterEach((to, from) => { end = new Date().getTime(); let logData = window.vm.$store.getters.log; logData['from'] = from.name; logData['to'] = to.name; logData['start'] = start; logData['end'] = end; logData['url'] = "url"; logServer(logData); start = new Date().getTime(); window.scrollTo(0, 0); })
其中的start和end为进入页面的开始和结束时间。因为是在页面跳转之后发送请求,所以此时将end置为当前时间。在发送完日志之后进入页面,将start设置为当前时间。
优化
我们是在假设用户每一次的操作都会发送一次请求来实现的,但在实际环境中用户的操作大部分都不会给后台发送请求。此时我们可以考虑在主页面是加点击事件记录下当前页面的信息,鼠标位置等。
<template> <div id="app" @click="clickme"> <router-view/> </div> </template>
如果有更好的方法请留言分享一下,谢谢~