RUM 配置¶
本文用于承载 HarmonyOS RUM 初始化配置与手动采集能力。
初始化配置¶
import { FTSDK } from '@guancecloud/ft_sdk/src/main/ets/components/FTSDK';
import { FTRUMConfig } from '@guancecloud/ft_sdk/src/main/ets/components/Configs';
const rumConfig = new FTRUMConfig()
.setRumAppId('your-app-id')
.setSamplingRate(1.0)
.setSessionErrorSampleRate(1.0)
.setEnableTraceUserAction(true)
.setEnableTraceUserView(true)
.setEnableTraceUserResource(true)
.setEnableTrackAppANR(true)
.setEnableTrackAppCrash(true)
.setEnableTraceWebView(true);
await FTSDK.installRUMConfig(rumConfig);
| 方法 | 类型 | 必须 | 说明 |
|---|---|---|---|
setRumAppId |
string |
是 | RUM 应用 ID,从[用户访问监测]应用中获取 |
setSamplingRate |
number |
否 | RUM 采样率,范围 [0.0, 1.0],默认 1.0 |
setSessionErrorSampleRate |
number |
否 | 错误采样率,范围 [0.0, 1.0],默认 0.0 |
setEnableTraceUserAction |
boolean |
否 | 是否开启自动动作追踪,默认 false |
setEnableTraceUserView |
boolean |
否 | 是否开启页面追踪,默认 false |
setEnableTraceUserResource |
boolean |
否 | 是否开启资源追踪,默认 false |
setEnableTrackAppANR |
boolean |
否 | 是否开启 ANR 监控,默认 false |
setEnableTrackAppCrash |
boolean |
否 | 是否开启 APP 崩溃监控,默认 false。如需 Native Crash,需依赖 @guancecloud/ft_native |
setEnableTraceWebView |
boolean |
否 | 是否开启 WebView 数据采集,默认 false。如需完整接入,请参考 WebView 数据监测 |
setRumCacheLimitCount |
number |
否 | RUM 数据缓存数量限制,默认 100000,最小值 10000 |
View 手动采集¶
startView(viewName: string, property?: Record<string, object>): void
stopView(property?: Record<string, object>): void
updateLoadTime(loadTime: number): void
自动追踪:
在 RUM 配置中开启 enableTraceUserView 后,SDK 会自动追踪页面跳转,包括:
- 路由导航(
router.pushUrl、router.replaceUrl等) Navigation组件切换
import { FTRUMGlobalManager } from '@guancecloud/ft_sdk/src/main/ets/components/rum/FTRUMGlobalManager';
// 场景 1
FTRUMGlobalManager.getInstance().startView('ProductPage');
// 场景 2: 动态参数
class PropertyWrapper {
value: string | number | boolean;
constructor(v: string | number | boolean) {
this.value = v;
}
}
class ViewProperty {
private properties: Map<string, string | number | boolean> = new Map();
set(key: string, value: string | number | boolean): void {
this.properties.set(key, value);
}
toObject(): Record<string, object> {
const result: Record<string, object> = {} as Record<string, object>;
this.properties.forEach((value, key) => {
result[key] = new PropertyWrapper(value) as object;
});
return result;
}
}
const viewProperty = new ViewProperty();
viewProperty.set('page_category', 'product');
viewProperty.set('page_id', '12345');
FTRUMGlobalManager.getInstance().startView('ProductPage', viewProperty.toObject());
FTRUMGlobalManager.getInstance().updateLoadTime(100000000);
// 场景 1
FTRUMGlobalManager.getInstance().stopView();
// 场景 2: 动态参数
const stopViewProperty = new ViewProperty();
stopViewProperty.set('view_duration', 1000);
FTRUMGlobalManager.getInstance().stopView(stopViewProperty.toObject());
注意事项:
- 自动追踪需要在 RUM 配置中开启
enableTraceUserView(true) - 自动追踪会在页面切换时自动调用
startView和stopView,无需手动调用 - 如果使用条件渲染等场景,仍可手动调用
startView和stopView - 页面名称会自动从路由路径或
Navigation组件名称中提取
Action 手动采集¶
addAction(actionName: string, actionType: string, duration: number, startTime: number, property?: Record<string, object>): void
import { FTRUMGlobalManager } from '@guancecloud/ft_sdk/src/main/ets/components/rum/FTRUMGlobalManager';
// 场景 1: 直接完成
FTRUMGlobalManager.getInstance().addAction('buy_button_click', 'click');
// 场景 2: 动态参数
class PropertyWrapper {
value: string | number | boolean;
constructor(v: string | number | boolean) {
this.value = v;
}
}
class ActionProperty {
private properties: Map<string, string | number | boolean> = new Map();
set(key: string, value: string | number | boolean): void {
this.properties.set(key, value);
}
toObject(): Record<string, object> {
const result: Record<string, object> = {} as Record<string, object>;
this.properties.forEach((value, key) => {
result[key] = new PropertyWrapper(value) as object;
});
return result;
}
}
const actionProperty = new ActionProperty();
actionProperty.set('product_id', '12345');
actionProperty.set('product_name', 'iPhone 15');
FTRUMGlobalManager.getInstance().addActionWithProperty('buy_button_click', 'click', actionProperty.toObject());
// 场景 3: 开始 Action(包含时长计算机制)
FTRUMGlobalManager.getInstance().startAction('buy_button_click', 'click');
FTRUMGlobalManager.getInstance().stopAction();
自动追踪:
在 RUM 配置中开启 enableTraceUserAction 后,SDK 会自动追踪 UI 组件的点击事件。为 Button 组件添加 customProperty 可获取按钮文本:
Button('Buy Now')
.id('buy-btn')
.customProperty('buy-btn', 'Buy Now')
.onClick(() => {
// 点击事件会自动被追踪
})
Resource 手动采集¶
startResource(resourceId: string, property?: Record<string, object>): void
stopResource(resourceId: string): void
addResource(resourceId: string, resourceParams: ResourceParams, netStatusBean?: NetStatusBean): void
自动追踪:
在 RUM 配置中开启 enableTraceUserResource 后,SDK 可自动追踪以下请求:
@guancecloud/ft_sdk:RCP 与 Axios 兼容模式@guancecloud/ft_sdk_ext:基于@kit.NetworkKitHttpInterceptorChain的增强模式,自0.1.14-alpha03起支持,且要求 HarmonyOS API 22+
import { FTRUMGlobalManager } from '@guancecloud/ft_sdk/src/main/ets/components/rum/FTRUMGlobalManager';
import { ResourceParams } from '@guancecloud/ft_sdk/src/main/ets/components/rum/bean/ResourceParams';
import { NetStatusBean } from '@guancecloud/ft_sdk/src/main/ets/components/rum/bean/NetStatusBean';
const resourceId = 'https://api.example.com/data';
FTRUMGlobalManager.getInstance().startResource(resourceId);
const resourceParams = new ResourceParams();
resourceParams.setUrl(resourceId);
resourceParams.setResourceStatus(200);
resourceParams.setResponseContentLength(1024);
resourceParams.resourceType = 'xhr';
const netStatusBean = new NetStatusBean();
netStatusBean.setResourceHostIP('192.168.1.1');
netStatusBean.setDNSTime(10000000);
netStatusBean.setTcpTime(20000000);
netStatusBean.setTTFB(50000000);
netStatusBean.setResponseTime(100000000);
FTRUMGlobalManager.getInstance().stopResource(resourceId);
FTRUMGlobalManager.getInstance().addResource(resourceId, resourceParams, netStatusBean);
Resource 自动追踪¶
开启 enableTraceUserResource(true) 后,SDK 会自动追踪通过 RCP、Axios 兼容模式或 @kit.NetworkKit HTTP 拦截器发送的请求。
RCP 自动追踪接入¶
在 RUM 配置中开启 enableTraceUserResource 后,SDK 会为通过 RCP 发送的 HTTP 请求自动采集 Resource 数据。
从当前版本开始,SDK 不再自动创建或持有全局 RCP Session,而是提供以下能力供业务自行装配:
RCPTraceInterceptor:自动注入 Trace HeadersRCPResourceInterceptor:自动采集Resource数据与性能指标createFTRCPInterceptors():返回默认 RCP 拦截器列表,便于与自定义SessionConfiguration合并createFTRCPTrackConfig():快速生成带默认拦截器和TracingConfiguration的SessionConfiguration
推荐接入方式:使用默认 SessionConfiguration 工厂函数
import { rcp } from '@kit.RemoteCommunicationKit';
import { createFTRCPTrackConfig } from '@guancecloud/ft_sdk/src/main/ets/components/network/FTHttpAutoTrack';
const session = rcp.createSession(
createFTRCPTrackConfig({
baseAddress: 'https://api.example.com'
})
);
// GET 请求
const request = new rcp.Request('/data', 'GET');
const response = await session.fetch(request);
// POST 请求
const headers: rcp.RequestHeaders = { 'Content-Type': 'application/json' };
const postRequest = new rcp.Request('/data', 'POST', headers, { name: 'test' });
const postResponse = await session.fetch(postRequest);
如果项目通过 SDK 根入口导入,也可以使用:
手动装配拦截器
如果需要完全控制 Session 配置,也可以直接使用 SDK 提供的拦截器:
import { rcp } from '@kit.RemoteCommunicationKit';
import { RCPTraceInterceptor, RCPResourceInterceptor } from '@guancecloud/ft_sdk/src/main/ets/components/network/FTHttpAutoTrack';
const session = rcp.createSession({
baseAddress: 'https://api.example.com',
interceptors: [
new RCPTraceInterceptor(),
new RCPResourceInterceptor()
],
requestConfiguration: {
tracing: {
collectTimeInfo: true
}
}
});
TracingConfiguration 说明:
collectTimeInfo: true:建议开启。SDK 依赖response.timeInfo计算 DNS、TCP、SSL、TTFB、下载时间等性能指标incomingHeader/outgoingHeader:可选,默认开启incomingData/outgoingData:默认关闭,以减少额外开销
HTTP 拦截器接入¶
如果业务使用 @kit.NetworkKit 的 http.createHttp() 发起请求,可以通过 @guancecloud/ft_sdk_ext 提供的 HTTP 拦截器完成自动 Trace Header 注入和 Resource 采集。该接入方式自 0.1.14-alpha03 起支持,并要求 HarmonyOS API 22 及以上版本。
请先确保项目已安装:
ft_sdk.har,并在oh-package.json5中声明为@guancecloud/ft_sdkft_sdk_ext.har,并在oh-package.json5中声明为@guancecloud/ft_sdk_ext-
如果通过本地 HAR 安装
ft_sdk_ext.har,还需要在工程根目录的oh-package.json5中增加overrides["@guancecloud/ft_sdk"] = "file:./libs/ft_sdk.har",将其内部依赖改写到本地 HAR -
HttpInitialRequestInterceptor:在请求开始阶段注入 Trace Header,并启动Resource HttpFinalResponseInterceptor:在响应结束阶段补充Resource数据并结束采集createFTHttpInterceptorChain():创建可复用的http.HttpInterceptorChainapplyFTHttpTrack():将默认拦截器链直接挂载到单个http.HttpRequest
提供两种接入方式。
方式一:使用 SDK 提供的默认工厂
import { http } from '@kit.NetworkKit';
import { createFTHttpInterceptorChain } from '@guancecloud/ft_sdk_ext/src/main/ets/components/network/FTHttpAutoTrackExt';
const request = http.createHttp();
const interceptorChain = createFTHttpInterceptorChain();
interceptorChain.apply(request);
try {
const response = await request.request('https://httpbin.org/get', {
method: http.RequestMethod.GET,
header: {
'Accept': 'application/json'
}
});
} finally {
request.destroy();
}
如果希望继续追加业务自己的拦截器,也可以这样写:
import { http } from '@kit.NetworkKit';
import { createFTHttpInterceptorChain } from '@guancecloud/ft_sdk_ext/src/main/ets/components/network/FTHttpAutoTrackExt';
const request = http.createHttp();
const interceptorChain = createFTHttpInterceptorChain({
interceptors: [
new CustomAfterInterceptor()//追加自定义
]
});
interceptorChain.apply(request);
此时执行顺序为:
[
new HttpInitialRequestInterceptor(),
new HttpFinalResponseInterceptor(),
new CustomAfterInterceptor()
]
方式二:手动装配 HttpInterceptorChain
如果业务本身已经有自定义拦截器,或者需要自由决定拦截器顺序,推荐直接手动创建 http.HttpInterceptorChain:
import { http } from '@kit.NetworkKit';
import {
HttpInitialRequestInterceptor,
HttpFinalResponseInterceptor
} from '@guancecloud/ft_sdk_ext/src/main/ets/components/network/FTHttpAutoTrackExt';
const request = http.createHttp();
const interceptorChain = new http.HttpInterceptorChain();
interceptorChain.addChain([
new CustomBeforeInterceptor(),
new HttpInitialRequestInterceptor(),
new HttpFinalResponseInterceptor()
]);
interceptorChain.apply(request);
注意事项:
- HTTP 拦截器依赖
@kit.NetworkKit在 API 22+ 提供的拦截器能力,低于 API 22 时请改用 RCP 或 Axios 兼容模式 HttpRequestContext当前无法稳定拿到真实请求方法,因此Resource中的method会记录为UNKNOWN@kit.NetworkKit的拦截器回调暂不暴露 RCPtimeInfo级别的明细耗时,因此当前只会补充resourceLoad
Axios 接入¶
如果业务使用 @ohos/axios,可按以下方式接入自动追踪:
@guancecloud/ft_sdk:基于 Axiosrequest/response interceptors的兼容模式@guancecloud/ft_sdk_ext:自0.1.14-alpha03起提供基于interceptorChain的增强模式
@ohos/axios 2.2.4 及以上版本¶
import axios from '@ohos/axios';
import { applyFTAxiosTrack } from '@guancecloud/ft_sdk/src/main/ets/components/network/FTHttpAutoTrack';
const client = axios.create({
timeout: 10000
});
applyFTAxiosTrack(client);
该接入方式基于 Axios 的 request/response interceptors,可以与业务自己的拦截器共存使用:
import axios from '@ohos/axios';
import { applyFTAxiosTrack } from '@guancecloud/ft_sdk/src/main/ets/components/network/FTHttpAutoTrack';
const client = axios.create({
timeout: 10000
});
applyFTAxiosTrack(client);
client.interceptors.request.use((config) => {
config.headers = {
...(config.headers || {}),
Authorization: 'Bearer <token>',
'X-Signature': 'signed-value'
};
return config;
});
client.interceptors.response.use((response) => {
return response;
});
执行次序说明:
- 在
@ohos/axioscompat 模式下,request拦截器表现为:后注册先执行 - 这意味着多个
request interceptors可以共存,但注册顺序会影响 FT 看到的是“修改前”还是“修改后”的请求头 - 如果希望 FT 采集到业务补齐鉴权、签名等字段之后的最终请求头,推荐顺序是:先
applyFTAxiosTrack(client),再注册业务request interceptor - 按上述顺序时,业务
request interceptor会先执行,FT 随后执行并读取到最终的headers - 如果希望调整次序,只需调整注册顺序;例如先注册业务、再调用
applyFTAxiosTrack(client)时,FT 会先执行,业务拦截器后执行
@ohos/axios 2.2.8 及以上¶
对于 @ohos/axios 2.2.8 及以上版本,推荐优先通过 @guancecloud/ft_sdk_ext 的 interceptorChain 接入 FT 自动追踪:
import axios from '@ohos/axios';
import { createFTHttpInterceptorChain } from '@guancecloud/ft_sdk_ext/src/main/ets/components/network/FTHttpAutoTrackExt';
const client = axios.create({
timeout: 10000,
interceptorChain: createFTHttpInterceptorChain()
});
如果存在多个 interceptor 共存、需要手动调整执行次序,或者需要与业务自定义拦截器统一装配的场景,可以参考 HTTP 拦截器接入 中的内容,按需自行组合 HttpInitialRequestInterceptor 和 HttpFinalResponseInterceptor。
如果按单次请求传入,也可以这样写:
import axios from '@ohos/axios';
import { createFTHttpInterceptorChain } from '@guancecloud/ft_sdk_ext/src/main/ets/components/network/FTHttpAutoTrackExt';
const response = await axios.request({
url: 'https://httpbin.org/post',
method: 'post',
data: {
source: 'axios',
message: 'ft auto track'
},
responseType: 'string',
interceptorChain: createFTHttpInterceptorChain()
});
注意事项:
- 推荐在创建 Axios 实例时统一注入
interceptorChain,避免遗漏单次请求 interceptorChain模式依赖@guancecloud/ft_sdk_ext(本地 HAR 文件名仍为ft_sdk_ext.har),并要求 HarmonyOS API 22+- 如需自动注入 Trace Headers,除了创建拦截器链外,还需要在 Trace 配置中开启
setEnableAutoTrace(true) - 如需自动采集
Resource,仍需在 RUM 配置中开启setEnableTraceUserResource(true) - 如果调用方已有自定义 HTTP/Axios 拦截器,推荐直接使用
HttpInitialRequestInterceptor、HttpFinalResponseInterceptor手动装配顺序,避免在 FT 自动追踪之后再次改写url、method或headers - SDK 只提供拦截器和默认配置工厂函数,RCP Session 的创建和生命周期由业务自己管理
- 如果业务直接使用
rcp.createSession()创建 Session,需要自行添加 SDK 提供的拦截器,否则请求不会被自动追踪 - 如果业务直接使用
http.createHttp()或@ohos/axios,需要显式挂载applyFTHttpTrack()、applyFTAxiosTrack()或createFTHttpInterceptorChain()
Resource 性能指标说明¶
HarmonyOS SDK 通过 RCP(Remote Call Protocol)的 TimeInfo 接口获取网络请求的性能指标,包括 DNS、TCP、SSL、TTFB(Time To First Byte)等。
TTFB 计算说明:
- HarmonyOS TTFB:使用
startTransferTimeMs - preTransferTimeMs计算,包含服务器处理时间、网络传输时间和响应头接收时间 -
Android TTFB:仅表示响应头接收时间,通常很短
-
DNS 时间:
nameLookupTimeMs - TCP 时间:
connectTimeMs - nameLookupTimeMs - SSL 时间:
tlsHandshakeTimeMs - connectTimeMs - TTFB:
startTransferTimeMs - preTransferTimeMs - 下载时间:
totalTimeMs - startTransferTimeMs
由于 HarmonyOS RCP API 的限制,preTransferTimeMs 几乎等于 SSL 完成时间,因此 HarmonyOS 的 TTFB 会包含服务器处理时间,导致其值通常比 Android 更大。这是预期的平台行为差异,并非 SDK 实现问题。