项目上线后,遇到问题怎么办?线上问题难以重现怎么办?如何在线上快速定位问题所在,减少错误发生次数?
相信每一位前端开发者都遇到过这种头疼的问题。
现在我就分享一种简单的方法:实现了监控页面错误、接口错误,实时上传日志,并发送消息到钉钉群。
前提条件
需要开通unicloud,创建两个表:my-interface-error、my-page-error、一个云函数dingding_message
前两张表你可以自定义需要收集的字段;发送钉钉消息的代码,请自行实现。
以下程序仅供参考
核心文件
// 线上日志报告
import { getCurrentFullpath } from '@/common/nav.js';
import { pageUrl } from '@/project.config.js'
import store from '@/store/index.js'
const db = uniCloud.database()
const platform = process.env.VUE_APP_PLATFORM
const projectName = process.env.VUE_APP_NAME
const device = uni.getSystemInfoSync().system
/**
* 采集 接口异常
* @param {String} interface_name 接口地址
* @param {String} errorcode 返回状态
* @param {Object} content 数据
*/
export async function collectInterfaceLog(interface_name, errorcode, content) {
const mobile = store.getters['ZG_user/mobile']
const log = {
projectName,
platform,
mobile,
content,
interface_name,
errorcode,
}
// console.warn('report.interface error',log)
if (process.env.NODE_ENV === 'development') return
const res = await db.collection('my-interface-error').add(log)
const logId = res.result?.id || ''
const link = `${pageUrl}alone/#/pages_h5/interface-error?id=${logId}`
const link2 = `dingtalk://dingtalkclient/page/link?url=${encodeURIComponent(link)}&pc_slide=false`
uniCloud.callFunction({
name: 'dingding_message',
data: {
type: 1,
data: {
"msgtype": "actionCard",
"actionCard": {
"title": "接口报错",
"text": `接口名称:${interface_name} \n\n 错误代码:${errorcode} \n\n 用户手机:${mobile} \n\n 访问平台:${platform} \n\n 项目名称:${projectName}`,
"btnOrientation": "0",
"btns": [{
"title": "查看详情",
"actionURL": link
},
{
"title": "在浏览器查看",
"actionURL": link2
}
]
}
}
}
})
}
/**
* 采集 前端错误
* @param {Object} content 错误信息
*/
export async function collectErrorLog(content) {
const route = getCurrentFullpath()
const mobile = store.getters['ZG_user/mobile']
const log = {
projectName,
platform,
mobile,
content,
device,
route,
}
// console.warn('report.page error',log)
if (process.env.NODE_ENV === 'development') return
const res = await db.collection('my-page-error').add(log)
const logId = res.result?.id || ''
const link = `${pageUrl}alone/#/pages_h5/page-error?id=${logId}`
uniCloud.callFunction({
name: 'dingding_message',
data: {
type: 1,
data: {
"msgtype": "actionCard",
"actionCard": {
"title": "页面报错",
"text": `错误消息:${content.message} \n\n 用户手机:${mobile} \n\n 访问平台:${platform} \n\n 项目名称:${projectName}`,
"btnOrientation": "0",
"btns": [{
"title": "查看详情",
"actionURL": link
}]
}
}
}
})
}
接入页面错误报告
App.vue
import { collectErrorLog } from '@/common/report.js'
import { throttle } from '@/common/helper.js'
const uploadVueError = throttle(collectErrorLog,1000,3000)
export default {
onLaunch() {
},
// 此处只能监听到.vue文件的错误
onError(error) {
uploadVueError({
message: error.message,
error_stack: error.stack,
})
},
onPageNotFound() {
uni.reLaunch({
url: '/pages/error'
})
}
}
接入接口错误报告
function errorListen(response, options) {
try {
const requestPath = options.url.replace(baseUrl, '')
const statusCode = `${response.statusCode}`
const content = {
requestPath,
requestParams: options.data,
response,
}
collectInterfaceLog(requestPath, statusCode, content)
} catch (e) {
console.error(e);
}
}