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

前端业务监控系统,异常上报业务,异常队列收集,异常捕获

前端在开发业务监控系统,特别时一些指标类业务系统时,常常需要配合进行异常收集上报工作。
大致工作分为
1. 异常捕获
2. 异常队列收集
3. 异常队列边界
4. 上报时机

一:异常捕获

这里需要关注具体的业务重点,我们不做具体举例,这里只用常见的几种类型收集来做说明
1、 业务系统界面卡顿
前端常常会遇到使用过程中业务系统卡顿情况,这里需要使用PerformanceObserver 进行性能监控

if (typeof window !== 'undefined' && 'PerformanceObserver' in window) {try {const observer = new window.PerformanceObserver((list) => {list.getEntries().forEach(entry => {collectError({type: 'longTask',name: entry.name,startTime: entry.startTime,duration: entry.duration,detail: entry});});});observer.observe({ entryTypes: ['longtask'] });} catch (e) {}
}

2.业务系统界面崩溃

// 2. 页面挂了/业务代码报错(全局异常)
if (typeof window !== 'undefined') {window.addEventListener('error', function (event: any) {collectError({type: 'jsError',msg: event.message,url: event.filename,line: event.lineno,col: event.colno,stack: event.error && event.error.stack});}, true);window.addEventListener('unhandledrejection', function (event: any) {collectError({type: 'promiseError',msg: event.reason ? (event.reason.message || String(event.reason)) : '',stack: event.reason && event.reason.stack});});
}

3.接口请求异常
这里可以是所有接口捕获,也可以指定几个重点监控的接口名称进行追踪

  1. 针对普通fetch
// 3. 接口异常(fetch 拦截)
if (typeof window !== 'undefined' && 'fetch' in window) {const rawFetch = window.fetch;window.fetch = async function (...args) {try {return await rawFetch.apply(this, args);} catch (err:any) {collectError({type: 'apiError',url: args[0],    //请求地址params: args[1], //请求参数msg: err.message,stack: err.stack});throw err;}};
}

2.针对使用了axios或者其他工具并且定义了拦截器

axiosInstance.interceptors.response.use((response: AxiosResponse) => {const { data } = responsereturn data},(error: AxiosError) => {//错误收集,上报使用collectError({type: 'apiError',url: error.config && error.config.url,params: error.config && error.config.data,method: error.config && error.config.method,msg: error.message,stack: error.stack,response: error.response // 可选}))

二: 异常队列收集

我们在收集异常时往往不是收集到了就立刻上报,这样效率和资源都会有损耗,推荐的做法时,建立一个异常队列,用来暂时存储收集到的异常

// 异常队列
const errorQueue: any[] = [];

三:异常队列边界

有了异常队列,我们往往需要人为定义一个边界,当收集到一定数量后就可以进行上报任务

const MAX_QUEUE_LENGTH = 10;   //异常队列长度

四:上报时机

需要明确一点,异常上报不是我们的重点任务,它时服务于业务系统运行的。所以我们要有主次感,只有在队列任务空闲时才会上报,不分主次占用资源的进行上报,因为使用上报的话,频率往往会高于正常业务

requestIdleCallback,接受两个参数,一个是需要被执行的函数,一个时配置对象{},含一个空闲时间,一个是否因为超时强制执行

当然,requestIdleCallback并不是唯一的选择,在React中就没有采用这种方式,而是使用scheduler调度器策略,内部降级使用`setTimeout 等其他方式。

由于`requestIdleCallback运行环境的限制:
requestIdleCallback 目前不是所有浏览器都支持(如 Safari 兼容性较差,移动端支持也不完全支持)

// 定时上报,防止遗漏
setInterval(() => {if (typeof window !== 'undefined' && 'requestIdleCallback' in window) {window.requestIdleCallback(reportErrors);} else {setTimeout(reportErrors, 0);}
}, REPORT_INTERVAL);

import { POST } from '@/httpUtils/http';const MAX_QUEUE_LENGTH = 10;   //异常队列长度
const REPORT_INTERVAL = 5000; // 5秒上报间隔// 异常队列
const errorQueue: any[] = [];
//上报地址
const fetchUrl='129.168.0.53/sys/error/queue'//重点监控接口清单
const importantUrl=['/sys/load/file','/sys/load/list','/sys/load/map']// 异常上报接口
const reportApi = async (errors: any[]): Promise<void> => {await POST(fetchUrl, {errors});return undefined;
};//主动上报方法
const reportErrors = async () => {if (errorQueue.length === 0) return;const errorsToSend = errorQueue.splice(0, errorQueue.length);try {await reportApi(errorsToSend);if (typeof window !== 'undefined') {window.alert('异常上报成功!');} else {console.log('异常上报成功!');}} catch (e) {// 失败提示if (typeof window !== 'undefined') {window.alert('异常上报失败:' + (e as Error).message);} else {console.error('异常上报失败:', e);}}
};// 收集异常
export const collectError = (error: any) => {// 判断是否为重点接口if (error.type === 'apiError' && importantUrl.some(u => error.url && error.url.includes(u))) {reportApi([error]);return;}// 其他异常,正常入队列errorQueue.push(error);if (errorQueue.length >= MAX_QUEUE_LENGTH) {reportErrors();}
}// 定时上报,防止遗漏
setInterval(() => {if (typeof window !== 'undefined' && 'requestIdleCallback' in window) {window.requestIdleCallback(reportErrors);} else {setTimeout(reportErrors, 0);}
}, REPORT_INTERVAL);// 自动捕获场景 -- 页面卡顿(长任务)
if (typeof window !== 'undefined' && 'PerformanceObserver' in window) {try {const observer = new window.PerformanceObserver((list) => {list.getEntries().forEach(entry => {collectError({type: 'longTask',name: entry.name,startTime: entry.startTime,duration: entry.duration,detail: entry});});});observer.observe({ entryTypes: ['longtask'] });// eslint-disable-next-line @typescript-eslint/no-unused-vars} catch (e) {// 某些低版本浏览器不支持 longtask}
}// 自动捕获场景  -- 页面挂了/业务代码报错(全局异常)
if (typeof window !== 'undefined') {window.addEventListener('error', function (event: any) {collectError({type: 'jsError',msg: event.message,url: event.filename,line: event.lineno,  //代码行号col: event.colno,   stack: event.error && event.error.stack});}, true);window.addEventListener('unhandledrejection', function (event: any) {collectError({type: 'promiseError',msg: event.reason ? (event.reason.message || String(event.reason)) : '',stack: event.reason && event.reason.stack});});
}// 自动捕获场景 -- 接口异常(原生fetch 拦截)
if (typeof window !== 'undefined' && 'fetch' in window) {const rawFetch = window.fetch;window.fetch = async function (...args) {try {return await rawFetch.apply(this, args);} catch (err:any) {collectError({type: 'apiError',url: args[0],    //请求地址params: args[1], //请求参数msg: err.message,stack: err.stack});throw err;}};
}// 导出队列和上报函数(如需手动调用)
export { errorQueue, reportErrors };
http://www.xdnf.cn/news/15081.html

相关文章:

  • 【Unity】MiniGame编辑器小游戏(十)连连看【Link】
  • C#基础篇(11)泛型类与泛型方法详解
  • UI前端与数字孪生结合实践探索:智慧物流的仓储优化与管理系统
  • 大数据在UI前端的应用深化:用户行为模式的挖掘与预测性分析
  • 原型与原型链到底是什么?
  • Linux驱动学习day20(pinctrl子系统驱动大全)
  • 自动驾驶决策与规划
  • 【Kafka】登录日志处理的三次阶梯式优化实践:从同步写入到Kafka多分区批处理
  • 【PDF提取内容改名】批量提取pdf多个指定区域内容到excel表格的操作步骤和方法
  • 制作MikTex本地包可用于离线安装包
  • doris2.1.8连接报错ERROR 1203 (42000): Reach limit of connections解决办法
  • 冷冻电镜重构的GPU加速破局:从Relion到CryoSPARC的并行重构算法
  • 前端UI逻辑复杂可以用什么设计模式
  • 由 DB_FILES 参数导致的 dg 服务器无法同步问题
  • CVE-2025-32463复现
  • 在overleaf中使用bibtex格式引用文献
  • 自动化测试报告优化:jenkins+jmeter定制化HTML报告生成
  • QT 第八讲 --- 控件篇 Widget(三)界面系列
  • 米思齐2.0 3.0 mixly arduino 编程软件下载安装及详情使用指南 导入库文件方法 支持8266 esp32
  • 宇树 G1 部署(一)——综述
  • 如何将华为手机中的照片传输到电脑
  • Unreal引擎——动画系统详解-其二
  • 2025年INS SCI2区,灵活交叉变异灰狼算法GWO_C/M+集群任务调度,深度解析+性能实测
  • ${project.basedir}延申出来的Maven内置的一些常用属性
  • 编码器(Encoder)和解码器(Decoder)
  • 暑假复习篇之图像识别①
  • 社区云管家 - 智慧生活新方式 ——仙盟创梦IDE
  • 常见前端开发问题的解决办法
  • 用 Spring Boot + Redis 实现哔哩哔哩弹幕系统(上篇博客改进版)
  • 蓝桥杯 第十六届(2025)真题思路复盘解析