如何搭建前端异常监控系统 #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 标签

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


流程图



参考资料


目录
相关文章
|
23天前
|
缓存 监控 前端开发
基于 CoffeeScript 的内网管理监控软件前端代码优化
本文探讨了基于CoffeeScript的内网管理监控软件前端代码优化方法,包括数据请求缓存、界面更新采用虚拟DOM技术以及增强错误处理机制,旨在提升软件性能、响应速度和用户体验。
34 4
|
4月前
|
JavaScript 前端开发 开发者
Vue.js 框架大揭秘:响应式系统、组件化与路由管理,震撼你的前端世界!
【8月更文挑战第27天】Vue.js是一款备受欢迎的前端JavaScript框架,以简洁、灵活和高效著称。本文将从三个方面深入探讨Vue.js:响应式系统、组件化及路由管理。响应式系统为Vue.js的核心特性,能自动追踪数据变动并更新视图。例如,通过简单示例代码展示其响应式特性:`{{ message }}`,当`message`值改变,页面随之自动更新。此外,Vue.js支持组件化设计,允许将复杂界面拆分为独立且可复用的组件,提高代码可维护性和扩展性。如创建一个包含标题与内容的简单组件,并在其他页面中重复利用。
85 3
|
10天前
|
机器学习/深度学习 前端开发 算法
婚恋交友系统平台 相亲交友平台系统 婚恋交友系统APP 婚恋系统源码 婚恋交友平台开发流程 婚恋交友系统架构设计 婚恋交友系统前端/后端开发 婚恋交友系统匹配推荐算法优化
婚恋交友系统平台通过线上互动帮助单身男女找到合适伴侣,提供用户注册、个人资料填写、匹配推荐、实时聊天、社区互动等功能。开发流程包括需求分析、技术选型、系统架构设计、功能实现、测试优化和上线运维。匹配推荐算法优化是核心,通过用户行为数据分析和机器学习提高匹配准确性。
38 3
|
8天前
|
前端开发 搜索推荐 安全
陪玩系统架构设计陪玩系统前后端开发,陪玩前端设计是如何让人眼前一亮的?
陪玩系统的架构设计、前后端开发及前端设计是构建吸引用户、功能完善的平台关键。架构需考虑用户需求、技术选型、安全性等,确保稳定性和扩展性。前端可选用React、Vue或Uniapp,后端用Spring Boot或Django,数据库结合MySQL和MongoDB。功能涵盖用户管理、陪玩者管理、订单处理、智能匹配与通讯。安全性方面采用SSL加密和定期漏洞扫描。前端设计注重美观、易用及个性化推荐,提升用户体验和平台粘性。
34 0
|
4月前
|
机器学习/深度学习 数据采集 数据可视化
基于爬虫和机器学习的招聘数据分析与可视化系统,python django框架,前端bootstrap,机器学习有八种带有可视化大屏和后台
本文介绍了一个基于Python Django框架和Bootstrap前端技术,集成了机器学习算法和数据可视化的招聘数据分析与可视化系统,该系统通过爬虫技术获取职位信息,并使用多种机器学习模型进行薪资预测、职位匹配和趋势分析,提供了一个直观的可视化大屏和后台管理系统,以优化招聘策略并提升决策质量。
240 4
|
22天前
|
监控 前端开发 JavaScript
OCamlScript 用于局域网电脑监控软件前端开发的探索
在数字化时代,局域网电脑监控软件广泛应用于企业管理和教育机构。OCamlScript 作为新兴技术,在此类软件的前端开发中展现出独特潜力,特别是在网络请求、界面更新及用户交互处理方面。通过合理利用其特性,可构建高效稳定的前端应用,提升用户体验,具有广阔的应用前景。
34 9
|
26天前
|
人工智能 自然语言处理 前端开发
【AI系统】LLVM 前端和优化层
本文介绍了 LLVM 编译器的核心概念——LLVM IR,并详细讲解了 LLVM 的前端 Clang 如何将 C、C++ 等高级语言代码转换为 LLVM IR。文章还探讨了编译过程中的词法分析、语法分析和语义分析三个关键步骤,以及 LLVM 优化层的 Pass 机制,包括分析 Pass 和转换 Pass 的作用及依赖关系。
28 3
|
2月前
|
监控 JavaScript 前端开发
前端的混合之路Meteor篇(六):发布订阅示例代码及如何将Meteor的响应数据映射到vue3的reactive系统
本文介绍了 Meteor 3.0 中的发布-订阅模型,详细讲解了如何在服务器端通过 `Meteor.publish` 发布数据,包括简单发布和自定义发布。客户端则通过 `Meteor.subscribe` 订阅数据,并使用 MiniMongo 实现实时数据同步。此外,还展示了如何在 Vue 3 中将 MiniMongo 的 `cursor` 转化为响应式数组,实现数据的自动更新。
|
2月前
|
前端开发 安全 API
前端全栈之路Deno篇(三):一次性搞懂和学会用Deno 2.0 的权限系统详解和多种权限配置权限声明方式
本文深入解析了 Deno 2.0 的权限系统,涵盖主包和第三方包的权限控制机制,探讨了通过命令行参数、权限 API 和配置文件等多种权限授予方式,并提供了代码示例和运行指导,帮助开发者有效管理权限,提升应用安全性。
|
2月前
|
JavaScript 前端开发
前端js,vue系统使用iframe嵌入第三方系统的父子系统的通信
前端js,vue系统使用iframe嵌入第三方系统的父子系统的通信