Skip to content

RUM Configuration

This document covers the initialization configuration and manual collection capabilities for HarmonyOS RUM.

Initialization Configuration

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);
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
setEnableTrackAppANR boolean No Whether to enable ANR monitoring, default false
setEnableTrackAppCrash boolean No Whether to enable APP crash monitoring, default false. For Native Crash, dependency on @guancecloud/ft_native is required
setEnableTraceWebView boolean No Whether to enable WebView data collection, default false. For complete integration, please refer to WebView Data Monitoring
setRumCacheLimitCount number No RUM data cache limit count, default 100000, minimum 10000

View Manual Collection

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.)
  • Navigation component switching
import { FTRUMGlobalManager } from '@guancecloud/ft_sdk/src/main/ets/components/rum/FTRUMGlobalManager';

// 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 startView and stopView during page transitions, no manual calls are needed
  • For scenarios like conditional rendering, manual calls to startView and stopView are still possible
  • Page names are automatically extracted from route paths or Navigation component names

Action Manual Collection

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';

// 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 (includes duration calculation mechanism)
FTRUMGlobalManager.getInstance().startAction('buy_button_click', 'click');
FTRUMGlobalManager.getInstance().stopAction();

Automatic Tracing:

After enabling enableTraceUserAction in the RUM configuration, the SDK automatically traces click events on UI components. Adding customProperty to a Button component can capture the button text:

Button('Buy Now')
  .id('buy-btn')
  .customProperty('buy-btn', 'Buy Now')
  .onClick(() => {
    // Click events are automatically traced
  })

Resource Manual Collection

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.NetworkKit HttpInterceptorChain, supported since 0.1.14-alpha03 and requires 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 Automatic Tracing

After enabling enableTraceUserResource(true), the SDK automatically traces requests sent via RCP, Axios compatibility mode, or @kit.NetworkKit HTTP interceptors.

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 Headers
  • RCPResourceInterceptor: Automatically collects Resource data and performance metrics
  • createFTRCPInterceptors(): Returns a default list of RCP interceptors, facilitating merging with custom SessionConfiguration
  • createFTRCPTrackConfig(): Quickly generates a SessionConfiguration with default interceptors and TracingConfiguration

Recommended Integration Method: Using the default SessionConfiguration factory function

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 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:

import { createFTRCPTrackConfig } from '@guancecloud/ft_sdk/Index';

Manual Assembly of Interceptors

If you need full control over the Session configuration, you can also directly use the interceptors provided by the 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 Explanation:

  • collectTimeInfo: true: Recommended to enable. The SDK relies on response.timeInfo to calculate performance metrics like DNS, TCP, SSL, TTFB, download time, etc.
  • incomingHeader / outgoingHeader: Optional, enabled by default
  • incomingData / outgoingData: Disabled by default to reduce overhead

HTTP Interceptor Integration

If the business uses @kit.NetworkKit's http.createHttp() to send requests, automatic Trace Header injection and Resource collection can be achieved through 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_sdk in oh-package.json5
  • ft_sdk_ext.har, and declared as @guancecloud/ft_sdk_ext in oh-package.json5
  • If installing ft_sdk_ext.har via local HAR, you also need to add overrides["@guancecloud/ft_sdk"] = "file:./libs/ft_sdk.har" in the project root's oh-package.json5 to rewrite its internal dependency to the local HAR

  • HttpInitialRequestInterceptor: Injects Trace Headers at the request start stage and starts the Resource

  • HttpFinalResponseInterceptor: Completes Resource data and ends collection at the response end stage
  • createFTHttpInterceptorChain(): Creates a reusable http.HttpInterceptorChain
  • applyFTHttpTrack(): Directly attaches the default interceptor chain to a single http.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/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();
}

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/src/main/ets/components/network/FTHttpAutoTrackExt';

const request = http.createHttp();
const interceptorChain = createFTHttpInterceptorChain({
  interceptors: [
    new CustomAfterInterceptor() // Append 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 an 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);

Notes:

  • HTTP interceptors rely on the interceptor capability provided by @kit.NetworkKit in API 22+. For versions below API 22, please use RCP or Axios compatibility mode instead.
  • HttpRequestContext currently cannot reliably obtain the real request method, so the method in Resource will be recorded as UNKNOWN.
  • The interceptor callbacks of @kit.NetworkKit do not currently expose detailed timing information at the RCP timeInfo level, so currently only resourceLoad will be supplemented.

Axios Integration

If the business uses @ohos/axios, automatic tracing can be integrated as follows:

  • @guancecloud/ft_sdk: Compatibility mode based on Axios request/response interceptors
  • @guancecloud/ft_sdk_ext: Enhanced mode based on interceptorChain provided since 0.1.14-alpha03

@ohos/axios version 2.2.4 and above

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);

This integration method is based on Axios's request/response interceptors and can coexist with business's own 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;
});

Execution Order Explanation:

  • In @ohos/axios compat mode, request interceptors behave as: last registered, first executed
  • This means multiple request interceptors can coexist, but the registration order affects whether FT sees the request headers "before modification" or "after modification"
  • If you want FT to collect the final request headers after business supplements fields like authentication and signature, the recommended order is: First applyFTAxiosTrack(client), then register the business request interceptor
  • With the above order, the business request interceptor executes first, and FT executes subsequently, reading the final headers
  • If you want to adjust the order, simply adjust the registration order; for example, if you register the business first and then call applyFTAxiosTrack(client), FT will execute first, and the business interceptor will execute later

@ohos/axios version 2.2.8 and above

For @ohos/axios version 2.2.8 and above, it is recommended to prioritize integrating FT automatic tracing via @guancecloud/ft_sdk_ext's interceptorChain:

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()
});

If multiple interceptors need to coexist, manual adjustment of execution order is required, or integration with business custom interceptors needs to be unified, you can refer to the content in HTTP Interceptor Integration and combine HttpInitialRequestInterceptor and HttpFinalResponseInterceptor as needed.

If passing per request, you can also write it like this:

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()
});

Notes:

  • It is recommended to uniformly inject the interceptorChain when creating the Axios instance to avoid missing single requests.
  • The interceptorChain mode depends on @guancecloud/ft_sdk_ext (the local HAR file name is still ft_sdk_ext.har) and requires HarmonyOS API 22+.
  • To automatically inject Trace Headers, besides creating the interceptor chain, you also need to enable setEnableAutoTrace(true) in the Trace configuration.
  • To automatically collect Resource, you still need to enable setEnableTraceUserResource(true) in the RUM configuration.
  • If the caller already has custom HTTP/Axios interceptors, it is recommended to directly use HttpInitialRequestInterceptor and HttpFinalResponseInterceptor to manually assemble the order, avoiding rewriting url, method, or headers again after FT automatic tracing.
  • The SDK only provides interceptors and default configuration factory functions. The creation and lifecycle management of the RCP Session are handled by the business itself.
  • If the business directly uses rcp.createSession() to create a Session, it needs to manually add the interceptors provided by the SDK; otherwise, requests will not be automatically traced.
  • If the business directly uses http.createHttp() or @ohos/axios, it needs to explicitly mount applyFTHttpTrack(), applyFTAxiosTrack(), or createFTHttpInterceptorChain().

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.