跳转到主要内容
本文档介绍 Web RUM SDK 的高级配置选项,帮助您根据业务需求定制数据收集行为。
RUM 提供多种高级配置选项:

保护敏感数据

屏蔽个人身份信息等敏感数据

关联用户会话

将用户会话与内部用户标识关联

减少数据量

通过采样降低 RUM 数据收集量

增强上下文

为数据添加丰富的上下文信息

覆盖默认 RUM 视图名称

RUM 会在用户访问新页面或 SPA 中 URL 更改时自动生成视图事件。视图名称默认从当前页面 URL 计算,并自动移除变量 ID(包含数字的路径段)。例如,/dashboard/1234/dashboard/9a 会被归一化为 /dashboard/? 您可以通过设置 trackViewsManually 选项手动跟踪视图事件,并为视图指定自定义名称。

配置手动跟踪视图

1

启用手动跟踪

在初始化时设置 trackViewsManuallytrue
rum-init.js
import { flashcatRum } from "@flashcatcloud/browser-rum";

flashcatRum.init({
  applicationId: "<YOUR_APPLICATION_ID>",
  clientToken: "<YOUR_CLIENT_TOKEN>",
  trackViewsManually: true
});
2

调用 startView 方法

在每个新页面或路由更改时调用 startView 方法:
flashcatRum.startView({
  name: "checkout",
  service: "purchase",
  version: "1.2.3",
  context: {
    payment: "Done"
  }
});
name
string
视图名称,默认为页面 URL 路径
service
string
服务名称,默认为创建 RUM 应用时指定的服务
version
string
应用版本,默认为创建 RUM 应用时指定的版本
context
object
视图的附加上下文,应用于视图及其子事件

React Router 集成

RumTracker.jsx
import { matchRoutes, useLocation } from "react-router-dom";
import { routes } from "path/to/routes";
import { flashcatRum } from "@flashcatcloud/browser-rum";
import { useEffect } from "react";

export default function App() {
  let location = useLocation();

  useEffect(() => {
    const routeMatches = matchRoutes(routes, location.pathname);
    const viewName = routeMatches && computeViewName(routeMatches);
    if (viewName) {
      flashcatRum.startView({ name: viewName });
    }
  }, [location.pathname]);

  // ...
}

function computeViewName(routeMatches) {
  let viewName = "";
  for (let index = 0; index < routeMatches.length; index++) {
    const routeMatch = routeMatches[index];
    const path = routeMatch.route.path;
    if (!path) continue;

    if (path.startsWith("/")) {
      viewName = path;
    } else {
      viewName += viewName.endsWith("/") ? path : `/${path}`;
    }
  }
  return viewName || "/";
}

设置视图名称

使用 setViewName 方法更新当前视图的名称,而无需启动新视图:
flashcatRum.setViewName("Checkout");

丰富和控制 RUM 数据

通过 beforeSend 回调函数,您可以在事件发送到 Flashduty 之前对其进行拦截和修改:
  • 丰富事件:添加额外的上下文属性
  • 修改事件:更改事件内容或屏蔽敏感信息
  • 丢弃事件:选择性地丢弃特定 RUM 事件

上下文类型

不同的事件类型对应不同的上下文:
事件类型上下文
ViewLocation 对象
Action触发事件的 Event 和处理堆栈
Resource (XHR)XMLHttpRequestPerformanceResourceTiming 和处理堆栈
Resource (Fetch)RequestResponsePerformanceResourceTiming 和处理堆栈
Resource (Other)PerformanceResourceTiming
ErrorError 对象
Long TaskPerformanceLongTaskTiming

丰富 RUM 事件

为事件添加上下文属性,例如为资源事件添加响应头数据:
flashcatRum.init({
  applicationId: "<YOUR_APPLICATION_ID>",
  clientToken: "<YOUR_CLIENT_TOKEN>",
  beforeSend: (event, context) => {
    if (event.type === "resource" && event.resource.type === "fetch") {
      event.context.responseHeaders = Object.fromEntries(
        context.response.headers
      );
    }
    return true;
  }
});

修改 RUM 事件内容

例如,从视图 URL 中屏蔽电子邮件地址:
flashcatRum.init({
  applicationId: "<YOUR_APPLICATION_ID>",
  clientToken: "<YOUR_CLIENT_TOKEN>",
  beforeSend: (event) => {
    event.view.url = event.view.url.replace(/email=[^&]*/, "email=REDACTED");
  }
});

可修改的属性

属性说明
view.url当前页面的 URL
view.referrer前一个页面的 URL
view.name当前视图名称
service应用的服务名称
version应用版本
action.target.name用户交互的元素(仅限自动收集的操作)
error.message错误消息
error.stack错误堆栈或补充信息
error.resource.url触发错误的资源 URL
resource.url资源 URL
context通过上下文 API 或手动生成事件添加的属性

丢弃 RUM 事件

通过在 beforeSend 中返回 false,可以丢弃特定 RUM 事件:
flashcatRum.init({
  applicationId: "<YOUR_APPLICATION_ID>",
  clientToken: "<YOUR_CLIENT_TOKEN>",
  beforeSend: (event) => {
    if (shouldDiscard(event)) {
      return false;
    }
  }
});
视图事件无法被丢弃。

用户会话

通过为 RUM 会话添加用户信息,您可以:
  • 跟踪特定用户的浏览路径
  • 了解哪些用户受错误影响最大
  • 监控关键用户的性能

用户属性

以下为可选的用户属性,建议至少提供一个:
usr.id
string
唯一用户标识符
usr.name
string
用户友好名称,默认在 RUM UI 中显示
usr.email
string
用户电子邮件,若无名称则显示邮件

用户会话 API

flashcatRum.setUser({
  id: "1234",
  name: "John Doe",
  email: "john@doe.com",
  plan: "premium"
});
用户会话信息更改后,之后的 RUM 事件将包含更新后的信息。注销(调用 clearUser)后,最后一个视图仍保留用户信息,但后续视图和会话级别数据不会。

采样

默认情况下,RUM 会收集所有会话的数据。您可以通过 sessionSampleRate 参数设置采样率来减少收集的会话数量:
flashcatRum.init({
  applicationId: "<YOUR_APPLICATION_ID>",
  clientToken: "<YOUR_CLIENT_TOKEN>",
  sessionSampleRate: 90  // 采集 90% 的会话
});
被采样的会话将不收集任何页面视图及其相关遥测数据。

用户跟踪同意

为遵守 GDPR、CCPA 等隐私法规,RUM 允许在初始化时设置用户跟踪同意状态:
状态行为
"granted"开始收集数据并发送到 Flashduty
"not-granted"不收集任何数据

示例:处理用户同意

flashcatRum.init({
  applicationId: "<YOUR_APPLICATION_ID>",
  clientToken: "<YOUR_CLIENT_TOKEN>",
  trackingConsent: "not-granted"
});

acceptCookieBannerButton.addEventListener("click", function () {
  flashcatRum.setTrackingConsent("granted");
});
同意状态不会在标签页间同步或持久化,您需要在初始化或通过 setTrackingConsent 提供用户决定。

视图上下文

您可以通过以下 API 为当前视图及其子事件添加或修改上下文:
flashcatRum.startView({
  name: "checkout",
  context: {
    hasPaid: true,
    amount: 23.42
  }
});

错误上下文

在捕获错误时,您可以通过 dd_context 属性为错误对象附加本地上下文:
const error = new Error("Something went wrong");
error.dd_context = { component: "Menu", param: 123 };
throw error;

全局上下文

全局上下文会附加到所有 RUM 事件上:
// 添加属性
flashcatRum.setGlobalContextProperty("activity", {
  hasPaid: true,
  amount: 23.42
});

// 删除属性
flashcatRum.removeGlobalContextProperty("codeVersion");

// 替换全局上下文
flashcatRum.setGlobalContext({
  codeVersion: 34
});

// 清除全局上下文
flashcatRum.clearGlobalContext();

// 读取全局上下文
const context = flashcatRum.getGlobalContext();

上下文生命周期

默认情况下,全局上下文和用户上下文存储在当前页面内存中:
  • 页面完全刷新后不会保留
  • 不同标签页或窗口间不共享
启用 storeContextsAcrossPages 选项可以将上下文存储到 localStorage
flashcatRum.init({
  applicationId: "<YOUR_APPLICATION_ID>",
  clientToken: "<YOUR_CLIENT_TOKEN>",
  storeContextsAcrossPages: true
});
  • 不建议在上下文中存储个人身份信息,因为 localStorage 数据会超出用户会话生命周期
  • trackSessionAcrossSubdomains 选项不兼容
  • localStorage 容量限制为 5 MiB

微前端支持

RUM 支持微前端架构,通过堆栈跟踪机制识别事件来源。在 beforeSend 中根据堆栈信息覆盖 serviceversion 属性:
const SERVICE_REGEX = /some-pathname\/(?<service>\w+)\/(?<version>\w+)\//;

flashcatRum.init({
  applicationId: "<YOUR_APPLICATION_ID>",
  clientToken: "<YOUR_CLIENT_TOKEN>",
  beforeSend: (event, context) => {
    const stack = context?.handlingStack || event?.error?.stack;
    const { service, version } = stack?.match(SERVICE_REGEX)?.groups || {};

    if (service && version) {
      event.service = service;
      event.version = version;
    }

    return true;
  }
});
以下事件无法归因于特定来源:自动收集的操作事件、非 XHR/Fetch 的资源事件、视图事件、CORS 和 CSP 违规事件。

集成 RUM 与分布式追踪

集成 RUM 与分布式追踪,可让您将 Web 应用程序的请求与其对应的后端跟踪关联起来,实现完整的前后端链路追踪。

使用方法

使用 allowedTracingUrls 参数配置当前应用的 API 服务域名:
import { flashcatRum } from "@flashcatcloud/browser-rum";

flashcatRum.init({
  applicationId: "<YOUR_APPLICATION_ID>",
  clientToken: "<YOUR_CLIENT_TOKEN>",
  service: "<SERVICE_NAME>",
  env: "<ENV_NAME>",
  version: "1.0.0",
  sessionSampleRate: 100,
  allowedTracingUrls: [
    "https://api.example.com",
    /https:\/\/.*\.my-api-domain\.com/,
    (url) => url.startsWith("https://api.example.com")
  ],
  traceSampleRate: 20
});
allowedTracingUrls 匹配完整 URL,接受以下类型:
类型说明
String匹配任何以该值开头的 URL
RegExp使用正则表达式的 test() 方法检查匹配
Function接收 URL 作为参数,返回 true 表示匹配

追踪协议

分布式追踪通过在 Header 上添加对应的头部字段实现:
traceparent: [version]-[trace id]-[parent id]-[trace flags]
  • version: 当前为 00
  • trace id: 128 bits 的 trace ID,16 进制处理后为 32 个字符
  • parent id: 64 bits 的 span ID,16 进制处理后为 16 个字符
  • trace flags: 代表是否有降采样,01 代表命中采样,00 代表非采样
tracestate: dd=s:[sampling priority];o:[origin]
  • sampling priority: 1 代表 trace 被采样
  • origin: 始终为 RUM,代表通过 RUM SDK 采集
示例
traceparent: 00-00000000000000008448eb211c80319c-b7ad6b7169203331-01
tracestate: dd=s:1;o:rum

如何验证

添加配置后,查看从应用中发送的请求,如能正确携带对应的 header 则说明配置无误。
分布式追踪验证
如您的 HTTP 请求涉及到跨域问题,需要确保请求可通过跨域检测。请确保对应的 server 有跨域相关配置,支持预检请求访问。

注意事项

  • 确保正确配置 applicationIdclientToken,以避免数据上传失败
  • 根据应用需求调整采样率和隐私设置,平衡数据量与合规性
  • 对于微前端或复杂前端框架,建议在框架路由级别实现 startView 逻辑

相关文档

有关 RUM SDK 的更多详细信息,请访问 Flashduty SDK GitHub 仓库