一文摸清前端监控自研实践(三)错误监控
前言
上篇文章我们分享了关于 用户行为监控
的内容,本文我们接着来看 错误异常监控
的方面
系列文章传送门
应用的稳定情况
众所周知,无论进行发布前的单元测试
、集成测试
、人工测试
进行再多轮,都会难免漏掉一些边缘的测试场景,甚至还有一些奇奇怪怪的玄学故障出现
;而出现报错后,轻则某些数据页面无法访问
,重则导致客户数据出错
;
这时,一个完善的错误监控体系就派上很大的用场,它可以帮助我们做以下的事情:
- 应用报错时,及时知晓线上应用出现了错误,及时安排修复止损;
- 应用报错后,根据上报的用户行为追踪记录数据,迅速进行bug复现;
- 应用报错后,通过上报的错误行列以及错误信息,找到报错源码并快速修正;
- 数据采集后,进行分析提供宏观的 错误数、错误率、影响用户数等关键指标;
整体封装
ts
复制代码
// 错误类型
export enum mechanismType {
JS = 'js',
RS = 'resource',
UJ = 'unhandledrejection',
HP = 'http',
CS = 'cors',
VUE = 'vue',
}
// 格式化后的 异常数据结构体
export interface ExceptionMetrics {
mechanism: Object;
value?: string;
type: string;
stackTrace?: Object;
pageInformation?: Object;
breadcrumbs?: Array<behaviorStack>;
errorUid: string;
meta?: any;
}
// 初始化用参
export interface ErrorVitalsInitOptions {
Vue: any;
}
// 判断是 JS异常、静态资源异常、还是跨域异常
export const getErrorKey = (event: ErrorEvent | Event) => {
const isJsError = event instanceof ErrorEvent;
if (!isJsError) return mechanismType.RS;
return event.message === 'Script error.' ? mechanismType.CS : mechanismType.JS;
};
// 初始化的类
export default class ErrorVitals {
private engineInstance: EngineInstance;
// 已上报的错误 uid
private submitErrorUids: Array<string>;
constructor(engineInstance: EngineInstance, options: ErrorVitalsInitOptions) {
const { Vue } = options;
this.engineInstance = engineInstance;
this.submitErrorUids = [];
// 初始化 js错误
this.initJsError();
// 初始化 静态资源加载错误
this.initResourceError();
// 初始化 Promise异常
this.initPromiseError();
// 初始化 HTTP请求异常
this.initHttpError();
// 初始化 跨域异常
this.initCorsError();
// 初始化 Vue异常
this.initVueError(Vue);
}
// 封装错误的上报入口,上报前,判断错误是否已经发生过
errorSendHandler = (data: ExceptionMetrics) => {
// 统一加上 用户行为追踪 和 页面基本信息
const submitParams = {
...data,
breadcrumbs: this.engineInstance.userInstance.breadcrumbs.get(),
pageInformation: this.engineInstance.userInstance.metrics.get('page-information'),
} as ExceptionMetrics;
// 判断同一个错误在本次页面访问中是否已经发生过;
const hasSubmitStatus = this.submitErrorUids.includes(submitParams.errorUid);
// 检查一下错误在本次页面访问中,是否已经产生过
if (hasSubmitStatus) return;
this.submitErrorUids.push(submitParams.errorUid);
// 记录后清除 breadcrumbs
this.engineInstance.userInstance.breadcrumbs.clear();
// 一般来说,有报错就立刻上报;
this.engineInstance.transportInstance.kernelTransportHandler(
this.engineInstance.transportInstance.formatTransportData(transportCategory.ERROR, submitParams),
);
};
// 初始化 JS异常 的数据获取和上报
initJsError = (): void => {
//... 详情代码在下
};
// 初始化 静态资源异常 的数据获取和上报
initResourceError = (): void => {
//... 详情代码在下
};