此页面需要javascript支持,请在浏览器中启用javascript

sentry前端监控for vue(1)

性能
Performance
H5
vue
sentry
阅读 

从 sentry 入手监控

简单的在 sentry.io注册了一个账户

开始由向导进入并且添加监控
发现它针对大量的平台,搞了很多的sdk啥的
我按照监控我线上的博客站 icebreaker.top 的思路

选择了4项贴合的

  • javascript
  • vue
  • node.js
  • express

如图所示:

从 Vue Clinet 开始

yarn add @sentry/vue @sentry/tracing
import Vue from "vue";
import * as Sentry from "@sentry/browser";
import { Integrations } from "@sentry/tracing";

Sentry.init({
  Vue,
  dsn: "https://xxx.ingest.sentry.io",
  autoSessionTracking: true,
  integrations: [
    new Integrations.BrowserTracing(),
  ],

  // We recommend adjusting this value in production, or using tracesSampler
  // for finer control
  tracesSampleRate: 1.0,
});

类似这样,他就做到了前端的简单的监控
当然我们肯定要深入其中,查看@sentry/vue源码中,到底在哪些地方埋了点的

@sentry/vue

从 npm 上查看依赖,看到在运行时是依赖的 @sentry/browser

我们先按照Readme的方式

import Vue from 'vue'
import App from './App'
import router from './router'
import * as Sentry from '@sentry/vue'

Sentry.init({
  Vue: Vue,
  dsn: '__PUBLIC_DSN__',
})

clone getsentry/sentry-javascript

看了一下,所有js的都在里面,也用了 lerna ,有点意思

@sentry/vue 看了一下 rollup,ts 打了2个iife(立即执行函数)包,都是 ES5 Browser Tracing Bundle
只是一个用 terser 压缩了一个没有

tsconfig.esm.json 里面是 ts 打包到 esm/ 下的

显然一个是给es6编程用的,一个cdn或者下载下来直接使用的

我们主要看esm

从 代码看,从@sentry/browser导出了大量的func,index.ts里也没有默认导出

所以要 import * as Sentry from '@sentry/vue' 来用

我们主要看针对Vue的自定义部分

sdk.ts/vuerouter.ts

sdk

这部分就包含了,最重要的 init 方法,看看做了哪些事情

  • 拿Vue的根实例从window或者传入
  • 一堆初始化和meta信息

下面主要就是2个了

  • browserInit
  • VueHelper

browserInit@sentry/browser 的配置,我们主要就看 VueHelper

VueHelper

  • setup

默认开启错误追踪_attachErrorHandler,按选项开启_startTracing

错误追踪很简单,拿到Vue根实例,劫持一下Vue.config.errorHandler

还用了setTimeout 0这种,让它本身的发送请求,进入下一个宏事件循环,Get!
原话是

// Capture exception in the next event loop, to make sure that all breadcrumbs are recorded in time.

主要看发送到sentry服务器的有哪些东西 metadata:

  • componentName
  • propsData (optional)
  • lifecycleHook info info 是 Vue 特定的错误信息,比如错误所在的生命周期钩子

然后就去走 getCurrentHub withScope captureException 这些应该就是发送方法

居然还有事务 getTransaction

_startTracing

_applyTracingHooks

// Don't attach twice, just in case
    if (vm.$options.$_sentryPerfHook) {
      return;
    }
    vm.$options.$_sentryPerfHook = true;

rootHandler 处理根节点的
childHandler 处理子节点的

主要都用的 vm.$once(hook:${hook})

span transaction 这种目前看不懂,要后续看其他包的时候才可以知道

now拿的是'@sentry/utils',难道是Date.now() or performance里的?

hooks

// Each component has it's own scope, so all activities are only related to one of them

appliedTracingHooks 一个500ms的宏事件,打出一个warn?

接下来用一个全局的mixin,附加自个的 beforeCreate hook
在里面清除 appliedTracingHooks 事件和 applyTracingHooks(this)

applyTracingHooks里面也是根据 internalHooks 去劫持原先的钩子

// Mappings from operation to corresponding lifecycle hook.
const HOOKS: { [key in Operation]: Hook[] } = {
  activate: ['activated', 'deactivated'],
  create: ['beforeCreate', 'created'],
  destroy: ['beforeDestroy', 'destroyed'],
  mount: ['beforeMount', 'mounted'],
  update: ['beforeUpdate', 'updated'],
};

然而想要理解这套,还是必须从 '@sentry/types'去找到 Span, Transaction 究竟是个啥

vue-router

vueRouterInstrumentation

检测 vue-routeronError hooks 和 添加一个全局的导航守卫

有意思的是,他通过闭包,在闭包外声明了一个 firstLoad 的 flag:boolean

用来判断,页面是直接进入的,还是通过导航进入的。学习到了

总结

Vue检测

  • Vue.config.xxxxHandler
  • lifecycle hooks
  • mixin

Vue-Router

  • Navigation Guards
  • router.onError
© 2021 icebreaker 苏ICP备19002675号-2
version:1.2.2