I. Introduction
In front-end projects, various errors are often encountered. When the error recurs, it is often necessary to repeatedly console.log to find the cause of the problem. Then, we can encapsulate a log to record various user behaviors and various interface requests to find the error.
Identify monitoring needs:
- Which page the user is browsing in the system
- Where the user clicked on the page
- Which interfaces are requested and what is the return value
- error message
How to store and when to upload:
- In the Vue3 project, with pinia, it is recorded in the form of an array. Every time a piece of data is generated, it can be pushed into the array.
- Upload to the server when the page is refreshed or closed
2. In the Vue3+TypeScript project, encapsulate the log
Regarding project construction, if you are not familiar with it, you can refer to Vue3+TypeScript+Vite+Pinia
In the src/store directory, create a new logger.ts file
moment is the moment.js tool installed in the project
import { defineStore } from "pinia";
import moment from "moment";
export const useLoggerStore = defineStore('logger', {
state: () => {
return {
loggerArray: [] as any[]
}
},
getters: {},
actions: {
setLoggerArray (data: any) {
this.loggerArray.push({
...data,
nowPage: window.location.href,
steps: this.loggerArray.length + 1,
time: moment().format('YYYY-MM-DD kk:mm:ss a')
}
)
}
}
})
Edit code in App.vue
<template>
<router-view></router-view>
</template>
<script lang="ts" setup>
import { useLoggerStore } from './store/logger';
const loggerStore = useLoggerStore()
// 监听页面隐藏/打开
window.addEventListener('visibilitychange', () => {
if (document.hidden) {
loggerStore.setLoggerArray({
title: '离开/隐藏页面'
})
} else {
loggerStore.setLoggerArray({
title: '进入页面'
})
}
})
// 监听用户鼠标点击行为
window.addEventListener('mouseup', (event: any) => {
loggerStore.setLoggerArray({
title: '用户点击',
Element: event.srcElement.outerHTML
})
})
// 监听报错信息
window.addEventListener('error', (err: any) => {
loggerStore.setLoggerArray({
title: '报错',
errorMsg: err.message
})
})
// 在页面刷新、关闭前发送记录的数据,fetch能保证浏览器结束进程前发送请求
window.addEventListener('beforeunload', () => {
const arr = JSON.stringify(loggerStore.loggerArray)
console.log(arr)
})
</script>
<style scoped lang='less'></style>
Edit the code in src/router/index.ts, only write the code about the log here
import { useLoggerStore } from '@/store/logger';
// 路由跳转前的监听操作
router.beforeEach((to, from, next) => {
const loggerStore = useLoggerStore()
loggerStore.setLoggerArray({
title: '切换页面',
fromPage: from.path,
toPage: to.path
})
const userStore = useUserStore()
Nprogress.start()
if (userStore.token) {
if (to.path === '/login') {
next('/')
return
}
next()
} else if (whiteList.includes(to.path)) {
next()
} else {
next('/login')
}
})
Finally, edit the code in src/http/request.ts, which is the request request encapsulated by yourself
import axios from 'axios'
import Nprogress from 'nprogress'
import 'nprogress/nprogress.css'
import { ElMessage } from 'element-plus'
import { useLoggerStore } from '@/store/logger'
const request = axios.create({
baseURL: import.meta.env.VITE_BASE_URL,
timeout: 5000
})
const NERWORK_ERROR = '服务器错误,请稍后重试!'
request.interceptors.request.use(config => {
Nprogress.start()
const token = sessionStorage.getItem("token")
config.headers.token = token
const loggerStore = useLoggerStore()
loggerStore.setLoggerArray({
title: '请求接口',
data: JSON.stringify(config)
})
return config
}, error => {
Nprogress.done()
return Promise.reject(error)
})
request.interceptors.response.use(res => {
const loggerStore = useLoggerStore()
const url = res.request.custom.options.url
const index = import.meta.env.VITE_BASE_URL.length
const newUrl = url.substring(index, url.length)
loggerStore.setLoggerArray({
title: `'接口响应'-${newUrl}`,
data: JSON.stringify(res)
})
Nprogress.done()
if (res.status === 200) {
return res.data
} else {
ElMessage.error(NERWORK_ERROR)
return Promise.reject(NERWORK_ERROR)
}
})
class Http {
get = function (url: string, params: any) {
return request({
url: url,
method: 'get',
headers: { 'Content-Type': 'multipart/form-data' },
params
})
}
post = function (url: string, data: any) {
return request({
url: url,
method: 'post',
data
})
}
}
const http = new Http()
export { http }
At this time, the front-end monitoring log is OK, and the log interface is agreed with the back-end, and the front-end log can be uploaded under certain conditions.