前端监控的意义

前端监控现在已经是老生常谈的一个话题了,我之前的一次面试中就被问到了有没有做过前端监控,我回答没做过。。。然后就没有然后了。

前端的监控对于开发人员和产品经理都有很重要的意义。

对于产品来说,可以通过用户行为的一些埋点上报来判断需求是否成功,哪些模块比较吸引用户,从而方便下一步的决策。

对于开发人员而言,那就更重要了,如果客户反馈线上出现了 bug,然后跟你形容“点这里点哪里然后就炸了”。。。但是我们引入监控之后,不光可以第一时间知道出现异常,而且错误堆栈,触发报错的设备,浏览器的版本等信息都一目了然,这可以大大提高解决 bug 的效率。

注册

sentry 官网进行注册,填写一些必要的注册信息之后回向你的邮箱发送一个验证邮件,点击验证之后就可以开始使用了。

进入之后默认是英文的,相信很多人跟我一样看起来会很不习惯,sentry 是提供了中文界面的,需要进入设置中修改。

点击左上角用户,然后在弹出的菜单中选择 User Setting,在进入的页面中修改 Language 为 Simplified Chinese 然后刷新页面就可以了。

image-20221210155628014

创建应用

准备完成之后我们就可以开始创建应用了,点击左侧菜单的项目,然后右上角点击创建项目。

在创建页面选择我们要添加监控的应用类型,我们这里使用Vue 项目来演示,所以我选择 Vue。

image-20221210160115027

然后选择告警的策略,这里我使用默认的有新的异常时发送告警。

image-20221210160221237

最后填写项目名称,选择团队(注册之后默认会有一个团队),然后点击创建项目就完成了。

image-20221210160410551

项目创建完成之后会弹出对应的集成文档,我们将文档中给出的代码复制到项目中指定的位置即可。

image-20221210160521310

例如我使用的是 Vue3,在安装完 SDK 之后在 main.ts 中添加如下代码

import { createApp } from "vue";
import { createPinia } from "pinia";

import ArcoVue from "@arco-design/web-vue";
import App from "./App.vue";
import "@arco-design/web-vue/dist/arco.css";
import router from "./router";

import * as Sentry from "@sentry/vue";
import { BrowserTracing } from "@sentry/tracing";

const app = createApp(App);

Sentry.init({
  app,
  dsn: "your-dsn",
  integrations: [
    new BrowserTracing({
      routingInstrumentation: Sentry.vueRouterInstrumentation(router),
      tracePropagationTargets: ["localhost", "youronline.site", /^\//],
    }),
  ],
  tracesSampleRate: 1.0,
  logErrors: true,
});

app.use(createPinia()).use(router).use(ArcoVue).mount("#app");

📢注意:Vue在接入Sentry 之后浏览器控制台不会弹出报错,如果需要保留,需要设置logErrors 的值为 true

现在我们就可以进行测试了,我们在页面上添加事件手动抛出一个异常

<script setup lang="ts">
import { ref } from "vue";

const message = ref("");

function handler() {
  throw new Error(message.value || "error");
}
</script>

<template>
  <main :style="{ backgroundColor: '#fff', padding: '20px' }">
    <a-input-search
      :style="{ width: '320px' }"
      placeholder="请输入错误消息"
      button-text="Send"
      search-button
      v-model="message"
      @search="handler"
    />
  </main>
</template>

此时点击 send 之后可以在控制台看到有报错,如果是第一次触发这个异常会收到邮件通知。

image-20221210164824679

进入 sentry 的项目中可以看到错误已经上报了,并且用户具体的操作过程也能看到

image-20221210165119336

到线上环境试一下,此时的报错就不太好看了,因为刚才我们是 localhost 的开发环境,错误堆栈都是能定位到具体组件的,但是线上的代码经过编译之后可读性已经丧失了。

所以此时我们需要将 SourceMap 来解析编译后的代码。

SourceMap

上传 SourceMap 需要用到 Sentry 的 Token,进入用户设置中创建 Token

image-20221210173213630

使用默认的权限即可,如果你要自定义的话,必须要提供的权限是project:releasesorg:read

获取token 之后安装插件,这里需要根据项目使用的环境安装不同的插件,例如 Vite、Webpack 等,更多支持可以查看官网的sourcemap文档

这里以 Vite 为例

$ pnpm i @sentry/vite-plugin -D

然后在 vite.config.ts中添加相关配置,将sentryVitePlugin添加到 plugins 最后,填写好对应的信息之后就可以了。

import sentryVitePlugin from "@sentry/vite-plugin";

export default defineConfig({
    plugins: [
        // ... 省略其他插件
    sentryVitePlugin({
      org: "your-org",
      project: "your-project",
      include: "./dist",
      authToken: "your-token",
    }),
  ],
  build: {
    sourcemap: true
  }
})

每次 build 之后插件会自动将生成的 sourcemap 上传到 Sentry,但是直接上传到欣赏环境会被别人直接拿到源码,所以我们需要在打包时删除所有的 map 文件。

例如我在流水线中可以修改步骤,在编译完成之后删除 map 文件。

stage('构建') {
  steps {
    sh 'pnpm run build && rm -fr ./dist/assets/*.map'
  }
}

上传之后我们可以进入到项目设置中查看 SourceMap来确认是否成功。

image-20221210174639712

如果上传不成功可以根据文档进行排查。

上传完成之后再来看新的告警信息,此时已经可以显示源码中导致错误的代码了。

image-20221210193244796

除了错误堆栈之外,用户的设备信息也一起发送到了 sentry,也可以方便我们从设备以及浏览器版本等方面定位错误。

现在 sentry 已经支持了性能监控,另外用户行为的监控也在内测中了。

注意:使用官网的 sentry 是需要付费的,但是 sentry 是开源的支持私有部署,公司在使用时可以自行部署,由于部署需要的服务器资源比较大,这里就不演示了。


前端小白