如何搭建前端异常监控系统 #102

简介: 如何搭建前端异常监控系统 #102

什么是异常


是指用户在使用应用时,无法得到预期的结果。不同的异常带来的后果程度不同,轻则引起用户使用不悦,重则导致产品无法使用,从而使用户丧失对产品的认可。


为什么要处理异常


  • 增强用户体验
  • 远程定位问题
  • 无法复现问题,特别是移动端,各种原因,可能是系统版本,机型等等

前端有哪些异常


异常 频率
JavaScript 异常(语法错误、代码错误) 经常
静态资源加载异常(img、js、css) 偶尔
Ajax 请求异常 偶尔
承诺异常 较少
iframe 异常 较少


如何捕获异常


尝试捕获

try-catch只能捕获同步运行错误,对语法和异步错误却捕获不到。

1、同步运行错误

try {
    kill;
} catch(err) {
    console.error('try: ', err);
}

结果:try: ReferenceError: kill is not defined

2、无法捕获语法错误

try {
    let name = '1;
} catch(err) {
    console.error('try: ', err);
}

结果:Unterminated string constant

编译器能够阻止运行语法错误。

3、无法捕获异步错误

try {
    setTimeout(() => {
        undefined.map(v => v);
    }, 1000);
} catch(err) {
    console.error('try: ', err);
}

结果:Uncaught TypeError: Cannot read property 'map' of undefined


窗口错误

当 运行时错误(包括语法错误)发生时, 会触发一个 接口的 事件,并执行 若该函数返回 ,则阻止执行默认事件处理函数。JavaScriptwindowErrorEventerrorwindow.onerror()true

1、同步运行错误

/**
* @param {String}  message   错误信息
* @param {String}  source    出错文件
* @param {Number}  lineno    行号
* @param {Number}  colno     列号
* @param {Object}  error     error对象
*/
window.onerror = (message, source, lineno, colno, error) => {
    console.error('捕获异常:', message, source, lineno, colno, error);
    return true;
};
kill;

结果:捕获异常: Uncaught ReferenceError: kill is not defined

2、无法捕获语法错误

/**
* @param {String}  message   错误信息
* @param {String}  source    出错文件
* @param {Number}  lineno    行号
* @param {Number}  colno     列号
* @param {Object}  error     error对象
*/
window.onerror = (message, source, lineno, colno, error) => {
    console.error('捕获异常:', message, source, lineno, colno, error);
    return true;
};
let name = '1;

结果:Unterminated string constant

编译器能够阻止运行语法错误。

3、异步错误

/**
* @param {String}  message   错误信息
* @param {String}  source    出错文件
* @param {Number}  lineno    行号
* @param {Number}  colno     列号
* @param {Object}  error     error对象
*/
window.onerror = (message, source, lineno, colno, error) => {
    console.error('捕获异常:', message, source, lineno, colno, error);
    return true;
};
setTimeout(() => {
    undefined.map(v => v);
}, 1000);

结果:捕获异常: Uncaught TypeError: Cannot read property 'map' of undefined`

window.addEventListener('error')

当一项资源(如 或 )加载失败,加载资源的元素会触发一个 接口的 事件,并执行该元素上的 处理函数。这些 事件不会向上冒泡到 ,不过(至少在 Firefox 中)能被单一的 . 捕获。<img><script>Eventerroronerror()errorwindowwindowaddEventListener

<script>
window.addEventListener('error', (err) => {
    console.error('捕获异常:', err);
}, true);
</script>
<img src="./test.jpg" />

结果:捕获异常:Event {isTrusted: true, type: "error", target: img, currentTarget: Window, eventPhase: 1, …}


window.addEventListener('unhandledrejection')


当 被 且没有 处理器的时候,会触发 事件;这可能发生在 下,但也可能发生在 中。 这对于调试回退错误处理非常有用。PromiserejectrejectunhandledrejectionwindowWorker

window.addEventListener("unhandledrejection", (err) => {
    err.preventDefault();
    console.error('捕获异常:', err);
});
Promise.reject('promise');

结果:捕获异常:PromiseRejectionEvent {isTrusted: true, promise: Promise, reason: "promise", type: "unhandledrejection", target: Window, …}


Vue

Vue.config.errorHandler = (err, vm, info) => {
  console.error('捕获异常:', err, vm, info);
}


React

React16,提供了一个内置函数 ,使用它可以非常简单的获取到 下的错误信息。componentDidCatchReact

componentDidCatch(error, info) {
    console.error('捕获异常:', error, info);
}

但是,推荐ErrorBoundary

用户界面中的 错误不应破坏整个应用程序。为了为 用户解决此问题, 引入了“错误边界”的新概念。JavaScriptReactReact16

新建 组件:ErrorBoundary.jsx

import React from 'react';
import { Result, Button } from 'antd';
class ErrorBoundary extends React.Component {
    constructor(props) {
        super(props);
        this.state = { hasError: false, info: '' };
    }
    static getDerivedStateFromError(error) {
        return { hasError: true };
    }
    componentDidCatch(error, info) {
        this.setState({
            info: error + ''
        });
    }
    render() {
        if (this.state.hasError) {
            // 你可以渲染任何自定义的降级 UI
            return (
                <Result
                    status="500"
                    title="500"
                    subTitle={this.state.info}
                    extra={<Button type="primary">Report feedback</Button>}
                />
            );
        }
        return this.props.children;
    }
}
export default ErrorBoundary;

使用:

<ErrorBoundary>
    <App />
</ErrorBoundary>

注意

错误边界不会捕获以下方面的错误:

  • 事件处理程序
  • 异步代码(例如 或 回调)setTimeoutrequestAnimationFrame
  • 服务器端渲染
  • 在错误边界本身(而不是其子级)中引发的错误

iframe

由于浏览器设置的“同源策略”,无法非常优雅的处理 异常,除了基本属性(例如其宽度和高度)之外,无法从 获得很多信息。iframeiframe

<script>
    document.getElementById("myiframe").onload = () => {
        const self = document.getElementById('myiframe');
        try {
            (self.contentWindow || self.contentDocument).location.href;
        } catch(err) {
            console.log('捕获异常:' + err);
        }
    };
</script>
<iframe id="myiframe" src="https://nibuzhidao.com" frameBorder="0" />


哨兵

业界非常优秀的一款监控异常的产品,作者也是用的这款,文档齐全。


需要上报哪些信息


  • 错误 id
  • 用户 ID
  • 用户名
  • 用户 IP
  • 设备
  • 错误信息
  • 游览器
  • 系统版本
  • 应用版本
  • 机型
  • 时间戳
  • 异常级别(错误、警告、信息)

异常上报


1、Ajax 发送数据

2、动态创建 img 标签

如果异常数据量大,导致服务器负载高,调整发送频率(可以考虑把异常信息存储在客户端,设定时间阀值,进行上报)或设置采集率(采集率应该通过实际情况来设定,随机数,或者某些用户特征都是不错的选择)。


流程图



参考资料


目录
相关文章
|
2月前
|
JavaScript 前端开发 开发者
Vue.js 框架大揭秘:响应式系统、组件化与路由管理,震撼你的前端世界!
【8月更文挑战第27天】Vue.js是一款备受欢迎的前端JavaScript框架,以简洁、灵活和高效著称。本文将从三个方面深入探讨Vue.js:响应式系统、组件化及路由管理。响应式系统为Vue.js的核心特性,能自动追踪数据变动并更新视图。例如,通过简单示例代码展示其响应式特性:`{{ message }}`,当`message`值改变,页面随之自动更新。此外,Vue.js支持组件化设计,允许将复杂界面拆分为独立且可复用的组件,提高代码可维护性和扩展性。如创建一个包含标题与内容的简单组件,并在其他页面中重复利用。
58 3
|
2月前
|
机器学习/深度学习 数据采集 数据可视化
基于爬虫和机器学习的招聘数据分析与可视化系统,python django框架,前端bootstrap,机器学习有八种带有可视化大屏和后台
本文介绍了一个基于Python Django框架和Bootstrap前端技术,集成了机器学习算法和数据可视化的招聘数据分析与可视化系统,该系统通过爬虫技术获取职位信息,并使用多种机器学习模型进行薪资预测、职位匹配和趋势分析,提供了一个直观的可视化大屏和后台管理系统,以优化招聘策略并提升决策质量。
107 4
|
3月前
|
前端开发 JavaScript Java
基于Vue+ElementUI框架实现学生管理系统前端页面设计
基于Vue+ElementUI框架实现学生管理系统前端页面设计
|
15天前
|
移动开发 缓存 前端开发
构建高效的前端路由系统:从原理到实践
在现代Web开发中,前端路由系统已成为构建单页面应用(SPA)不可或缺的核心技术之一。不同于传统服务器渲染的多页面应用,SPA通过前端路由技术实现了页面的局部刷新与无缝导航,极大地提升了用户体验。本文将深入剖析前端路由的工作原理,包括Hash模式与History模式的实现差异,并通过实战演示如何在Vue.js框架中构建一个高效、可维护的前端路由系统。我们还将探讨如何优化路由加载性能,确保应用在不同网络环境下的流畅运行。本文不仅适合前端开发者深入了解前端路由的奥秘,也为后端转前端或初学者提供了从零到一的实战指南。
|
16天前
|
机器学习/深度学习 数据采集 JavaScript
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
ADR药品不良反应监测系统是一款智能化工具,用于监测和分析药品不良反应。该系统通过收集和分析病历、处方及实验室数据,快速识别潜在不良反应,提升用药安全性。系统采用Java开发,基于SpringBoot框架,前端使用Vue,具备数据采集、清洗、分析等功能模块,并能生成监测报告辅助医务人员决策。通过集成多种数据源并运用机器学习算法,系统可自动预警药品不良反应,有效减少药害事故,保障公众健康。
ADR智能监测系统源码,系统采用Java开发,基于SpringBoot框架,前端使用Vue,可自动预警药品不良反应
|
2月前
|
数据采集 数据可视化 关系型数据库
【优秀python web设计】基于Python flask的猫眼电影可视化系统,可视化用echart,前端Layui,数据库用MySQL,包括爬虫
本文介绍了一个基于Python Flask框架、MySQL数据库和Layui前端框架的猫眼电影数据采集分析与可视化系统,该系统通过爬虫技术采集电影数据,利用数据分析库进行处理,并使用Echart进行数据的可视化展示,以提供全面、准确的电影市场分析结果。
|
2月前
|
API Java 数据库连接
从平凡到卓越:Hibernate Criteria API 让你的数据库查询瞬间高大上,彻底告别复杂SQL!
【8月更文挑战第31天】构建复杂查询是数据库应用开发中的常见需求。Hibernate 的 Criteria API 以其强大和灵活的特点,允许开发者以面向对象的方式构建查询逻辑,同时具备 SQL 的表达力。本文将介绍 Criteria API 的基本用法并通过示例展示其实际应用。此 API 通过 API 构建查询条件而非直接编写查询语句,提高了代码的可读性和安全性。无论是简单的条件过滤还是复杂的分页和连接查询,Criteria API 均能胜任,有助于提升开发效率和应用的健壮性。
67 0
|
2月前
|
前端开发 数据处理 开发者
解锁Django模板系统终极奥义!揭秘高效前端渲染秘籍,让你的网站秒变炫酷黑科技!
【8月更文挑战第31天】Django作为Python的高级Web框架,内置的模板系统支持动态HTML渲染。本文通过在线书店案例,详细介绍Django模板系统的设置与高效渲染技巧,包括创建模板文件、编写视图函数及URL配置。通过合理使用过滤器、深度查询和模板继承等技巧,提升前端渲染效率和安全性,优化Web应用开发流程。
14 0
|
2月前
|
XML 监控 前端开发
WebTracing:如何使用一款SDK实现前端全链路监控
WebTracing:如何使用一款SDK实现前端全链路监控
118 1
|
3月前
|
存储 开发框架 前端开发
循序渐进VUE+Element 前端应用开发(31)--- 系统的日志管理,包括登录日志、接口访问日志、实体变化历史日志
循序渐进VUE+Element 前端应用开发(31)--- 系统的日志管理,包括登录日志、接口访问日志、实体变化历史日志
下一篇
无影云桌面