RUM Configuration¶
This article covers the HarmonyOS RUM initialization configuration and manual collection capabilities.
RUM Initialization Configuration¶
import { FTSDK, FTRUMConfig } from '@guancecloud/ft_sdk/Index';
const rumConfig = new FTRUMConfig()
.setRumAppId('your-app-id')
.setSamplingRate(1.0)
.setSessionErrorSampleRate(1.0)
.setEnableTraceUserAction(true)
.setEnableTraceUserView(true)
.setEnableTraceUserResource(true)
.setEnableTrackAppUIBlock(true)
.setEnableTrackAppANR(true)
.setEnableTrackAppCrash(true)
.setEnableTraceWebView(true);
await FTSDK.installRUMConfig(rumConfig);
| Method | Type | Required | Description |
|---|---|---|---|
setRumAppId |
string |
Yes | RUM application ID, obtained from the [RUM] application |
setSamplingRate |
number |
No | RUM sampling rate, range [0.0, 1.0], default 1.0 |
setSessionErrorSampleRate |
number |
No | Error sampling rate, range [0.0, 1.0], default 0.0 |
setEnableTraceUserAction |
boolean |
No | Whether to enable automatic action tracing, default false |
setEnableTraceUserView |
boolean |
No | Whether to enable page tracing, default false |
setEnableTraceUserResource |
boolean |
No | Whether to enable resource tracing, default false |
setEnableTrackAppUIBlock |
boolean |
No | Whether to enable UI blocking detection, default false |
setEnableTrackAppANR |
boolean |
No | Whether to enable ANR monitoring, default false |
setEnableTrackAppCrash |
boolean |
No | Whether to enable APP crash monitoring, default false. For Native Crash, requires dependency on @guancecloud/ft_native |
setEnableTraceWebView |
boolean |
No | Whether to enable WebView data collection, default false. For complete integration, refer to WebView Data Monitoring |
setRumCacheLimitCount |
number |
No | RUM data cache limit count, default 100000, minimum 10000 |
setRumCacheDiscardStrategy |
RUMCacheDiscard |
No | Sets the RUM data discard rule when the limit is reached, default is RUMCacheDiscard.DISCARD, DISCARD discards appended data, DISCARD_OLDEST discards oldest data |
RUM Manual Collection¶
Configure setEnableTraceUserAction, setEnableTraceUserView, setEnableTraceUserResource, setEnableTrackAppUIBlock, setEnableTrackAppCrash, and setEnableTrackAppANR in FTRUMConfig to enable automatic collection of Action, View, Resource, LongTask, and Error. For custom collection, use FTRUMGlobalManager for manual reporting.
View¶
startView(viewName: string, property?: Record<string, object>): void
stopView(property?: Record<string, object>): void
updateLoadTime(loadTime: number): void
Automatic Tracing:
After enabling enableTraceUserView in the RUM configuration, the SDK automatically traces page navigation, including:
- Route navigation (
router.pushUrl,router.replaceUrl, etc.) Navigationcomponent switching
import { FTRUMGlobalManager } from '@guancecloud/ft_sdk/Index';
// Scenario 1
FTRUMGlobalManager.getInstance().startView('ProductPage');
// Scenario 2: Dynamic parameters
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);
// Scenario 1
FTRUMGlobalManager.getInstance().stopView();
// Scenario 2: Dynamic parameters
const stopViewProperty = new ViewProperty();
stopViewProperty.set('view_duration', 1000);
FTRUMGlobalManager.getInstance().stopView(stopViewProperty.toObject());
Notes:
- Automatic tracing requires enabling
enableTraceUserView(true)in the RUM configuration - Automatic tracing automatically calls
startViewandstopViewduring page transitions, no manual calls needed - For scenarios like conditional rendering, manual calls to
startViewandstopVieware still possible - Page names are automatically extracted from route paths or
Navigationcomponent names
Action¶
addAction(actionName: string, actionType: string, duration: number, startTime: number, property?: Record<string, object>): void
import { FTRUMGlobalManager } from '@guancecloud/ft_sdk/Index';
// Scenario 1: Direct completion
FTRUMGlobalManager.getInstance().addAction('buy_button_click', 'click');
// Scenario 2: Dynamic parameters
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());
// Scenario 3: Start Action
FTRUMGlobalManager.getInstance().startAction('buy_button_click', 'click');
Automatic Tracing:
After enabling enableTraceUserAction in the RUM configuration, the SDK automatically traces click events on UI components. Adding customProperty to a Button component captures the button text:
Button('Buy Now')
.id('buy-btn')
.customProperty('buy-btn', 'Buy Now')
.onClick(() => {
// Click events are automatically traced
})
Error¶
addError(
log: string,
message: string,
errorType: string | ErrorType,
state: AppState,
property?: Record<string, object> | null,
dateline?: number,
callBack?: RunnerCompleteCallBack | null
): void
addCustomError(errorMessage: string, errorStack?: string, property?: Record<string, object>): void
import { FTRUMGlobalManager, ErrorType, AppState } from '@guancecloud/ft_sdk/Index';
class PropertyWrapper {
value: string | number | boolean;
constructor(v: string | number | boolean) {
this.value = v;
}
}
class ErrorProperty {
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;
}
}
try {
throw new Error('checkout failed');
} catch (err) {
const error = err instanceof Error ? err : new Error(String(err));
const errorProperty = new ErrorProperty();
errorProperty.set('module', 'checkout');
errorProperty.set('action', 'submit_order');
// Scenario 1: Report custom Error
FTRUMGlobalManager.getInstance().addCustomError(
error.message,
error.stack ?? '',
errorProperty.toObject()
);
// Scenario 2: Specify Error type and application state
FTRUMGlobalManager.getInstance().addError(
error.stack ?? '',
error.message,
ErrorType.CUSTOM,
AppState.RUN,
errorProperty.toObject()
);
}
LongTask¶
addLongTask(log: string, duration: number, property?: Record<string, string | number | boolean>): void
duration unit is nanoseconds.
import { FTRUMGlobalManager } from '@guancecloud/ft_sdk/Index';
const durationMs = 350;
const durationNs = durationMs * 1000000;
const stack = new Error('checkout render long task').stack ?? 'Stack trace not available';
FTRUMGlobalManager.getInstance().addLongTask(
stack,
durationNs,
{
module: 'checkout',
operation: 'render_order_list',
threshold_ms: 200
}
);
Resource¶
startResource(resourceId: string, property?: Record<string, object>): void
stopResource(resourceId: string): void
addResource(resourceId: string, resourceParams: ResourceParams, netStatusBean?: NetStatusBean): void
Automatic Tracing:
After enabling enableTraceUserResource in the RUM configuration, the SDK can automatically trace the following requests:
@guancecloud/ft_sdk: RCP and Axios compatibility mode@guancecloud/ft_sdk_ext: Enhanced mode based on@kit.NetworkKitHttpInterceptorChain, supported since0.1.14-alpha03, and requires HarmonyOS API 22+
import {
FTRUMGlobalManager,
ResourceParams,
NetStatusBean
} from '@guancecloud/ft_sdk/Index';
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 Automatic Tracing¶
After enabling enableTraceUserResource(true), the SDK automatically traces requests sent via RCP, Axios compatibility mode, or @kit.NetworkKit HTTP interceptors.
When integrating @guancecloud/ft_sdk_ext, it is recommended to uniformly import public APIs from @guancecloud/ft_sdk_ext/Index, avoiding deep paths like src/main/....
RCP Automatic Tracing Integration¶
After enabling enableTraceUserResource in the RUM configuration, the SDK automatically collects Resource data for HTTP requests sent via RCP.
Starting from the current version, the SDK no longer automatically creates or holds a global RCP Session. Instead, it provides the following capabilities for business to assemble themselves:
RCPTraceInterceptor: Automatically injects Trace HeadersRCPResourceInterceptor: Automatically collectsResourcedata and performance metricscreateFTRCPInterceptors(): Returns a default list of RCP interceptors, facilitating merging with customSessionConfigurationcreateFTRCPTrackConfig(): Quickly generates aSessionConfigurationwith default interceptors andTracingConfiguration
Recommended Integration Method: Using the default SessionConfiguration factory function
import { rcp } from '@kit.RemoteCommunicationKit';
import { createFTRCPTrackConfig } from '@guancecloud/ft_sdk/Index';
const session = rcp.createSession(
createFTRCPTrackConfig({
baseAddress: 'https://api.example.com'
})
);
// GET request
const request = new rcp.Request('/data', 'GET');
const response = await session.fetch(request);
// POST request
const headers: rcp.RequestHeaders = { 'Content-Type': 'application/json' };
const postRequest = new rcp.Request('/data', 'POST', headers, { name: 'test' });
const postResponse = await session.fetch(postRequest);
If the project imports via the SDK root entry, you can also use:
Manual Assembly of Interceptors
If complete control over Session configuration is needed, you can also directly use the interceptors provided by the SDK:
import { rcp } from '@kit.RemoteCommunicationKit';
import { RCPTraceInterceptor, RCPResourceInterceptor } from '@guancecloud/ft_sdk/Index';
const session = rcp.createSession({
baseAddress: 'https://api.example.com',
interceptors: [
new RCPTraceInterceptor(),
new RCPResourceInterceptor()
],
requestConfiguration: {
tracing: {
collectTimeInfo: true
}
}
});
TracingConfiguration Explanation:
collectTimeInfo: true: Recommended to enable. The SDK relies onresponse.timeInfoto calculate performance metrics such as DNS, TCP, SSL, TTFB, download time, etc.incomingHeader/outgoingHeader: Optional, enabled by defaultincomingData/outgoingData: Disabled by default to reduce additional overhead
HTTP Interceptor Integration¶
If the business uses @kit.NetworkKit's http.createHttp() to initiate requests, automatic Trace Header injection and Resource collection can be completed via the HTTP interceptor provided by @guancecloud/ft_sdk_ext. This integration method is supported since 0.1.14-alpha03 and requires HarmonyOS API 22 or higher.
First, ensure the project has installed:
ft_sdk.har, and declared as@guancecloud/ft_sdkinoh-package.json5ft_sdk_ext.har, and declared as@guancecloud/ft_sdk_extinoh-package.json5- If installing
ft_sdk_ext.harvia local HAR, also addoverrides["@guancecloud/ft_sdk"] = "file:./libs/ft_sdk.har"to the project root'soh-package.json5to rewrite its internal dependency to the local HAR
The SDK provides the following capabilities:
HttpInitialRequestInterceptor: Injects Trace Header at the request start stage and startsResourceHttpFinalResponseInterceptor: CompletesResourcedata and ends collection at the response end stagecreateFTHttpInterceptorChain(): Creates a reusablehttp.HttpInterceptorChainapplyFTHttpTrack(): Directly mounts the default interceptor chain to a singlehttp.HttpRequest
Two integration methods are provided.
Method 1: Using the SDK-provided default factory
import { http } from '@kit.NetworkKit';
import { createFTHttpInterceptorChain } from '@guancecloud/ft_sdk_ext/Index';
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();
}
If you wish to continue adding your own business interceptors, you can also write it like this:
import { http } from '@kit.NetworkKit';
import { createFTHttpInterceptorChain } from '@guancecloud/ft_sdk_ext/Index';
const request = http.createHttp();
const interceptorChain = createFTHttpInterceptorChain({
interceptors: [
new CustomAfterInterceptor()//Add custom
]
});
interceptorChain.apply(request);
The execution order in this case is:
[
new HttpInitialRequestInterceptor(),
new HttpFinalResponseInterceptor(),
new CustomAfterInterceptor()
]
Method 2: Manually assembling HttpInterceptorChain
If the business already has custom interceptors or needs to freely decide the interceptor order, it is recommended to directly create http.HttpInterceptorChain manually:
import { http } from '@kit.NetworkKit';
import {
HttpInitialRequestInterceptor,
HttpFinalResponseInterceptor
} from '@guancecloud/ft_sdk_ext/Index';
const request = http.createHttp();
const interceptorChain = new http.HttpInterceptorChain();
interceptorChain.addChain([
new CustomBeforeInterceptor(),
new HttpInitialRequestInterceptor(),
new HttpFinalResponseInterceptor()
]);
interceptorChain.apply(request);
Notes:
- HTTP interceptor relies on the interceptor capability provided by
@kit.NetworkKitat API 22+. For versions below API 22, please switch to RCP or Axios compatibility mode. - In the HTTP interceptor mode using
http.createHttp()directly,HttpRequestContextcurrently cannot stably obtain the real request method, so themethodinResourcemay be recorded asUNKNOWN. - If the business uses
@ohos/axios'sinterceptorChainmode, it is recommended to additionally mountapplyFTAxiosChainMethodBridge()to bridge axios's real method, url, and headers. - The interceptor callbacks of
@kit.NetworkKitdo not currently expose detailed timing like RCPtimeInfo, so currently onlyresourceLoadwill be supplemented.
Axios Integration¶
If the business uses @ohos/axios, automatic tracing can be integrated as follows:
@guancecloud/ft_sdk: Compatibility mode based on Axiosrequest/response interceptors@guancecloud/ft_sdk_ext: Enhanced mode based oninterceptorChainprovided since0.1.14-alpha03
@ohos/axios version 2.2.4 and above¶
This integration method is based on Axios's request/response interceptors.
import axios from '@ohos/axios';
import { applyFTAxiosTrack } from '@guancecloud/ft_sdk/Index';
const client = axios.create({
timeout: 10000
});
applyFTAxiosTrack(client);
This integration method can coexist with the business's own interceptors:
import axios from '@ohos/axios';
import { applyFTAxiosTrack } from '@guancecloud/ft_sdk/Index';
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;
});
Execution Order Explanation:
- In
@ohos/axioscompat mode,requestinterceptors behave as: last registered, first executed - This means multiple
request interceptorscan coexist, but the registration order affects whether FT sees the "before modification" or "after modification" request headers - If you want FT to collect the final request headers after business supplements authentication, signature, and other fields, the recommended order is: first
applyFTAxiosTrack(client), then register businessrequest interceptor - With the above order, the business
request interceptorexecutes first, FT executes subsequently and reads the finalheaders - If you want to adjust the order, simply adjust the registration order; for example, when registering business first and then calling
applyFTAxiosTrack(client), FT executes first, and the business interceptor executes later
@ohos/axios 2.2.8 and above¶
For @ohos/axios 2.2.8 and above, it is recommended to prioritize integrating FT automatic tracing via interceptorChain from @guancecloud/ft_sdk_ext:
import axios from '@ohos/axios';
import {
createFTHttpInterceptorChain,
applyFTAxiosChainMethodBridge
} from '@guancecloud/ft_sdk_ext/Index';
const client = axios.create({
timeout: 10000,
interceptorChain: createFTHttpInterceptorChain()
});
applyFTAxiosChainMethodBridge(client);
const response = await client.post('https://api.example.com/data', {
source: 'axios',
message: 'ft auto track'
});
If multiple interceptors coexist, requiring manual adjustment of execution order, or scenarios requiring unified assembly with business custom interceptors, refer to the content in HTTP Interceptor Integration and combine HttpInitialRequestInterceptor and HttpFinalResponseInterceptor as needed.
If passing per request, you can also write:
import axios from '@ohos/axios';
import { createFTHttpInterceptorChain } from '@guancecloud/ft_sdk_ext/Index';
const response = await axios.request({
url: 'https://httpbin.org/post',
method: 'post',
data: {
source: 'axios',
message: 'ft auto track'
},
responseType: 'string',
interceptorChain: createFTHttpInterceptorChain()
});
Notes:
- It is recommended to uniformly inject
interceptorChainwhen creating the Axios instance and callapplyFTAxiosChainMethodBridge(client)to avoid missing the bridge causing inaccurateResourcemethod recording. - The
interceptorChainmode relies on@guancecloud/ft_sdk_ext(local HAR file name is stillft_sdk_ext.har) and requires HarmonyOS API 22+. - For automatic injection of Trace Headers, besides creating the interceptor chain,
setEnableAutoTrace(true)must also be enabled in the Trace configuration. - For automatic collection of
Resource,setEnableTraceUserResource(true)must still be enabled in the RUM configuration. - If the caller already has custom HTTP/Axios interceptors, it is recommended to directly use
HttpInitialRequestInterceptor,HttpFinalResponseInterceptorto manually assemble the order, avoiding rewritingurl,method, orheadersagain after FT automatic tracing. - The SDK only provides interceptors and default configuration factory functions; the creation and lifecycle of the RCP Session are managed by the business itself.
- If the business directly uses
rcp.createSession()to create a Session, it needs to add the interceptors provided by the SDK itself; otherwise, requests will not be automatically traced. - If the business directly uses
http.createHttp()or@ohos/axios, it needs to explicitly mountapplyFTHttpTrack(),applyFTAxiosTrack(),createFTHttpInterceptorChain(); AxiosinterceptorChainmode also requires callingapplyFTAxiosChainMethodBridge(client).
Resource Performance Metrics Explanation¶
The HarmonyOS SDK obtains network request performance metrics, including DNS, TCP, SSL, TTFB (Time To First Byte), etc., through RCP's (Remote Call Protocol) TimeInfo interface.
TTFB Calculation Explanation:
- HarmonyOS TTFB: Calculated using
startTransferTimeMs - preTransferTimeMs, includes server processing time, network transmission time, and response header reception time -
Android TTFB: Only represents response header reception time, usually very short
-
DNS time:
nameLookupTimeMs - TCP time:
connectTimeMs - nameLookupTimeMs - SSL time:
tlsHandshakeTimeMs - connectTimeMs - TTFB:
startTransferTimeMs - preTransferTimeMs - Download time:
totalTimeMs - startTransferTimeMs
Due to limitations of the HarmonyOS RCP API, preTransferTimeMs is almost equal to the SSL completion time. Therefore, HarmonyOS's TTFB includes server processing time, causing its value to typically be larger than Android's. This is an expected platform behavior difference, not an SDK implementation issue.