• 基于matomo实现业务数据埋点采集上报


    matomo是一款Google-analytics数据埋点采集上报的平替方案,可保护您的数据和客户的隐私;正如它官网的slogan: Google Analytics alternative that protects your data and your customers' privacy; 该项目源码开源免费,支持私有化部署,保证数据安全、可靠;支持多种方式集成,不管你的应用是传统的html多页面应用还是现代的SPA单页面应用,不管你的应用是CSR渲染还是SSR渲染,均可支持;

    • SDK统计代码 

    1. <script>
    2. var _paq = window._paq = window._paq || [];
    3. /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
    4. _paq.push(['trackPageView']); // 记录页面视图
    5. _paq.push(['enableLinkTracking']); // 在所有适用的链接元素上安装链接跟踪
    6. (function () {
    7. var u = "https://test-matobo.jnt-express.com.cn/"; // matomo私有服务器地址
    8. _paq.push(['setTrackerUrl', u + 'matomo.php']); // 指定 Matomo 服务器 URL
    9. _paq.push(['setSiteId', '9']); // 设置追踪的站点唯一编码(指定网站 ID) 该id将作为唯一标识来区分matomo正在采集数据的应用
    10. var d = document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
    11. g.async=true; g.src = u + 'matomo.js'; s.parentNode.insertBefore(g, s); // async 属性指定该脚本SDK将会在加载完毕后执行
    12. })();
    13. script>
    • 常用Api:

    • setCustomUrl(string):

      Override the page's reported URL,覆盖页面报告的 URL;给matomo上报业务系统的地址路径、路由信息等

    • trackPageView([customTitle]):

      Log a page view. 记录页面视图信息并上报页面标题

    • setUserId(userId):

      Sets a User ID to this user (such as an email address or a username). 设置该用户的用户 ID(例如电子邮件地址或用户名)

    • resetUserId:

      Clears (un-set) the User ID. 清除(取消设置)用户 ID

    • trackEvent(category,action,[name],[value]):

      Log an event with an event category (Videos, Music, Games...), an event action (Play, Pause, Duration, Add Playlist, Downloaded, Clicked...), and an optional event name and optional numeric value  记录事件,其中包含事件类别(视频、音乐、游戏...)、事件操作(播放、暂停、持续时间、添加播放列表、下载、单击...)以及可选事件名称和可选数值;此api将作为行为埋点,例记录按钮点击次数上报等场景使用

    • 接入方式

    matomo支持多种方式接入,不管你的应用是传统的html多页面应用,还是现代的vue、react等单页面应用 

    传统的html多页面应用接入:

    • 使用

    • 引入SDK

    1. <script>
    2. var _paq = window._paq = window._paq || [];
    3. /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
    4. _paq.push(['trackPageView']);
    5. _paq.push(['enableLinkTracking']);
    6. (function() {
    7. var u="https://test-matobo.jnt-express.com.cn/";
    8. _paq.push(['setTrackerUrl', u+'matomo.php']);
    9. _paq.push(['setSiteId', '10']);
    10. var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
    11. g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
    12. })();
    13. script>

    引入SDK即可自动采集部分数据,如有特殊需求需要记录页面信息及标题,在对应的地方调用window._paq.push方法去传递参数即可;api跟其他方式保持一致;

    • 现代的单页面应用接入:

    • Hooks 封装

    1. /** src/plugins/matomo.ts */
    2. export default function useMatomo() {
    3. /** 页面地址信息上报 */
    4. const setCustomUrl = (url: string) => {
    5. ;(window as any)._paq.push(['setCustomUrl', `${url}`])
    6. }
    7. /** 页面标题信息上报 */
    8. const trackPageView = (title: string | any) => {
    9. ;(window as any)._paq.push(['trackPageView', `${title}`])
    10. }
    11. /** 用户信息userId上报 */
    12. const setUserId = (userId: string | number | boolean) => {
    13. ;(window as any)._paq.push(['setUserId', `${userId}`])
    14. ;(window as any)._paq.push(['trackPageView'])
    15. }
    16. /** 重置userId,这里多次调用trackAllContentImpressions是为了在退出登录的时候重置调userId,并在下一次登录时重新生成一条最新的记录 */
    17. const resetUserId = () => {
    18. // UserID passed to Matomo (see https://developer.matomo.org/guides/tracking-javascript-guide#user-id)
    19. ;(window as any)._paq.push(['resetUserId'])
    20. ;(window as any)._paq.push(['trackAllContentImpressions', 'new_visit=1'])
    21. ;(window as any)._paq.push(['trackPageView'])
    22. ;(window as any)._paq.push(['trackAllContentImpressions'])
    23. }
    24. /**
    25. * 行为埋点
    26. * $matomo.trackEvent('行为类别', '事件', 'name', 'value')
    27. * behaviorCategory 行为类别
    28. * event 事件
    29. * name 事件名称
    30. * value 事件值
    31. */
    32. const trackEvent = (behaviorCategory: string, event: string, name: string, value?: string | number) => {
    33. ;(window as any)._paq.push(['trackEvent', `${behaviorCategory}`, `${event}`, `${name}`])
    34. }
    35. return {
    36. setCustomUrl,
    37. trackPageView,
    38. setUserId,
    39. resetUserId,
    40. trackEvent
    41. }
    42. }
    1. <template>
    2. <ConfigProvider :locale="zhCN">
    3. <router-view />
    4. ConfigProvider>
    5. template>
    6. <script lang="ts" setup>
    7. import { onMounted, watch } from 'vue'
    8. import { ConfigProvider } from 'ant-design-vue'
    9. import { useRouter } from 'vue-router'
    10. import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
    11. import useMatomo from '@/plugins/matomo'
    12. import { useAuthStore } from '@/store/auth'
    13. const router = useRouter()
    14. const authStore = useAuthStore()
    15. const matomo = useMatomo()
    16. /**
    17. 在App.vue中记录每个路由切换的路径及页面标题信息;
    18. sertUserId一般在登录完成之后调用,这里在App.vue中调用是为了解决token存在,spa应用直接进目标页面而跳过登录页无法触发setUserId上报的问题
    19. */
    20. watch(
    21. () => router.currentRoute.value,
    22. (newValue: any) => {
    23. // 这里延迟是因为matomo sdk加载是异步非阻塞加载,所以为了能正确的获取到window上matomo的实例,我们这里会有略微延迟
    24. setTimeout(() => {
    25. /**
    26. * 记录跳转页面及页面标题 userCode及nickName均为业务系统数据,此处做拼接传入
    27. **/
    28. const name =
    29. authStore.userInfo?.userCode !== undefined
    30. ? `${authStore.userInfo?.userCode} | ${authStore.userInfo?.nickName}`
    31. : ''
    32. matomo.setUserId(name)
    33. matomo.setCustomUrl(window.location.href)
    34. matomo.trackPageView(router.currentRoute.value.meta.title)
    35. }, 500)
    36. }
    37. )
    1. <script lang="ts" setup>
    2. import { reactive, ref, onMounted } from 'vue'
    3. import useMatomo from '@/plugins/matomo'
    4. const matomo = useMatomo()
    5. const jumpPage = (data: any) => {
    6. /** 登录成功后在跳转之前将业务数据userCode和nickName上报 */
    7. const { userCode, nickName, menuTree } = data
    8. const name = `${userCode} | ${nickName}` || ''
    9. matomo.setUserId(name)
    10. }
    11. script>
    1. <script lang="ts" setup>
    2. import { reactive, ref, onMounted } from 'vue'
    3. import useMatomo from '@/plugins/matomo'
    4. const matomo = useMatomo()
    5. const exportBtn = () => {
    6. /** 例如需要记录导出按钮的点击次数,在导出按钮中trackEvent即可 */
    7. matomo.trackEvent('品牌监控报表', '导出', 'export')
    8. script>

    vue-matomo npm包方式引入:

    • vue2

    1. /** 官方提供了vue-matomo这个库,仅适用于vue2,vue3方式接入会有问题 */
    2. npm install --save vue-matomo
    1. /** main.js */
    2. import Vue from 'vue'
    3. import VueMatomo from 'vue-matomo'
    4. Vue.use(VueMatomo, {
    5. // 请求对应服务域名,如果是私有化部署,可以填写自己内网的私有域名,如果是公网部署填写https://matomo.example.com即可
    6. host: 'https://matomo.example.com',
    7. /** 新建项目的script文件中会存在siteId这个变量,这个是跟项目绑定的唯一标识,通过该变量索引查找到对应项目 */
    8. siteId: 5,
    9. // 最终的追踪js文件名 默认 'piwik'
    10. trackerFileName: 'matomo',
    11. siteId: 9,
    12. router: router,
    13. // 支持外部链接跟踪
    14. enableLinkTracking: true,
    15. // 是否需要在发送追踪信息之前请求许可 默认false
    16. requireConsent: false,
    17. // 是否追踪初始页面 默认true
    18. trackInitialView: true,
    19. debug: false
    20. });
    21. // 挂载到vue的实例中之后,我们可以使用this.$matomo or window._paq.push or window.Piwik.getTracker 等三种方式来访问均可,此处使用this来访问

    其实就是在业务代码中做侵入式埋点了,在对应的业务逻辑中使用  this.$matomo && this.$matomo.trackPageView() 或 window._paq.push(['trackPageView']) 等api来进行注入埋点采集数据并上报,两者功能效果相同,区别仅仅只是调用方式不同,挂载到实例中直接以funtion函数的方式调用传参,window全局变量调用通过 push方法来调用,push方法接收一个数组,数组第一项为key,后续剩余参数为name;

    • vue3

    vue3由于使用Composition API,且生命周期机制跟vue2不同,同时matomo又是异步加载资源,所以在main.ts文件中即使挂载了对应的实例,通过getCurrentInstance()?.appContext.config.globalProperties.$matomo 来访问matomo对应实例,无法保证能准确的获取,即使你通过nextTick;因为加载matomo资源不是响应式的,若在页面渲染完成时,matomo资源文件未加载完成,此时获取到的matomo实例仍然为undefined;至于matomo的实例只在页面渲染的那一刻就决定你单次加载是否包含matomo实例 

    参考github issues:

    https://github.com/AmazingDreams/vue-matomo/issues/117

     

    解决方案: 

     

    通过window._pag.push 来访问全局变量,因为即使你获取到的this.$matomo实例是undefined,window._paq.push也可以保证它是可用的;

    • react

        社区没有提供react-matomo之类的npm包/工具来给开发者使用,可以参考Hooks方案,将使用到的Api封装成Hooks,通过window._paq.push的方式在需要的地方来调用;

    由于是私有化部署,关于公司logo及业务数据等相关较敏感的数据均已打码,只展示具体收集指标和效果;

    数据采集上报最终效果图:

  • 相关阅读:
    黑魔法-认识 Docker
    okhttp4.11源码分析
    Q3营收同比翻三倍,踩猛“油门”零跑必将领跑?
    “通胀噩梦:恶梦继续还是即将终结?经济前景备受关注!“
    文本摘要实战:基于句子相似度矩阵构建图结构实现文本摘要 代码+数据
    Github
    C. Planar Reflections-CodeCraft-21 and Codeforces Round #711 (Div. 2)
    AT2401C 功率放大器(PA)射频前端集成芯片
    C专家编程 第9章 再论数组 9.1 什么时候数组与指针相同
    家用摄像头怎么选:实用性,功能性以及性价比是关键
  • 原文地址:https://blog.csdn.net/dengyao46395665/article/details/133827201