前言 一直以来我们都是用Sentry做项目监控,不过前段时间我们的Sentry坏掉了 (我搞坏的) 但监控又是很有必要的,在sentry修好之前,我想先寻找一个临时的替代方案,同时发现网上关
一直以来我们都是用Sentry做项目监控,不过前段时间我们的Sentry坏掉了(我搞坏的)
但监控又是很有必要的,在sentry修好之前,我想先寻找一个临时的替代方案,同时发现网上关于ExceptionLess的资料少得可怜,ExceptionLess官方的文档也不是很完善,翻了好久文档和源码,于是有了本文……
关于ExceptionLess写.NetCore的同学应该不会陌生,这个是.Net平台的一款监控工具,跟Sentry差不多,不过我们觉得界面比sentry清爽,信息也比较清晰一目了然,所以我们的.NetCore服务监控全都用ExceptionLess来做。
然后ExceptionLess也是支持前端的,因此,我打算先暂时用ExceptionLess来做我们的前端项目监控。
准备工作在ExceptionLess中创建一个项目,这个懂的都懂,不重复了~
ExceptionLess提供了好几种模式,有Node.js、也有浏览器应用,这里我选的是浏览器应用。
官方还有关于Vue的例子,不过是vue3.x版本的,因为我们目前还在用vue2.x,所以只能自己基于浏览器应用的SDK封装一个来用~
安装ExceptionLess客户端使用yarn安装客户端
yarn add exceptionless
我使用的版本是^1.6.4
在src/utils
下创建一个新的js文件:exceptionless.js
import {ExceptionlessClient} from 'exceptionless/dist/exceptionless';
const exLessClient = ExceptionlessClient.default;
exLessClient.config.apiKey = '';
exLessClient.config.serverUrl = ''
const install = Vue => {
if (install.installed)
return
install.installed = true
Object.defineProperties(Vue.prototype, {
$exLess: {
get() {
return exLessClient
}
}
})
}
export default install
这样实现了把ExceptionLess封装为一个Vue模块
然后编辑main.js
,准备注册模块
import Exceptionless from './utils/exceptionless'
// Exceptionless模块
Vue.use(Exceptionless)
这样,在需要提交日志的地方就可以直接使用:
this.$exLess.submitLog('测试信息')
this.$exLess.submitException(error)
集成到全局异常处理
如果所有异常要自己手动捕获提交的话就太麻烦了,而且会有漏网之鱼
我参考了网上的资料,搞了个vue全局异常处理,把没有手动捕获的异常收集起来,然后一并提交到ExceptionLess平台。
直接上代码,src/utils/errorHandler.js
import {ExceptionlessClient} from 'exceptionless/dist/exceptionless';
const exLessClient = ExceptionlessClient.default;
function isPromise(ret) {
return (ret && typeof ret.then === 'function' && typeof ret.catch === "function")
}
const errorHandler = (error, vm, info) => {
console.error('抛出全局异常', 'vm=', vm, 'info=', info)
console.error(error)
exLessClient.submitException(error)
}
function registerActionHandle(actions) {
Object.keys(actions).forEach(key => {
let fn = actions[key]
actions[key] = function (...args) {
let ret = fn.apply(this, args)
if (isPromise(ret)) {
return ret.catch(errorHandler)
} else { // 默认错误处理
return ret
}
}
})
}
const registerVuex = (instance) => {
if (instance.$options['store']) {
let actions = instance.$options['store']['_actions'] || {}
if (actions) {
let tempActions = {}
Object.keys(actions).forEach(key => {
tempActions[key] = actions[key][0]
})
registerActionHandle(tempActions)
}
}
}
const registerVue = (instance) => {
if (instance.$options.methods) {
let actions = instance.$options.methods || {}
if (actions) {
registerActionHandle(actions)
}
}
}
let GlobalError = {
install: (Vue, options) => {
/**
* 全局异常处理
* @param {*} error
* @param {*} vm
*/
Vue.config.errorHandler = errorHandler
Vue.mixin({
beforeCreate() {
registerVue(this)
registerVuex(this)
}
})
Vue.prototype.$throw = errorHandler
}
}
export default GlobalError
在main.js
中注册
import ErrorHandler from "./utils/errorHandler"
// 全局异步处理模块
Vue.use(ErrorHandler)
搞定~
参考资料- 【实践总结】优雅的处理vue项目异常:https://juejin.cn/post/6844903860121632782
- Vue3 对比 Vue2.x 差异性、注意点、整体梳理,与React hook比又如何:https://juejin.cn/post/6892295955844956167#heading-21