Skip to content
当前页导航

性能监控平台

阿里云 ARMS

官方文档

它可以监测页面打开速度、API请求、PV(浏览数量)、UV(用户数量)、网站所有资源数量、网站性能指标数据、网站故障分析(JS错误、网络错误等)及自定义事件上报。

支持的平台

  • Web & H5
  • 小程序
  • uniapp Vue3版本,Vue2版本不支持
  • flutter
  • React Native
  • 鸿蒙
  • 原生 Android 及 IOS

应用接入代码分享

uniapp 接入

下载安装包

npm install @arms/rum-uniapp

将以下内容添加至/utils目录下的monitor.js文件中以完成初始化。

js
import monitor from '@arms/rum-uniapp';

monitor.init({
  pid: 'you pid',
  endpoint: 'you endpoint',
});

export default monitor;

在应用的入口文件 main.js 中配置 vue 实例。

js
import monitor from './utils/monitor';
import App from './App';
import { createSSRApp } from 'vue';

export function createApp() {
  const app = createSSRApp(App);
  // set vue instance
  monitor.setVue(app);
  return {
    app
  }
}

常用上报方法,文档

js
import armsRum from '@arms/rum-uniapp';

// sendCustom 方法一般用于统计用户行为
armsRum.sendCustom({
  type: 'click', // 用户行为类型
  name: '用户点击行为', // 用户行为名称
  group: 'clickGroup', // 用户行为分组
  properties: { // 自定义属性
    age: 18,
  },
});
  

// sendException 方法一般用于上报异常
armsRum.sendException({
  name: '报错标题', // 异常名称
  message: '异常信息,接口报404了', // 异常信息
  properties: { // 自定义属性
    age: 18,
  },
});

Web端接入

下载安装包

npm install @arms/rum-browser --save

main.js 中引入

js
import ArmsRum from '@arms/rum-browser';
ArmsRum.init({
  pid: "your id",
  endpoint: "your endpoint",
  // 设置环境信息,参考值:'prod' | 'gray' | 'pre' | 'daily' | 'local'
  env: 'local', 
  // 设置路由模式, 参考值:'history' | 'hash'
  spaMode: 'hash',
});

Sentry

官方文档

它是国外的平台,支持直接在线使用,但是数据都是保存在国外服务器。也支持自己部署(免费)。

它可以监测网站性能指标数据、网站故障分析(JS错误、网络错误等)及自定义事件上报。

自己部署

使用docker进行部署,对服务器有要求。官方文档掘金博客

支持的平台

  • Web & H5
  • uniapp:Vue2、Vue3、app、小程序、h5都支持

计费规则

数据支持保留90天

1

应用接入代码分享

uniapp 接入

这是第三方 npm 包,对 sentry 进行了二次封装,使它能用于 uniapp 。

下载安装包

npm install sentry-uniapp

封装 sentry.js ,dsn 创建项目的时候会给,当你突然忘记 dsn 的时候,可以访问这个地址 https://xxxxxx/insights/projects/替换项目名/getting-started/

js
import * as sentry from 'sentry-uniapp';

// 初始化
export function init() {
	sentry.init({
		dsn: "you dsn",
		extraOptions: {
			onmemorywarning: false,
			onerror: false
		}
	});
}

// 设置用户信息
export function setUser(info) {
	sentry.configureScope((scope) => {
		// 设置用户信息
		scope.setUser(info);
	});
}

// 上报异常,无法自定义标题,参数1: Error 对象或字符串 
// 自动化。SDK 会自动提取堆栈跟踪、上下文信息,格式标准。
export function captureException(e) {
	sentry.captureException(e);
}

// 上报异常,可以自定义标题,extra 为附加的对象内容
// 简单快捷。适合上报简单的日志消息。
export function captureMessage(message, extra) {
	sentry.captureMessage(message, {
		extra
	});
}

// 自定义上报事件,高度自定义上报信息
export function captureEvent(obj) {
	sentry.captureEvent({
		message: obj.message,
		level: obj.level || 'error', // 事件级别: error, warning, info, fatal, debug
		tags: obj.tags || {}, // 自定义标签
		extra: obj.extra, // 附加的信息
	});
}

在 App.vue 中引入

js
<script>
	import * as sentry from './sentry.js'
	export default {
		onLaunch: function() {
			console.log('App Launch')
			sentry.init();
		},
		onShow: function() {
			console.log('App Show')
		},
		onHide: function() {
			console.log('App Hide')
		},
		onError: function (e) {
      // 监听 App应用级别的错误并上报
			console.log('app onError', e)
			sentry.captureException(e);
		},
	}
</script>

登录后设置用户信息,方便在 sentry 后台记录的信息中,分辨是哪个用户上报的。

js
// 只需设置一次即可,设置后,每次错误上报都会自动携带这个信息
User {
    id?: string | number,
    email?: string,
    username?: string,
    ip_address?: string,
}

sentry.setUser(user);

上报异常。注意: 在sentry 后台中,如果上报方法中的 message 如果相同,会合并到一起,然后点击进详情,可以查看所有的。

js
// 一般用来统计用户行为
sentry.captureMessage('用户行为', {a: 12});
// 一般用来处理接口报错
sentry.captureEvent({
  message: '首页报错',
  extra: {
    b: 1
  }
});

2

Web 接入

下载安装包

npm install --save @sentry/vue

封装 sentry.js ,dsn 创建项目的时候会给,当你突然忘记 dsn 的时候,可以访问这个地址 https://xxxxxx/insights/projects/替换项目名/getting-started/

js
import * as Sentry from "@sentry/vue";

// 初始化
export function init(obj) {
	Sentry.init(obj);
}
// 设置用户信息
export function setUser(user) {
  Sentry.setUser(user);
}

// 上报异常,无法自定义标题,参数1: Error 对象或字符串  参数2: 附加信息
// 自动化。SDK 会自动提取堆栈跟踪、上下文信息,格式标准。
export function captureException(e, obj) {
	Sentry.captureException(e, obj);
}

// 上报异常,可以自定义标题,extra 为附加的对象内容
export function captureMessage(message, obj) {
	Sentry.captureMessage(message, {
		extra: obj.extra, // 自定义的信息对象
    level: obj.level || 'error', // 事件级别: error, warning, info, fatal, debug
    tags: obj.tags || {} // 自定义标签,对象格式
	});
}

在 main.js 中引入

js
// Vue2 版本
import Vue from "vue";
import Router from "vue-router";
import * as sentryInitl from "@sentry/vue";
import * as Sentry from "./sentry.js";

// 初始化, 如果不需要记录性能指标,可以不配置 integrations, tracesSampleRate, tracePropagationTargets
Sentry.init({
  Vue,
  dsn: "you dsn",
  sendDefaultPii: true,
  // 配置性能追踪集成
  integrations: [sentryInitl.browserTracingIntegration()],
  // 采样率(生产环境建议 0.1-1,开发环境可设为 1), 比例越高,采集的性能数据越多,消耗的资源也越多
  tracesSampleRate: 1,
  // 若需要过滤某些请求,可使用 tracesSampler ,它跟 tracesSampleRate 互斥
  // tracesSampler: (context) => {
  //   // 例如:忽略静态资源请求
  //   if (context.request?.url?.includes('.png')) return 0;
  //   return 1.0;
  // },
  // 指定需要追踪的域名或路径,避免监控无关的第三方资源。 // 监控同源请求 可配置成 /^\//
  tracePropagationTargets: ["localhost", /^\//],
});

Vue.config.errorHandler = function (err, vm, info) {
  Sentry.captureException(err, {
    extra: {
      info: info // Vue 特定的错误信息(例如哪个生命周期钩子出错了)
    } 
  });
}

Vue.config.warnHandler = function (msg, vm, trace) {
  Sentry.captureException(msg, {
    extra: {
      info: trace // Vue 特定的错误信息(例如哪个生命周期钩子出错了)
    } 
  });
}
// 监听资源加载错误
window.addEventListener('error', (e) => {
  if (e.target instanceof HTMLElement) {
    const tagName = e.target.tagName.toLowerCase()
    if (tagName === 'img') {
      console.error('图片加载失败:', e.target.src)
    } else if (tagName === 'script') {
      console.error('JS加载失败:', e.target.src)
    } else if (tagName === 'link') {
      console.error('CSS加载失败:', e.target.href)
    }
  }
}, true)

new Vue({
  router,
  render: (h) => h(App),
}).$mount("#app");
js
// Vue3 版本
import { createApp } from "vue";
import { createRouter } from "vue-router";
import router from "./router";
import * as sentryInitl from "@sentry/vue";
import * as Sentry from "./sentry.js";

const app = createApp({
  // ...
});

// 初始化, 如果不需要记录性能指标,可以不配置 integrations, tracesSampleRate, tracePropagationTargets
Sentry.init({
  app,
  dsn: "you dsn",
  sendDefaultPii: true,
  // 配置性能追踪集成
  integrations: [sentryInitl.browserTracingIntegration()],
  // 采样率(生产环境建议 0.1-1,开发环境可设为 1), 比例越高,采集的性能数据越多,消耗的资源也越多
  tracesSampleRate: 1,
  // 若需要过滤某些请求,可使用 tracesSampler ,它跟 tracesSampleRate 互斥
  // tracesSampler: (context) => {
  //   // 例如:忽略静态资源请求
  //   if (context.request?.url?.includes('.png')) return 0;
  //   return 1.0;
  // },
  // 指定需要追踪的域名或路径,避免监控无关的第三方资源。 // 监控同源请求 可配置成 /^\//
  tracePropagationTargets: ["localhost", /^\//],
});
app.config.errorHandler = function (err, vm, info) {
  Sentry.captureException(err, {
    extra: {
      info: info // Vue 特定的错误信息(例如哪个生命周期钩子出错了)
    } 
  });
}

app.config.warnHandler = function (msg, vm, trace) {
  Sentry.captureException(msg, {
    extra: {
      info: trace // Vue 特定的错误信息(例如哪个生命周期钩子出错了)
    } 
  });
}

// 监听资源加载错误
window.addEventListener('error', (e) => {
  if (e.target instanceof HTMLElement) {
    const tagName = e.target.tagName.toLowerCase()
    if (tagName === 'img') {
      console.error('图片加载失败:', e.target.src)
    } else if (tagName === 'script') {
      console.error('JS加载失败:', e.target.src)
    } else if (tagName === 'link') {
      console.error('CSS加载失败:', e.target.href)
    }
  }
}, true)

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

登录后设置用户信息,方便在 sentry 后台记录的信息中,分辨是哪个用户上报的。

js
// 只需设置一次即可,设置后,每次错误上报都会自动携带这个信息
User {
    id?: string | number,
    email?: string,
    username?: string,
    ip_address?: string,
}

Sentry.setUser(user);

上报异常。注意: 在sentry 后台中,如果上报方法中的 message 如果相同,会合并到一起,然后点击进详情,可以查看所有的。

js
Sentry.captureException(err, {
    extra: {
      info: '水电费'
    } 
  });

Sentry.captureMessage('手动上报一个异常1', {
  level: 'error',
  extra: {
    info: '一些附加信息',
  },
  tags: {
    project: '标签1',
  },
});

3