当前位置: 首页 > news >正文

分享前端如何监控线上的BUG

这篇文章的内容主要是在实际前端项目中要如何监控生产环境中前端的BUG。
文章主要从以下几个方面:为什么需要监控、监控的是哪些方面,简易版日志上报系统设计

为什么需要监控线上bug

当用户在使用过程中,上报投诉时BUG时,我们无法得知用户是如何操作的,自己又无法复现。这种情况下,我们需要设计一套监控的方法放在项目中,以便更好的监控整个项目。

设计思路

我们设计监控项目的目的就是想要回放用户当时的操作轨迹。
下图中就是我们设计整个前端回放项目的整个流程。
截屏2026-02-02 23.09.56

这里需要了解一个第三方库rrweb.js。大家也可以去官网看具体的使用方法。

这里简单说一下rrweb.js的使用方法。
在客户端记录用户操作日志时,一般不希望过多和我们的业务进行耦合,所以,我们可以单独封装到js/ts中,在根节点进行监听就可。

客户端代码实现

这里我先写一下代码

//封装的axios
import server from "./server"
//用来存储错误信息的数组
let events:Array<any> = [];
//上报信息的接口
export const reportBug = async (error:any) => {try {server.post('/user/reportBug', {events: events,errorMes: error}).then(response => {console.log('上报bug成功:', response.data);events = []; // 清空已上报的事件}).catch(err => {console.log('上报bug失败:', err);});} catch (error) {console.error('上报bug失败:', error);throw error;}
}
// 存储事件,数组超出500条后删除一半
export const recordEvents = (log:any) => {if (events?.length > 500) {events = events.slice(-250); // 超过500条,删除最早的一半}events.push(log)
}

那我们封装完之后的方法在哪里调用呢?
在vue项目中,我们可以在dom渲染结束后调用监听上报的方法,示例代码如下:

onMounted(() => {record({emit(event) {recordEvents(event);},});
});
// 当项目中出现js报错时,进行捕获并上报
window.addEventListener('error', (event) => {reportBug(event.message);
});
server.get('/user/get').then((res:any) => {console.log('app.vue test res:', res);if (res?.code === 200) {router.push('/home');} else {//出现错误时调用上报的方法reportBug(res?.message);router.push('/login');}
}).catch(err => {
//出现错误时调用上报的方法router.push('/login');
});

另外在已封装的server请求中,也要调用reportBug方法,这里就不展示了。
以上便是我们需要在客户端写的示例代码,在实际项目中还要根据我们具体的需求再做相应的修改

服务端部分

服务端部分是用node写的接口。在服务端,将用户反馈回来的数据写成log文件,存储在log文件夹下。

// 这里项目中要有一个logs的文件夹,否则会报错
const writeLog = (message) => {fs.writeFileSync('./logs/' + getFileName(), message, 'utf8');
}// 上报用户操作bug接口
router.post('/user/reportBug', async (ctx) => {const bodyData = ctx.request.body;writeLog(JSON.stringify(bodyData));// 这里可以将bug报告存储到数据库或发送到管理员邮箱ctx.body = {code: 200,message: 'Bug报告已收到,感谢您的反馈!',data: null};
}); 

这里需要注意的一点就是,因为上报的请求体会较大,所以需要在接口请求体设置中配置一下请求体的最大限度。这里设置的都是简单的

const koaBody = require('koa-bodyparser');
app.use(koaBody({enableTypes: ['json', 'form', 'text'],formLimit: '10mb',jsonLimit: '10mb',textLimit: '10mb'
}));

接下来要开始日志回放系统如何读取并回放出来用户的操作轨迹了

首先这里还是需要用到rrweb第三方插件中的Replayer回放部分
这里先说一下后端的处理逻辑

后端从日志文件夹中获取到日志列表,然后将它们返回到前端页面,这样从前端页面中就可以看到日志文件信息,当用户想查看时,就会点进去

这里就会涉及到接口拿到前端返回的数据信息和事件列表,然后相当于将当时的页面留了快照,并写成文件。在前端页面需要展示日志列表时,展示出来,并在读取详情时返回给前端页面

//设置文件名称,增加其时间戳
const getFileName = () => {const date = new Date().getTime();return `bugReport_${date}.json`;
}
// 将文件存储到logs文件夹下
const writeLog = (message) => {fs.writeFileSync('./logs/' + getFileName(), message, 'utf8');
}
// 上报用户操作bug接口
router.post('/user/reportBug', async (ctx) => {const bodyData = ctx.request.body;writeLog(JSON.stringify(bodyData));// 这里可以将bug报告存储到数据库或发送到管理员邮箱ctx.body = {code: 200,message: 'Bug报告已收到,感谢您的反馈!',data: null};
});
/ 获取日志文件列表接口
router.get('/user/logs/list', async (ctx) => {const files = fs.readdirSync('./logs').filter(file => file.endsWith('.json')).map(file => ({name: file,id: file.split('_')[1].split('.')[0]}));log('日志文件列表:', files);ctx.body = {code: 200,message: '日志文件列表获取成功',data: files};
});
router.get('/user/logs/:filename', async (ctx) => {const { filename } = ctx.params;const filePath = `./logs/${filename}`;   const fileContent = fs.readFileSync(filePath, 'utf8');ctx.body = {code: 200,data: JSON.parse(fileContent),message: '文件读取成功'}; 
});

日志回放中,前端是如何配置的

前端从接口中获取到数据后,就可以调用方法,在页面中显示了

const initReplayer = (events:any) => {const rplayerElement = document.getElementById('rplayer');//dom节点if (rplayerElement) {rplayerElement.innerHTML = '';}const replayer = new Replayer(events,{root: rplayerElement!,mouseTail: true,});replayer.play();};

以上是关于前端监控线上系统的整个简易操作流程,在实际项目中,还需要考虑到实际业务需求,做相应的修改。

http://www.jsqmd.com/news/335687/

相关文章:

  • AI业务架构师完全手册:让Token变利润的核心技能与避坑指南
  • PLSQL Developer 12.0.7 64位安装教程
  • 探索大数据领域ClickHouse的文本数据处理
  • 2026年医院展馆导览机器人技术深度解析与主流产品应用指南 - 智造出海
  • **AI漫剧爆款生成器2025推荐,解锁高互动率与平台适配的
  • 2026-02-03 全国各地响应最快的 BT Tracker 服务器(电信版)
  • SpringBoot+Vue 人事管理系统管理平台源码【适合毕设/课设/学习】Java+MySQL
  • 池州标志设计服务商选择指南与深度评测 - 2026年企业推荐榜
  • 前后端分离校园资产管理系统|SpringBoot+Vue+MyBatis+MySQL完整源码+部署教程
  • 2026年商场前台迎宾机器人选购指南:旗舰机型推荐 - 智造出海
  • 英伟达 数字孪生 AODT 下载
  • Dart 核心语法精讲:从空安全到流程控制(3)
  • Dart 函数深度解析:从基础语法到工程实践(4)
  • <span class=“js_title_inner“>ITIL 4落地实施:为什么90%的企业都在第一步就走错了路?</span>
  • **AI漫剧剧本写作工具2025推荐,三款适配不同创作场景的
  • **AI漫剧制作工具2025推荐,新手也能快速上手的创作利器
  • 2026年非人形机器人核心品类解析与代表性产品技术分析 - 智造出海
  • 自主可控的AI医疗方案:高精度人体图智能导诊系统源码,支持私有化部署
  • 2026年主流机器人产品与应用场景深度解析 - 智造出海
  • c语言高级议题
  • 认知突围:练就看透本质的能力
  • Qt视频监控系统开发实战:从视频捕获到照片管理
  • 财富分配不均:产能过剩的真相
  • 5句毒鸡汤,别再被PUA了!正义也许会迟到,但永远不会缺席
  • 别再用“多想想自己有的”骗自己了!拆解“人人有烦恼”的底层逻辑,以及真正获得满足感的方式
  • 30岁灵魂40岁重量:如何突破认知局限,跳出舒适圈,挑战不可能
  • 深耕与跳出:双轮驱动的成长密码
  • <span class=“js_title_inner“>RT-Thread首款低功耗AI产品预售: Edgi Talk</span>
  • <span class=“js_title_inner“>美国 TikTok 崩了!</span>
  • <span class=“js_title_inner“>双点双向重分布导致路由环路,你要怎么解?</span>