vue+node 前端埋點(一)

vue+node 前端埋點(一)統計PV、UV

目錄格式

目錄格式

main.js 文件

import track from './tools/track'
// track 執行
track.execute()

client/tool/track.js 文件

package.json 中添加 fingerprintjs2

"fingerprintjs2": "^1.8.6",

track.js

// PV、UV在beforeEach中統計
import Vue from 'vue'
import router from '../router/index.js'
import Fingerprint from 'fingerprintjs2'
import utils from '../store/utils'
// import uuid from 'uuid/v1'

// 判斷是否支持 performance
function getCurrentTime () {
    try {
        return performance.timing.navigationStart + performance.now()
    } catch (e) {
        return Date.now()
    }
}
// 上傳數據格式
const trackInfo = {
    eventId: '',
    type: 'screen',
    time: '',
    properties: {
        // 需要打點的數據
        _appid: 'xxx', // app標識,事先約定               
        _user_agent: '', // 瀏覽器UA                            
        _screen_type: '', // 所屬頁面
        _screen_event: '', // 具體頁面事件類型
        _screen_title: '', // 頁面標題
        _screen_path: '', // 頁面路徑
        _device_id : '' // web中使用瀏覽器指紋
    }
}
// 是否首次進入
let firstEnter = true
const track = {
    execute () {
        router.beforeEach((to, from, next) => {
            trackInfo.properties._screen_type = to.path
            trackInfo.properties._screen_event = 'ScreenAppear'
            trackInfo.properties._screen_title = to.name
            trackInfo.properties._screen_path = from.path
            trackInfo.time = getCurrentTime()
            trackInfo.type = 'screen'
            trackInfo.eventId = `template_${to.name}`
            if (firstEnter) {
                // 針對純web端項目,設備id取瀏覽器指紋
                trackInfo.properties._user_agent = window.navigator.userAgent
                // 判斷瀏覽器是否支持 requestIdleCallback
                if (window.requestIdleCallback) {
                    requestIdleCallback(function () {
                        Fingerprint().get(function (result) {
                            trackInfo.properties._device_id = result
                            utils.callTrackServer(trackInfo)
                        })
                    })
                } else {
                    setTimeout(function () {
                        Fingerprint().get(function (result) {
                            trackInfo.properties._device_id = result
                            utils.callTrackServer(trackInfo)
                        })
                    }, 500)
                }
                firstEnter = false
            } else {
                utils.callTrackServer(trackInfo)
            }
            next()
        })
    }
}
module.exports = track

client/store/utils.js

package.json 中添加 fingerprintjs2

"axios": "^0.17.1",
"uuid": "^3.3.2",

utils.js

import axios from 'axios'
import uuid from 'uuid/v1'
const utils = {
    // 向node端發送埋點數據
    callTrackServer (info) {
        axios({
            url: '/xxx/getTrackInfo',
            method: 'post',
            data: info
        }).then(res => {
            console.log('success')
        }).catch(err => {
            console.log(err)
        })
    }
}
module.exports = utils

server/routes/index.js

import Router from 'koa-router'
import Tools from '../tools'

var app = new Router()
// PV、UV
app.post('/payday/getTrackInfo', async (ctx, next) => {
    await Tools.trackInfoServer(ctx, next)
})
module.exports = app

server/tools/index.js

import Axios from 'axios'
import {
    loggerTrack
} from '../log'
import uuid from 'uuid'
const Tools = {
	// PV、UV
    trackInfoServer: function (ctx, next) {
        console.log(ctx.request.body)
        loggerTrack.info(`track:`, ctx.request.body)
        ctx.body = {res: 'success'}
        next()
    },
}
module.exports = Tools

server/logs/index.js 日誌寫入

import { createLogger, format, transports } from 'winston'
import 'winston-daily-rotate-file'
import safeStringify from 'fast-safe-stringify'
// import the built-in formatting methods
const { combine, metadata, timestamp, printf, colorize, padLevels } = format
const loggerTrack = createLogger({
    level: 'info',
    format: combine(
        timestamp({format: 'YYYY-MM-DD HH:mm:ss'}),
        metadata({key: 'content', fillExcept: ['timestamp', 'level', 'message']}),
        // printf(info => `${info.content.time}  ${info.content}`)
        printf(info => `${info.content.time}: ${safeStringify(info.content)}\n`)
    ),
    transports: [
        new transports.DailyRotateFile({
            level: 'info',
            filename: 'logs/track/track-%DATE%.log',
            datePattern: 'YYYY-MM-DD',
            // zippedArchive: true,
            maxSize: '20m',
            maxFiles: '30d'
        })
    ]
})
module.exports =
    {
        loggerTrack
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章