Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 507|回复: 0

[转] vue前端异常监控sentry实践

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-5-1 13:51:29 | 显示全部楼层 |阅读模式

    1. 监控原理

    1.1 onerror

    传统的前端监控原理分为异常捕获和异常上报。一般使用onerror捕获前端错误:

    window.onerror = (msg, url, line, col, error) => { console.log('onerror') // TODO }

    1.2 promise

    但是onerror事件无法捕获到网络异常的错误(资源加载失败、图片显示异常等),例如img标签下图片url 404 网络请求异常的时候,onerror无法捕获到异常,此时需要监听unhandledrejection

    window.addEventListener('unhandledrejection', function(err) { console.log(err) })

    1.3 上报

    捕获的异常如何上报?常用的发送形式主要有两种:

    1. 通过 ajax 发送数据(xhr、jquery...)
    2. 动态创建 img 标签的形式
    function report(error) { var reportUrl = 'http://xxxx/report' new Image().src = reportUrl + '?error=' + error }

    1.4 使用sentry

    sentry是一套开源的强大的前端异常监控上报工具,官网地址:https://sentry.io,官方提供了如何搭建sentry服务,此处略过安装流程,直接使用已有的服务。

    1.5 与vue结合

    针对vue,sentry官方推荐使用raven配合sentry进行异常捕获和上报。而在vue中,vue提供了错误捕获方法vue error handler,官方也推荐使用错误追踪服务 sentry 并通过vue error handler选项提供了官方支持。

    2. 安装raven

    raven是sentry官方针对vue推荐的插件,yarn安装raven-js即可。

    $ yarn add raven-js

    3. 初始化sentry

    初始化引入Vue、Raven、RavenVue即可,sentry能主动监听上报错误。

    import Raven from 'raven-js' import RavenVue from 'raven-js/plugins/vue' const dsn = 'https://<key1>@sentry.io/<key2>' Raven.config(dsn).addPlugin(RavenVue, Vue).install()

    4. 手动上报

    对于一些其他信息,如提示日志等,无法自动捕获,需要手动进行上报。

    log (data = null, type = 'error', options = {}) { // 添加面包屑 Raven.captureBreadcrumb({ message: data, category: 'manual message' }) // 异常上报 if (data instanceof Error) { Raven.captureException(data, { level: type, logger: 'manual exception', tags: { options: options } }) } else { Raven.captureException('error', { level: type, logger: 'manual data', extra: { data: data, options: this.options, date: new Date() } }) } }

    5. 封装异常上报类 Report.js

    针对上述内容,封装异常上报类Report,使用单例模式,避免监控类重复实例化。

    /**
     * by csxiaoyao
     * 2019.03.17
     * sunjianfeng@csxiaoyao.com
     */
    import Raven from 'raven-js' import RavenVue from 'raven-js/plugins/vue' class Report { static dsn = 'https://<key1>@sentry.io/<key2>' constructor (Vue, options = {}) { if (process.env.NODE_ENV === 'production') { // TODO } this.Vue = Vue this.options = options } /** * 单例模式 */ static getInstance (Vue, options) { if (!(this.instance instanceof this)) { this.instance = new this(Vue, options) this.instance.install() this.instance.registerError() } return this.instance } /** * init */ install () { Raven.config(Report.dsn, { release: '1.0.0', environment: 'production' // whitelistUrls: [/localhost/, /test\.oa\.com/] }).addPlugin(RavenVue, this.Vue).install() // 记录用户信息 Raven.setUserContext({ user: this.options.user || '' }) // 设置全局tag标签 Raven.setTagsContext({ environment: this.options.env || '' }) } /** * 注册全局错误处理 */ registerError () { // 监听error window.onerror = (msg, url, line, col, error) => { console.log('onerror') if (msg !== 'Script error.' && !url) { return true } setTimeout(() => { let data = {} col = col || (window.event && window.event.errorCharacter) || 0 data.url = url data.line = line data.col = col data.error = error if (&& error.stack) { data.msg = error.stack.toString() } this.log(data) }, 0) return true } // 监听promise window.addEventListener('unhandledrejection', err => { console.log('unhandledrejection') setTimeout(() => { this.log(JSON.stringify(err)) }, 0) }) } /** * 主动上报 * type: 'info','warning','error' */ log (data = null, type = 'error', options = {}) { // 添加面包屑 Raven.captureBreadcrumb({ message: data, category: 'manual message' }) // 异常上报 if (data instanceof Error) { Raven.captureException(data, { level: type, logger: 'manual exception', tags: { options: options } }) } else { Raven.captureException('error', { level: type, logger: 'manual data', extra: { data: data, options: this.options, date: new Date() } }) } } } export default Report

    6. 调用 Report.js 类

    main.js中引入Report类,并绑定实例化后的sentry实例到Vue上以便全局调用。

    import Report from '@/assets/Report' let sentry = Report.getInstance(Vue, {}) Vue.prototype.$sentry = sentry // 设置全局变量

    在其他的vue组件中手动上报日志。

    this.$sentry.log('test')

    7. sourceMap

    sentry针对压缩过的js文件提供了sourceMap分析,只需要上传版本对应的sourceMap,就可以在错误日志中查看对应的源码信息。详细方法见官方文档:https://docs.sentry.io/clients/javascript/sourcemaps/(https://docs.sentry.io/clients/javascript/sourcemaps/)

     

    转自:https://cloud.tencent.com/developer/article/1404307

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-18 22:56 , Processed in 0.068851 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表