这篇文章也发在个人博客,欢迎围观😄javascript
前端监控是相对于后端监控而言的,以往的后端监控只能记录接口被请求以后所发生的错误,可是如今随着用户复杂度不断提升,不少错误是在后端接口被请求之前就发生的JS错误。对于这种错误,传统的后端错误监控是无能为力的,所以前端监控应运而生。前端
最近想在公司的项目上部署前端监控,以主动捕捉用户端的错误(知足咱们本身的控制欲😄),再也不等待用户的反馈(事实上用户的反馈少之又少😓)。原本考虑本身写一个,奈何水平有限,加之看到已经有很多成熟的方案,因此...大家懂得!目前较为成熟的前端监控方案,具体参考知乎帖子 如何作前端异常监控 ,大体上可供选择的方案以下:vue
由于是想部署到公司本身的服务器上,上述貌似只有Sentry和BetterJS有提供自行部署的方案。而后考虑到目前前端项目都是压缩打包后再发布的,可以结合sourcemaps对错误进行定位是很是有必要的,所以从二者中选择了Sentry。(上述方案中,Fundebug也是支持sourcemaps的)java
做为试用,我选择使用Sentry提供的服务,注册帐号以后,选择使用免费版的服务,就能够开始在前端对咱们的项目加入前端错误监控了。webpack
首先,固然是要看Sentry提供的docs了,建立项目的步骤能够说是介绍得很是清楚了。git
OK,建立一个新项目以后,就应该到个人前端项目中引入监控的模块了。此处,由于个人项目是使用Vue的SPA项目,因此使用的是Sentry官方推荐的Raven.js。下载该模块以后,按照官方指引在项目中引入文件,其中key和project在你注册帐号以后官方都会自动帮你生成的,很是贴心。github
// main.js
import Raven from 'raven-js'
import RavenVue from 'raven-js/plugins/vue'
Raven
.config('https://<key>@sentry.io/<project>')
.addPlugin(RavenVue, Vue)
.install()
复制代码
这时候,你只要在你项目中的一个不起眼的角落埋下一个错误,而后去触发一下,就能看到调用了raven.js发送错误,而且在你的sentry项目中也能看到相关报错了。web
可是这样的报错信息其实意义不大,除了可以看到具体的error缘由外,错误位置根本无从定位。若是错误信息没有具体到咱们足以立刻定位出错误位置,那么咱们只能一遍遍地对代码进行排查,耗时耗力。这时候就要使用sourcemaps对错误进行定位了,所幸Sentry对此的支持也是很是好的。npm
首先,咱们来看官方文档对引入sourcemaps的说明。Sentry容许咱们经过三种方式使用sourcemaps,releases API, sentry-cli, sentry-webpack-plugin。考虑到项目构建过程当中就一并提交sourcemaps,我我的仅仅实践了最后一种。json
// 来自官方的步骤
1. Start by creating a new authentication token under **[Account] > API**.
2. Ensure you have project:write selected under scopes.
3. Install @sentry/webpack-plugin using npm
4. Create .sentryclirc file with necessary config (see Sentry Webpack Plugin docs below)
5. Update your webpack.config.json
复制代码
下面咱们来实践一下:
前两步,很是简单,略过略过。
对于第三步, 我我的发现仅仅install @sentry/webpack-plugin彷佛仍是不够的,还须要install @sentry/cli,不知道是我我的问题,敬请指出。
第四步,多是我对这种配置格式不太熟悉,折腾最久就是这一步了。给出官方配置说明,下面是个人基础配置(其实就是将如defaults.url,auth.token等拆分,写入配置文件便可),在项目根目录下:
// .sentryclirc
[defaults]
url = https://sentry.io/
<!-- 此处能够从你的sentry.io的全路径看出,如:https://sentry.io/此处是你的org/此处是你的project/ -->
org =
project =
[auth]
token = 此处就是你第一步第二步建立的token
复制代码
第五步,更新个人webpack配置,配置个人监控模块
此处参考了一位兄弟的文章,他用了另一个Plugin实现,请围观。
此处声明,这位大兄弟文中的方法都很好,可是对于须要截取7位数的参数做为版本号的问题,我我的实践是截取后Raven.js没法传递正确版本号了,反而不截取可以传递正确版本号!经过查看Raven.js的post,发现release很是长,不止7位。
下面这个步骤的urlPrefix属性特别关键,这个是给上传的文件添加前缀的,由于sentry除了根据版本号,还要匹配特定版本号中的路径。这个属性的默认值是~/,而~是仅仅是去掉了网址前面的协议和域名,即拼接起来的map资源路径是http://host/static/js/app.js.map。可是若是像个人站点,多了一级路径,那么就须要配置这个属性了,不然上传到Sentry的maps就没法访问到了。
// webpack.prod.conf.js
const SentryPlugin = require('@sentry/webpack-plugin');
plugins: [
new SentryPlugin({
include: './dist',
release: process.env.RELEASE_VERSION,
configFile: 'sentry.properties',
urlPrefix: '~/TechPage/', // 若是不须要也能够不传这个参
}),
]
复制代码
就是下面这个步骤,不该该截取
// prod.env.js
let gitSha = require('child_process').execSync('git rev-parse HEAD').toString().trim()
// process.env.RELEASE_VERSION = gitSha.substr(2, 9) 不该截取
process.env.RELEASE_VERSION = gitSha
module.exports = {
RELEASE_VERSION: `"${gitSha}"`,
NODE_ENV: '"production"'
}
复制代码
// main.js
import Raven from 'raven-js'
import RavenVue from 'raven-js/plugins/vue'
Raven
.config('https://<key>@sentry.io/<project>', {
release: process.env.RELEASE_VERSION,
debug: true
})
.addPlugin(RavenVue, Vue)
.install()
复制代码
因为sentry是经过release版本匹配一致的方式,使用特定版本的sourcemaps去定位错误的,所以咱们须要在项目构建的时候生成一个特定的版本号,将这个版本号赋值给Raven.js以及SentryPlugin,这样就能造成对应关系。固然你也能够经过另外的方式生成相应的release版本号,这都是能够的,只要是可以惟一对应就能够了。即便你没有造成对应关系,但只要你发布了source maps,Sentry默认是会根据js文件中的sourceMappingURL去找到map文件,而后定位错误的。
Raven.js的配置官方文档也是有详细说明的,详情点击。此处我仅仅配置了release以及debug,设置debug为true的话,Raven.js会将一些debug信息输出到控制台。
至此,你触发项目中的错误,就能得到下面的效果,错误信息也成功定位了,很是的清楚。
此处是参照上面提到那位兄弟的作法了,不过他提到了要在上传sourcemaps到sentry以后删除,不让终端用户接触,这是对的 。可是我这边删除以后,用户端发生错误以后,没有办法把定位后的错误信息返回了,返回的错误信息都是编译打包以后的代码的,可读性通常。若是发现我哪里配置错误,敬请指出。
通过踩坑,正是因为没有正确配置urlPrefix(@sentry/webpack-plugin中的属性,webpack-sentry-plugin中是配置filenameTransform方法),因此当我不发布source maps时,没法定位错误。
const SentryPlugin = require('webpack-sentry-plugin');
plugins: [
new SentryPlugin(Object.assign({
release: process.env.RELEASE_VERSION,
deleteAfterCompile: true,
suppressErrors: true,
/** filenameTransform: function (filename) { var pub = config.build.assetsPublicPath if (/^\/\//.test(pub)) pub = 'http:' + pub var urlObj = require('url').parse(pub) return '~' + urlObj.pathname.replace(/\/+$/, '') + '/' + filename } */
filenameTransform: function (filename) {
return '~/TechPage/' + filename
},
}, require('../sentry.conf.js'))),
]
复制代码
// sentry.conf.js(位于根目录)
module.exports = {
// 此处能够从你的sentry.io的全路径看出,如:https://sentry.io/此处是你的org/此处是你的project
organisation: '',
project: '',
apiKey: ''
}
复制代码
这种配置,我获得的报错信息是这样的,以下图:
通过配置,可以在不发布source maps的状况下,获得完整的错误定位!
若是想将Sentry部署到本身的服务器,Sentry官方也有详细的文档,各位请移步。
各位看官若是发现文中个人错处,请必定不要嫌麻烦,请开展花式吐槽!谢谢!
也欢迎上个人Demo网站点击建立时间一栏触发错误看看Sentry的效果,谢谢!
此处感谢 @时间是海 的提醒,参考了sentry社区里的问题才注意到urlPrefix这个问题。附上社区的两篇帖子: