Vue 接入 ARMS RUM:异常上报与 SourceMap 还原

Vue 接入 ARMS RUM,配置异常、事件上报与 SourceMap 自动上传。

可观测

Vue 应用接入 ARMS RUM,分别采集 JS 错误、业务异常和业务事件,并通过 SourceMap 将压缩堆栈还原到源码。

配套代码:ARMS-SourceMap-Demo。

环境与工程准备

准备 Node.js 20/22、Go 和目标 RUM 应用。获取应用接入用的 PID、Endpoint,以及符号表上传所需的工作空间、Service ID、地域和构建凭据。

Shell
git clone https://github.com/Roliyal/CROlordCodelibrary.git
cd CROlordCodelibrary/Chapter6Custom/ARMS-SourceMap-Demo/frontend
npm install
npm install vue @arms/rum-browser
npm install -D @arms/rum-vite-plugin

仓库是基础示例,原有构建插件配置使用旧字段。采用当前插件时,按第 4 步更新上传配置;不要直接复用旧地域默认值。

情况 处理方式 用途
未处理的运行时错误 SDK 异常采集 定位代码故障
已被业务捕获的异常 sendException 记录明确需要排查的业务失败
提交、购买、搜索等业务行为 sendCustom 统计行为与业务结果

库存不足、用户取消等正常分支,不必全部记为系统错误。先定清事件语义,错误数量和告警才有参考价值。

填写前端配置并初始化 SDK

在 frontend/.env.local 配置浏览器接入参数:

.env
VITE_ARMS_RUM_PID=<目标RUM应用PID>
VITE_ARMS_RUM_ENDPOINT=<浏览器上报地址>
VITE_APP_VERSION=rum-demo-001

修改后重启开发服务,使构建变量生效。

示例使用 @arms/rum-browser,在创建 Vue 应用前初始化一次:

JavaScript
import armsRum from '@arms/rum-browser'
import { createApp } from 'vue'
import App from './App.vue'

armsRum.init({
  pid: import.meta.env.VITE_ARMS_RUM_PID,
  endpoint: import.meta.env.VITE_ARMS_RUM_ENDPOINT,
  env: import.meta.env.MODE,
  appVersion: import.meta.env.VITE_APP_VERSION
})

createApp(App).mount('#app')

应用标识和上报地址从目标 RUM 应用获取。发布版本使用构建号或提交版本,避免线上多个构建都叫 dev。

采集器参数随 SDK 版本可能变化,接入时应固定依赖并核对该版本文档。Vue 框架内捕获的错误也要检查是否已接入采集;不能默认所有组件错误都会冒泡为浏览器未处理异常。手动上报前先确认现有集成,避免同一错误记录两次。

给页面加上三个测试按钮

在 src/App.vue 分别触发三种记录:

Vue
<script setup>
import armsRum from '@arms/rum-browser'

function throwJsError() {
  setTimeout(() => {
    throw new Error('RUM_SOURCEMAP_TEST')
  }, 0)
}

function sendBizException() {
  armsRum.sendException({
    name: 'ORDER_CREATE_FAILED',
    message: '订单创建失败',
    properties: { stage: 'submit', reason: 'upstream_timeout' }
  })
}

function sendBizEvent() {
  armsRum.sendCustom({
    type: 'biz', name: 'order_submit', group: 'order', value: 1,
    properties: { result: 'failed' }
  })
}
</script>

<template>
  <main>
    <button @click="throwJsError">触发 JS 错误</button>
    <button @click="sendBizException">上报业务异常</button>
    <button @click="sendBizEvent">上报业务事件</button>
  </main>
</template>

setTimeout 中的错误用于测试浏览器未处理异常,避免被 Vue 的组件错误处理先行捕获。

sendException 需要 name、message;sendCustom 需要 type、name。自定义事件进入事件统计,不能到异常列表里找。

事件属性保留用于聚合的稳定字段,不上传密码、Cookie、完整请求头或未经处理的个人信息。异常名也不要拼接用户 ID、订单号等不断变化的内容。

构建 SourceMap,并上传到同一应用

Vite 需要生成独立 SourceMap:

JavaScript
export default defineConfig({
  plugins: [vue()],
  build: { sourcemap: 'hidden' }
})

hidden 不会在 JS 中留下 SourceMap 引用,但 .map 仍会生成。应将它上传到 RUM,并从公开发布的静态资源中排除;仅设置 hidden 不会自动阻止公网访问。

在 vite.config.js 配置自动上传。下列值从 CI 环境变量获取,APP_VERSION 与浏览器应用版本对应:

JavaScript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { rumVitePlugin } from '@arms/rum-vite-plugin'

export default defineConfig({
  plugins: [
    vue(),
    rumVitePlugin({
      workspace: process.env.RUM_WORKSPACE,
      serviceId: process.env.RUM_SERVICE_ID,
      region: process.env.RUM_REGION,
      version: process.env.APP_VERSION,
      accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID,
      accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET,
      stsToken: process.env.ALIBABA_CLOUD_SECURITY_TOKEN,
      clearSourceMap: true
    })
  ],
  build: { sourcemap: 'hidden' },
  server: {
    proxy: {
      '/api': { target: 'http://127.0.0.1:8080', changeOrigin: true }
    }
  }
})

使用 RUM 构建插件时,要按已安装版本配置目标应用、地域、发布版本和构建环境凭据。插件负责注入关联标识,并在正确配置上传后处理符号表。旧版示例里的 pid 配置,不能不经核对就套到新版插件上。

上传凭据只放在本地构建环境或 CI 密钥配置里,不能使用会进入浏览器产物的 VITE_ 变量保存 AccessKey Secret。

启动服务与验证

需要联调 /api/hello 时,在独立终端运行仓库的 Go 后端:

Shell
cd CROlordCodelibrary/Chapter6Custom/ARMS-SourceMap-Demo/backend
go run .
curl -fsS http://127.0.0.1:8080/healthz

前端在配置好构建环境变量后执行:

Shell
npm run build
npm run preview -- --host 127.0.0.1

访问终端输出的预览地址,逐个点击测试按钮。

开发服务器下的源码堆栈,不能替代生产构建验收。应使用真正准备发布的 JS 与 SourceMap 做检查:

  1. 构建并确认 SourceMap 生成、关联标识注入和上传结果。
  2. 部署同一次构建的静态资源,确认 RUM 应用和版本一致。
  3. 在测试环境触发一个带堆栈的错误。
  4. 打开 RUM 异常详情,检查能否还原到源码文件和行列位置。
  5. 分别发送自定义异常和事件,核对它们进入各自的列表。

常见问题

上传成功却没有源码时,检查应用、地域、版本、debugId 及 sourcesContent。这些信息必须对应同一次构建,不能上传旧版本的 .map 再验证新版本 JS。

另一个容易混淆的问题是 Vite 代理:server.proxy 用于开发服务器。把 dist 交给静态服务器后,生产 /api 路由还需要由网关或 Web 服务器配置。

前后端 Trace 关联可以在上述验收通过后再接入,排障时更容易区分异常采集、源码还原和链路传播三个问题。

参考

一丝痕迹

很高兴,在这里遇见你。

头像,随邮箱而来。

填写邮箱后,会自动匹配 Gravatar。