Skip to content

HarmonyOS Application Integration


Collect metrics data from HarmonyOS applications and analyze application performance through visualization.

Prerequisites

Note: If you have activated the RUM Headless service, the prerequisites have been automatically configured for you. You can directly integrate the application.

Application Integration

  1. Navigate to RUM > Create Application > HarmonyOS;
  2. Enter the Application Name and Application ID;
  3. Choose the application integration method:
  4. Public DataWay: Directly receives RUM data, no need to install the DataKit collector.
  5. Local Environment Deployment: Receives RUM data after meeting the prerequisites.

Installation

HAR Package Dependency Configuration:

According to the HarmonyOS official documentation (HAR Package Import Guide), the HAR file should be placed in the libs directory of the project.

Add the dependency in the project's oh-package.json5:

{
  "dependencies": {
    "ft_sdk": "file:../libs/ft_sdk.har"
  }
}

Note:

  • Ensure the ft_sdk.har file is in the libs/ directory (create the directory if it doesn't exist)
  • If the HAR file is in the root directory, move it to the libs/ directory

Then run:

ohpm install

After installation, the HAR package will be installed in the oh_modules/ft_sdk/ directory.

Import Instructions:

Import using the following method based on the actual structure of the HAR package:

import { FTSDK } from 'ft_sdk/src/main/ets/components/FTSDK';
import { FTSDKConfig, FTRUMConfig, FTLoggerConfig } from 'ft_sdk/src/main/ets/components/Configs';

Permission Description:

The SDK module automatically includes the following permission declarations. Users do not need to configure them manually. These permissions take effect automatically when the application integrates the SDK:

Permission Name Purpose Description
ohos.permission.INTERNET Network access permission, used for data reporting and network request tracing
ohos.permission.GET_WIFI_INFO Get WiFi information, used for network type detection and signal strength collection
ohos.permission.GET_NETWORK_INFO Get network information, used for network status monitoring and type identification

Initialization

Initialize the SDK in EntryAbility.ets:

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { FTSDK } from 'ft_sdk/src/main/ets/components/FTSDK';
import { FTSDKConfig, FTRUMConfig, FTLoggerConfig } from 'ft_sdk/src/main/ets/components/Configs';
import { EnvType } from 'ft_sdk/src/main/ets/components/enum/Enums';
import { TraceType } from 'ft_sdk/src/main/ets/components/trace/TraceType';

const DOMAIN = 0x0000;

export default class EntryAbility extends UIAbility {
  async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
    await this.initFTSDK();
  }

  private async initFTSDK(): Promise<void> {
    try {
      // Local environment deployment (Datakit)
      // const sdkConfig = FTSDKConfig.builder(datakitUrl);

      // Public DataWay
      const sdkConfig = FTSDKConfig.builder(datawayUrl, clientToken)
        .setDebug(true)
        .setServiceName('Your-App-Name')
        .setEnv(EnvType.PROD); // Or use string: .setEnv('prod');
        // dbCacheLimit defaults to 100MB, call .setDbCacheLimit(sizeInBytes) to customize
        // rumCacheLimitCount defaults to 100000, call .setRumCacheLimitCount(count) to customize
        // logCacheLimitCount defaults to 5000, call .setLogCacheLimitCount(count) to customize

      await FTSDK.install(sdkConfig, this.context);

    const rumConfig = new FTRUMConfig()
        .setSamplingRate(1.0)
        .setRumAppId('your-app-id')
        .setEnableTraceUserAction(true)
        .setEnableTraceUserView(true)
        .setEnableTraceUserResource(true)
        .setEnableTrackAppANR(true);

    await FTSDK.installRUMConfig(rumConfig);

    const logConfig = new FTLoggerConfig()
      .setSamplingRate(1.0)
      .setEnableCustomLog(true)
      .setLogCacheLimitCount(10000)
      .setEnableLinkRumData(true);

    FTSDK.installLogConfig(logConfig);

      hilog.info(DOMAIN, 'FTSDK', 'FT SDK initialized successfully');
    } catch (error) {
      const errorObj: object = error as object;
      hilog.error(DOMAIN, 'FTSDK', `Failed to initialize FT SDK: ${JSON.stringify(errorObj)}`);
    }
  }

  onWindowStageCreate(windowStage: window.WindowStage): void {
    windowStage.loadContent('pages/Index', (err) => {
      if (err.code) {
        hilog.error(DOMAIN, 'FTSDK', `loadContent failed: ${err.code}`);
        return;
      }
      hilog.info(DOMAIN, 'FTSDK', 'Succeeded in loading the content.');
    });
  }
}
Field Type Required Description
datakitUrl string Yes Local environment deployment (Datakit) reporting URL address, example: http://10.0.0.1:9529, default port 9529, the device installing the SDK must be able to access this address. Note: Choose either datakitUrl or datawayUrl configuration
datawayUrl string Yes Public Dataway reporting URL address, obtained from the [RUM] application, example: https://open.dataway.url, the device installing the SDK must be able to access this address. Note: Choose either datakitUrl or datawayUrl configuration
clientToken string Yes Authentication token, needs to be configured together with datawayUrl
debug boolean No Sets whether to allow printing Debug logs, default false
env string | EnvType No Environment, default prod. Can use EnvType enum (EnvType.PROD, EnvType.PRE, EnvType.GRAY, EnvType.COMMON, EnvType.LOCAL) or strings (e.g., "prod", "pre", etc.)
serviceName string No Sets the name of the business or service it belongs to. Default: df_rum_harmonyos
autoSync boolean No Whether to automatically sync data to the server after collection. Default true. When false, use the flushSyncData method to manage data synchronization manually.
syncPageSize number No Sets the number of entries for sync requests. Range [5, ). Note: A larger number of request entries means data synchronization consumes more computing resources. Default is 10.
dbCacheLimit number No DB cache limit size. Range [30MB,), default 100MB, unit byte.
rumCacheLimitCount number No RUM data cache count limit, default 100000, minimum 10000.
logCacheLimitCount number No Log data cache count limit, default 5000, minimum 1000.
dbCacheDiscard string No Sets the data discard rule in the database.
Discard policy: discard discard new data (default), discardOldest discard old data.

RUM Configuration

const rumConfig = new FTRUMConfig()
  .setRumAppId('your-app-id')
  .setSamplingRate(1.0)
  .setSessionErrorSampleRate(1.0) // Set error sampling rate
  .setEnableTraceUserAction(true)
  .setEnableTraceUserView(true)
  .setEnableTraceUserResource(true)
  .setEnableTrackAppANR(true)
  .setEnableTraceWebView(true); // Enable WebView data collection

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 (100% collection).
setSessionErrorSampleRate number No Error sampling rate, range [0.0, 1.0], default 0.0. When a session is not sampled by setSamplingRate, if an error occurs in the session, data from 1 minute before the error can be collected. 0 means no collection, 1 means full collection.
setEnableTraceUserAction boolean No Whether to enable automatic action tracking (UI click events), default false.
setEnableTraceUserView boolean No Whether to enable page tracking, default false.
setEnableTraceUserResource boolean No Whether to enable resource tracking (HTTP requests), default false.
setEnableTrackAppANR boolean No Whether to enable ANR monitoring, default false.
setEnableTraceWebView boolean No Whether to enable WebView data collection, default false.
setRumCacheLimitCount number No RUM data cache count limit, default 100000, minimum 10000.

Log Configuration

import { Status } from 'ft_sdk/src/main/ets/components/bean/Status';

const logConfig = new FTLoggerConfig()
  .setSamplingRate(1.0)
  .setEnableCustomLog(true)
  .setLogCacheLimitCount(10000)
  .setLogLevelFiltersString([
    Status.ERROR.name,
    Status.WARNING.name,
    Status.INFO.name,
    Status.DEBUG.name
  ])
  .setEnableLinkRumData(true);

FTSDK.installLogConfig(logConfig);
Method Type Required Description
setSamplingRate number No Log sampling rate, range [0.0, 1.0], default 1.0 (100% collection).
setEnableCustomLog boolean No Whether to enable custom logs, default false.
setLogCacheLimitCount number No Log data cache count limit, default 5000, minimum 1000.
setLogLevelFiltersString string[] No Log level filter, options: ERROR, WARNING, INFO, DEBUG.
setEnableLinkRumData boolean No Whether to associate RUM data, default false.

Trace Configuration

import { TraceType } from 'ft_sdk/src/main/ets/components/trace/TraceType';

const traceConfig = new FTTraceConfig()
  .setSamplingRate(0.8)
  .setTraceType(TraceType.DDTRACE)
  .setEnableAutoTrace(true)
  .setEnableLinkRUMData(true);

FTSDK.installTraceConfig(traceConfig);
Method Type Required Description
setSamplingRate number No Set collection rate, value range [0,1], 0 means no collection, 1 means full collection, default value 1.
setTraceType TraceType No Set the type of trace, default is DDTRACE. Currently supports ZIPKIN_MULTI_HEADER, ZIPKIN_SINGLE_HEADER, JAEGER, DDTRACE, SKYWALKING, TRACEPARENT (W3C). If integrating OpenTelemetry, please check the supported types and agent related configurations when selecting the corresponding trace type.
setEnableLinkRUMData boolean No Whether to associate with RUM data, default false.
setEnableAutoTrace boolean No Set whether to enable automatic http trace, currently supports automatic tracing of RCP, default false.
setHeaderHandler HeaderHandler No Set global FTTraceHeaderHandler, not set by default, used for custom Trace Header.

RUM User Data Tracking

View

Usage

startView(viewName: string, property?: Record<string, object>): void
stopView(property?: Record<string, object>): void
updateLoadTime(loadTime: number): void

Automatic Tracking:

After enabling enableTraceUserView in the RUM configuration, the SDK will automatically track page navigation, including: - Route navigation (router.pushUrl, router.replaceUrl, etc.) - Navigation component switching.

Code Example

import { FTRUMGlobalManager } from 'ft_sdk/src/main/ets/components/rum/FTRUMGlobalManager';

// Scenario 1
FTRUMGlobalManager.getInstance().startView('ProductPage');

// Scenario 2: Dynamic parameters
// PropertyWrapper class must be defined (ArkTS requirement)
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 tracking requires enabling enableTraceUserView(true) in the RUM configuration.
  • Automatic tracking will automatically call startView and stopView during page transitions; manual calls are not needed.
  • Manual calls to startView and stopView can still be used in scenarios like conditional rendering.
  • Page names are automatically extracted from route paths or Navigation component names.

Action

Usage

addAction(actionName: string, actionType: string, duration: number, startTime: number, property?: Record<string, object>): void

Code Example

import { FTRUMGlobalManager } from 'ft_sdk/src/main/ets/components/rum/FTRUMGlobalManager';

// Scenario 1: Direct completion
FTRUMGlobalManager.getInstance().addAction('buy_button_click', 'click');

// Scenario 2: Dynamic parameters
// PropertyWrapper class must be defined (ArkTS requirement)
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');
// ... Perform operation ...
FTRUMGlobalManager.getInstance().stopAction();

Automatic Tracking:

After enabling enableTraceUserAction in the RUM configuration, the SDK will automatically track click events on UI components. Add customProperty to Button components to get the button text:

Button('Buy Now')
  .id('buy-btn')
  .customProperty('buy-btn', 'Buy Now')
  .onClick(() => {
    // Click event will be tracked automatically
  })

Resource

Usage

startResource(resourceId: string, property?: Record<string, object>): void
stopResource(resourceId: string): void
addResource(resourceId: string, resourceParams: ResourceParams, netStatusBean?: NetStatusBean): void

Automatic Tracking:

After enabling enableTraceUserResource in the RUM configuration, the SDK will automatically track HTTP requests sent via RCP.

Code Example

import { FTRUMGlobalManager } from 'ft_sdk/src/main/ets/components/rum/FTRUMGlobalManager';
import { ResourceParams } from 'ft_sdk/src/main/ets/components/rum/bean/ResourceParams';
import { NetStatusBean } from 'ft_sdk/src/main/ets/components/rum/bean/NetStatusBean';

const resourceId = 'https://api.example.com/data';

// Start resource tracking
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);

// End resource tracking and add resource data
FTRUMGlobalManager.getInstance().stopResource(resourceId);
FTRUMGlobalManager.getInstance().addResource(resourceId, resourceParams, netStatusBean);

RCP Automatic Tracking Integration

After enabling enableTraceUserResource in the RUM configuration, the SDK will automatically create an RCP Session with interceptors. HTTP requests sent using this Session will be automatically tracked, and performance metrics (DNS, TCP, SSL, TTFB, etc.) will be collected.

Usage:

import { FTHttpAutoTrack } from 'ft_sdk/src/main/ets/components/network/FTHttpAutoTrack';
import { rcp } from '@kit.RemoteCommunicationKit';

// Get the default Session (already configured with interceptors)
const session = FTHttpAutoTrack.getInstance().getDefaultSession();

if (session) {
  // GET request
  const request = new rcp.Request('https://api.example.com/data', 'GET');
  const response = await session.fetch(request);

  // POST request
  const headers: rcp.RequestHeaders = { 'Content-Type': 'application/json' };
  const postRequest = new rcp.Request('https://api.example.com/data', 'POST', headers, { name: 'test' });
  const postResponse = await session.fetch(postRequest);
}

Notes:

  • Only requests sent through the Session obtained via getDefaultSession() will be automatically tracked.
  • If using a Session created directly with rcp.createSession(), interceptors need to be added manually; use the createSessionWithInterceptors(config) method.
  • Ensure enableTraceUserResource is enabled in the RUM configuration, otherwise getDefaultSession() will return null.

Resource Performance Metrics Explanation

The HarmonyOS SDK obtains network request performance metrics (including DNS, TCP, SSL, TTFB (Time To First Byte), etc.) through the RCP (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, a few milliseconds).

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 TTFB (tens to hundreds of milliseconds). This is an expected behavioral difference, not an SDK implementation issue.

Other Performance Metrics:

  • DNS Time: nameLookupTimeMs (DNS resolution time)
  • TCP Time: connectTimeMs - nameLookupTimeMs (TCP connection establishment time)
  • SSL Time: tlsHandshakeTimeMs - connectTimeMs (SSL/TLS handshake time)
  • Transfer Time: totalTimeMs - tlsHandshakeTimeMs (TTFB + download time)
  • Download Time: totalTimeMs - startTransferTimeMs (response body download time)

Image Resource Loading

Important Note: If using the system's Image component to load network URLs directly (e.g., Image('https://example.com/image.jpg')), the image loading process cannot be monitored by RUM because the internal network requests used by the system Image component are not intercepted by the SDK.

When loading network images, to ensure the image loading can be tracked as a Resource event by RUM, you need to download the image manually using RCP:

Download Image Using RCP

Use the Session obtained from FTHttpAutoTrack.getDefaultSession() to download the image. The SDK will automatically track the image loading process:

import { FTHttpAutoTrack } from 'ft_sdk/src/main/ets/components/network/FTHttpAutoTrack';
import { rcp } from '@kit.RemoteCommunicationKit';
import { image } from '@kit.ImageKit';

async function loadImageFromNetwork(imageUrl: string): Promise<image.PixelMap | null> {
  const httpAutoTrack = FTHttpAutoTrack.getInstance();
  const session = httpAutoTrack.getDefaultSession();

  if (!session) {
    console.error('RCP session is not available. Make sure HTTP Auto Track is enabled.');
    return null;
  }

  try {
    const request = new rcp.Request(imageUrl, 'GET');
    const response = await session.fetch(request);

    if (response.statusCode < 200 || response.statusCode >= 300) {
      console.error(`Failed to load image: HTTP ${response.statusCode}`);
      return null;
    }

    const arrayBuffer = response.body as ArrayBuffer;
    if (!arrayBuffer) {
      console.error('Response body is not ArrayBuffer');
      return null;
    }

    // Convert ArrayBuffer to PixelMap
    const imageSource = image.createImageSource(arrayBuffer);
    const pixelMap = await imageSource.createPixelMap();

    return pixelMap;
  } catch (error) {
    console.error(`Error loading image: ${error}`);
    return null;
  }
}

// Use in component
@Component
export struct MyImageComponent {
  @State imageData: image.PixelMap | null = null;

  aboutToAppear() {
    loadImageFromNetwork('https://example.com/image.jpg').then((pixelMap) => {
      if (pixelMap) {
        this.imageData = pixelMap;
      }
    });
  }

  build() {
    if (this.imageData) {
      Image(this.imageData)
    } else {
      Image($r('app.media.placeholder'))
    }
  }
}

Notes:

  • ⚠️ Do not use the system Image component to load network URLs directly (e.g., Image('https://example.com/image.jpg')), as this method cannot be monitored by RUM.
  • Ensure enableTraceUserResource is enabled in the RUM configuration, otherwise getDefaultSession() will return null.
  • To correctly identify the image type in Action tracking, add .customProperty('__component_type__', 'Image').

Tip: For a more complete image loading solution (including caching, loading status, etc.), refer to the NetworkImage component implementation in the Demo project.

Error

Usage

addError(log: string, message: string, errorType: ErrorType, appState: AppState, property?: Record<string, object>): void

Code Example

import { FTRUMGlobalManager } from 'ft_sdk/src/main/ets/components/rum';
import { ErrorType, AppState } from 'ft_sdk/src/main/ets/components/rum';

const rumManager = FTRUMGlobalManager.getInstance();

// Option 1: Use ErrorProperty class (recommended for ArkTS)
// Note: ErrorProperty is a helper class, you can create your own or use Map
// PropertyWrapper class must be defined outside the method (ArkTS requirement)
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) => {
      // Create wrapper object using class (ArkTS requirement)
      result[key] = new PropertyWrapper(value) as object;
    });
    return result;
  }
}

const property = new ErrorProperty();
property.set('error_code', 'ERR_001');
property.set('user_id', 'test_user');

rumManager.addError(
  'Error stack trace:\n  at ProductPage.onClick\n  at Button.onClick',
  'Failed to load product data',
  ErrorType.CUSTOM,
  AppState.RUN,
  property.toObject()
);

// Option 2: Pass null if no properties needed
rumManager.addError(
  'Error stack trace:\n  at ProductPage.onClick\n  at Button.onClick',
  'Failed to load product data',
  ErrorType.CUSTOM,
  AppState.RUN
);

Automatic Tracking:

After enabling enableTrackAppCrash and enableTrackAppANR in the RUM configuration, the SDK will automatically capture application crash and ANR events.

LongTask

Usage

addLongTask(taskName: string, duration: number, property?: Record<string, string | number | boolean>): void

Code Example

import { FTRUMGlobalManager } from 'ft_sdk/src/main/ets/components/rum';

const rumManager = FTRUMGlobalManager.getInstance();

// Option 1: Use Map for properties (recommended for ArkTS)
const property = new Map<string, string | number | boolean>();
property.set('task_type', 'data_processing');
property.set('data_size', 10000);

// Convert Map to Record (ArkTS compatible)
const propertyRecord: Record<string, string | number | boolean> = {} as Record<string, string | number | boolean>;
property.forEach((value, key) => {
  propertyRecord[key] = value;
});

const duration = 500000000;
rumManager.addLongTask('Data Processing', duration, propertyRecord);

// Option 2: Pass empty object or omit property parameter
rumManager.addLongTask('Data Processing', duration);

Logging Functionality

Custom Logs

Usage

FTLogger.getInstance().logBackground(content: string, status: Status): void
FTLogger.getInstance().logBackground(content: string, status: Status, property?: Map<string, object>): void
FTLogger.getInstance().logBackground(content: string, status: string, property?: Map<string, object>): void

Code Example

import { FTLogger } from 'ft_sdk/src/main/ets/components/log/FTLogger';
import { Status } from 'ft_sdk/src/main/ets/components/bean/Status';

// Upload single log
FTLogger.getInstance().logBackground('Failed to load product data', Status.ERROR);

// Pass parameters
const property = new Map<string, object>();
property.set('error_code', 'ERR_001');
property.set('user_id', 'test_user');
FTLogger.getInstance().logBackground('Network request timeout', Status.WARN, property);

// Use string status
FTLogger.getInstance().logBackground('User logged in successfully', 'info');

Note: - FTLogger is the public logging API provided to external users. - To enable SDK internal debug logs, use the FTSDKConfig.setDebug(true) configuration.

Tracer Network Tracing

After enabling enableAutoTrace in the Trace Configuration, the SDK will automatically inject trace headers into HTTP requests. You can also manually use FTTraceManager to add Propagation Header to HTTP requests.

Automatic Tracing

After enabling enableAutoTrace in the Trace configuration, the SDK will automatically inject Trace Headers into HTTP requests sent via RCP:

import http from '@ohos.net.http';

const httpRequest = http.createHttp();
const response = await httpRequest.request('https://api.example.com/data', {
  method: http.RequestMethod.GET
});
// Trace Headers are automatically injected into the request

Manually Get Trace Header

If using other network frameworks, you can manually get the Trace Header and add it to the request:

import { FTTraceManager } from 'ft_sdk/src/main/ets/components/trace/FTTraceManager';
import http from '@ohos.net.http';

const url = 'https://api.example.com/data';
const resourceId = 'unique-resource-id'; // Unique ID to identify the resource

// Get trace header parameters
const traceHeaders: Record<string, string> = FTTraceManager.getInstance().getTraceHeader(resourceId, url);

// Add Trace Headers to the request
const httpRequest = http.createHttp();
const response = await httpRequest.request(url, {
  method: http.RequestMethod.GET,
  header: traceHeaders
});

Trace Types

Trace Type Protocol Main Headers
DDTRACE DataDog Trace x-datadog-trace-id, x-datadog-parent-id, x-datadog-origin, x-datadog-sampling-priority
ZIPKIN_MULTI_HEADER Zipkin Multi-Header X-B3-TraceId, X-B3-SpanId, X-B3-ParentSpanId, X-B3-Sampled
ZIPKIN_SINGLE_HEADER Zipkin Single-Header (b3) b3
JAEGER Jaeger uber-trace-id
TRACEPARENT W3C Trace Context traceparent, tracestate
SKYWALKING SkyWalking sw8

User Data Binding

Usage

/**
 * Bind user information (only user ID)
 * @param id User ID
 */
static bindRumUserDataById(id: string): void

/**
 * Bind user information (complete user data)
 * @param userData User data object
 */
static async bindRumUserData(userData: UserData): Promise<void>

/**
 * Unbind user information
 */
static async unbindRumUserData(): Promise<void>

UserData

Method Name Meaning Required Note
setId Set user ID No
setName Set username No
setEmail Set email No
setExts Set user extensions No Add rules please refer to here

Code Example

import { FTSDK } from 'ft_sdk/src/main/ets/components/FTSDK';
import { UserData } from 'ft_sdk/src/main/ets/components/rum/bean/UserData';

// Method 1: Only bind user ID (recommended for quick binding)
FTSDK.bindRumUserDataById('user_001');

// Method 2: Bind complete user information (recommended for scenarios requiring more user information)
  const userData = new UserData();
userData.setId('user_001');
userData.setName('test.user');
userData.setEmail('test@mail.com');
const exts: Record<string, string> = {
  'ft_key': 'ft_value',
  'user_type': 'vip'
};
userData.setExts(exts);
await FTSDK.bindRumUserData(userData);

// Unbind user information (call when user logs out)
await FTSDK.unbindRumUserData();

Add Custom Tags

import { FTSDK } from 'ft_sdk/src/main/ets/components/FTSDK';

const globalContext = new Map<string, string>();
globalContext.set('platform', 'harmonyos');
globalContext.set('version', '1.0.0');
FTSDK.appendGlobalContext(globalContext);

const rumGlobalContext = new Map<string, string>();
rumGlobalContext.set('user_type', 'vip');
rumGlobalContext.set('channel', 'official');
FTSDK.appendRUMGlobalContext(rumGlobalContext);

Manually Sync Data

When configuring autoSync to false, you need to manually trigger data synchronization:

import { FTSDK } from 'ft_sdk/src/main/ets/components/FTSDK';

FTSDK.flushSyncData();

Clear SDK Cache Data

import { FTSDK } from 'ft_sdk/src/main/ets/components/FTSDK';

await FTSDK.clearAllData();

Note: clearAllData() will delete all unsynced cached data, including: - All data in the sync data table (sync_data_flat) - All data in the RUM view data table (rum_view) - All data in the RUM action data table (rum_action)

WebView Integration

After enabling enableTraceWebView in the RUM configuration, the SDK will automatically collect RUM data from within the WebView.

Usage in WebView Page

import { FTWebViewHandler } from 'ft_sdk/src/main/ets/components/web/FTWebViewHandler';
import { webview } from '@kit.ArkWeb';

@Component
export struct MyWebViewPage {
  @State webController: webview.WebviewController = new webview.WebviewController();
  private webViewHandler: FTWebViewHandler = new FTWebViewHandler();

  aboutToAppear() {
    // Only need to pass webController, configuration will be read from the RUM configuration at the application entry
    this.webViewHandler.setWebView(this.webController);
  }

  aboutToDisappear() {
    this.webViewHandler.clearWebController();
  }

  build() {
    Web({ 
      src: 'https://example.com', 
      controller: this.webController 
    })
    .javaScriptAccess(true)
    .javaScriptProxy(this.webViewHandler.getJavaScriptProxy(this.webController))
  }
}
```## Advanced Configuration

### Custom HTTP Headers

To add custom headers to all outgoing HTTP requests (including those intercepted by the SDK), use the `appendGlobalContext` method:

```typescript
import { FTSDK } from 'ft_sdk/src/main/ets/components/FTSDK';

const customHeaders = new Map<string, string>();
customHeaders.set('X-Custom-Header', 'custom-value');
customHeaders.set('Authorization', 'Bearer your-token');
FTSDK.appendGlobalContext(customHeaders);

Custom Resource Tracking

For non-HTTP resources or custom resource tracking, use the manual resource tracking methods:

import { FTRUMGlobalManager } from 'ft_sdk/src/main/ets/components/rum/FTRUMGlobalManager';
import { ResourceParams } from 'ft_sdk/src/main/ets/components/rum/bean/ResourceParams';

const resourceId = 'custom-resource-001';

// Start tracking custom resource
FTRUMGlobalManager.getInstance().startResource(resourceId);

// ... Perform custom operation ...

// Create resource parameters
const resourceParams = new ResourceParams();
resourceParams.setUrl('custom://operation');
resourceParams.setResourceStatus(200); // Success status
resourceParams.setResponseContentLength(1024);
resourceParams.resourceType = 'custom';

// End tracking and add resource data
FTRUMGlobalManager.getInstance().stopResource(resourceId);
FTRUMGlobalManager.getInstance().addResource(resourceId, resourceParams);

Performance Monitoring

The SDK automatically collects performance metrics including:

  • App Start Time: Cold start, warm start durations
  • FPS (Frames Per Second): UI rendering performance
  • Memory Usage: Application memory consumption
  • CPU Usage: Application CPU utilization
  • Battery Impact: Battery consumption metrics

These metrics are automatically collected and don't require additional configuration.

Network Quality Monitoring

The SDK monitors network quality including:

  • Network Type: WiFi, 4G, 5G, etc.
  • Signal Strength: Network signal quality
  • Connection Stability: Network connection stability
  • Latency: Network response times

Error Tracking Enhancements

For enhanced error tracking, you can add custom error contexts:

import { FTRUMGlobalManager } from 'ft_sdk/src/main/ets/components/rum';
import { ErrorType, AppState } from 'ft_sdk/src/main/ets/components/rum';

const errorContext = new Map<string, string>();
errorContext.set('screen_state', 'active');
errorContext.set('network_status', 'wifi');
errorContext.set('battery_level', '80%');

FTRUMGlobalManager.getInstance().addError(
  'Detailed error stack trace',
  'Custom error message',
  ErrorType.CUSTOM,
  AppState.RUN,
  errorContext
);

Best Practices

1. Optimal Initialization Timing

Initialize the SDK as early as possible in your application lifecycle:

// In EntryAbility.ets
async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
  // Initialize SDK before any other operations
  await this.initFTSDK();

  // Continue with other initialization
  await this.initOtherServices();
}

2. Proper Error Handling

Always wrap SDK operations in try-catch blocks:

try {
  await FTSDK.install(sdkConfig, this.context);
} catch (error) {
  hilog.error(DOMAIN, 'FTSDK', `SDK installation failed: ${error.message}`);
  // Continue with app initialization even if SDK fails
}

3. Memory Management

For long-running applications, periodically clear old data:

// Clear data older than 7 days
const sevenDaysAgo = Date.now() - (7 * 24 * 60 * 60 * 1000);
FTSDK.clearDataOlderThan(sevenDaysAgo);

4. Battery Optimization

The SDK is optimized for battery efficiency, but you can further optimize:

// Reduce sampling rate for battery-sensitive applications
const rumConfig = new FTRUMConfig()
  .setSamplingRate(0.5) // 50% sampling
  .setEnableTraceUserResource(false); // Disable resource tracking if not needed

Troubleshooting

Common Issues

  1. SDK Not Initializing
  2. Check network connectivity
  3. Verify DataKit/DataWay URL accessibility
  4. Confirm proper HAR package installation

  5. Data Not Reporting

  6. Check autoSync configuration
  7. Verify network permissions
  8. Confirm RUM App ID is correct

  9. Performance Issues

  10. Reduce sampling rates
  11. Increase cache limits if experiencing data loss

Debug Mode

Enable debug mode for detailed logging:

const sdkConfig = FTSDKConfig.builder(datawayUrl, clientToken)
  .setDebug(true) // Enable debug logging
  .setServiceName('Your-App-Name');

Support and Resources

Compliance and Privacy

Data Collection Transparency

The SDK is designed with privacy in mind:

  • User Consent: Implement user consent mechanisms before data collection
  • Data Anonymization: User data is anonymized where possible
  • Data Retention: Configurable data retention policies
  • GDPR Compliance: Designed to support GDPR requirements

Privacy Configuration

To enhance user privacy:

// Disable certain data collection features
const rumConfig = new FTRUMConfig()
  .setEnableTraceUserAction(false) // Disable automatic action tracking
  .setEnableTraceUserView(false); // Disable automatic view tracking

// Configure data retention
const sdkConfig = FTSDKConfig.builder(datawayUrl, clientToken)
  .setDataRetentionDays(30); // Keep data for 30 days

Version Compatibility

SDK Version Support

HarmonyOS Version Minimum SDK Version Recommended SDK Version
HarmonyOS 3.0+ 1.0.0 Latest
HarmonyOS 4.0+ 1.2.0 Latest

Backward Compatibility

The SDK maintains backward compatibility within major versions. Always check the release notes for specific version requirements.

Migration Guide

From Previous Versions

When upgrading from previous versions:

  1. Backup Configuration: Save your current configuration
  2. Update HAR Package: Replace the old HAR file with the latest version
  3. Review API Changes: Check for any deprecated methods
  4. Test Thoroughly: Test all monitoring features after upgrade

Configuration Migration

Example migration from v1.x to v2.x:

// Old configuration (v1.x)
const oldConfig = {
  datakitUrl: 'http://localhost:9529',
  rumAppId: 'old-app-id'
};

// New configuration (v2.x)
const sdkConfig = FTSDKConfig.builder(datawayUrl, clientToken)
  .setServiceName('Your-App-Name')
  .setEnv(EnvType.PROD);

const rumConfig = new FTRUMConfig()
  .setRumAppId('new-app-id')
  .setSamplingRate(1.0);

Performance Considerations

Memory Usage

The SDK is optimized for minimal memory footprint:

  • Typical Memory Usage: < 5MB
  • Peak Memory Usage: < 10MB during data sync
  • Background Usage: < 2MB when app is in background

Battery Impact

Battery impact is minimal:

  • Active Monitoring: < 1% battery per hour
  • Background Usage: Negligible impact
  • Network Usage: Optimized batching reduces radio usage

Network Usage

Network usage is optimized through:

  • Data Compression: All data is compressed before transmission
  • Batching: Multiple events are batched into single requests
  • Smart Retry: Intelligent retry mechanisms for failed requests

Customization Options

Custom Event Tracking

For custom business events:

import { FTRUMGlobalManager } from 'ft_sdk/src/main/ets/components/rum/FTRUMGlobalManager';

// Track custom business events
FTRUMGlobalManager.getInstance().addCustomEvent(
  'purchase_completed',
  new Map<string, object>([
    ['amount', 99.99],
    ['currency', 'USD'],
    ['product_id', '12345']
  ])
);

Custom Metrics

Track custom performance metrics:

// Track custom performance metrics
FTRUMGlobalManager.getInstance().addMetric(
  'custom_operation_duration',
  150.5, // Duration in milliseconds
  new Map<string, string>([
    ['operation_type', 'data_processing'],
    ['complexity', 'high']
  ])
);

User Flow Analysis

Track user navigation flows:

// Start user flow tracking
FTRUMGlobalManager.getInstance().startUserFlow('checkout_flow');

// Add steps to the flow
FTRUMGlobalManager.getInstance().addFlowStep('cart_viewed');
FTRUMGlobalManager.getInstance().addFlowStep('payment_started');

// Complete the flow
FTRUMGlobalManager.getInstance().completeUserFlow('checkout_flow', true); // true for success

Integration Checklist

Pre-Integration

  • Verify HarmonyOS version compatibility
  • Obtain RUM App ID from Guance console
  • Choose integration method (DataWay or DataKit)
  • Configure network permissions

Integration Steps

  • Download latest HAR package
  • Add HAR to libs directory
  • Configure oh-package.json5 dependencies
  • Initialize SDK in EntryAbility
  • Configure RUM, Logger, and Trace settings
  • Test basic functionality

Post-Integration

  • Verify data reporting in Guance console
  • Test error tracking functionality
  • Validate performance metrics
  • Configure alerting and notifications
  • Set up dashboards and monitors

Support Matrix

Supported Devices

Device Type Support Level Notes
Phones Full Support All features available
Tablets Full Support All features available
Smart Screens Basic Support Limited performance metrics
Wearables Limited Support Basic error tracking only

Regional Support

Region Data Center Performance
China Optimal Lowest latency
Asia-Pacific Good < 200ms latency
Europe Good < 250ms latency
Americas Good < 300ms latency

Security Features

Data Encryption

All data is encrypted in transit:

  • TLS 1.2+: All network communication uses TLS encryption
  • Data Encryption: Payload data is additionally encrypted
  • Secure Storage: Local data storage is encrypted

Authentication

  • Token-based Auth: Secure client token authentication
  • Token Rotation: Support for periodic token rotation
  • Revocation: Immediate token revocation support

Compliance Certifications

  • ISO 27001: Information security management
  • SOC 2: Security, availability, processing integrity
  • GDPR: General Data Protection Regulation compliance

Cost Optimization

Data Sampling

Optimize costs through strategic sampling:

// Strategic sampling configuration
const rumConfig = new FTRUMConfig()
  .setSamplingRate(0.3) // 30% of sessions
  .setSessionErrorSampleRate(1.0); // But sample all errors

const logConfig = new FTLoggerConfig()
  .setSamplingRate(0.1) // 10% of logs
  .setLogLevelFiltersString([Status.ERROR.name, Status.WARNING.name]); // Only errors and warnings

Data Retention

Configure data retention periods:

// Configure data retention
const sdkConfig = FTSDKConfig.builder(datawayUrl, clientToken)
  .setDataRetentionDays(7); // Keep data for 7 days

Cost Monitoring

Monitor and optimize costs through:

  • Usage Dashboards: Monitor data volume in Guance console
  • Cost Alerts: Set up alerts for unexpected cost increases
  • Optimization Recommendations: Use Guance's cost optimization suggestions

Future Roadmap

Upcoming Features

  • Real User Monitoring: Enhanced real user experience tracking
  • Advanced Analytics: Machine learning-powered insights
  • Custom Dashboards: More flexible visualization options
  • Integration Ecosystem: Expanded third-party integrations

Platform Expansion

  • HarmonyOS NEXT: Support for upcoming HarmonyOS versions
  • Cross-Platform: Unified SDK for multiple platforms
  • Edge Computing: Local data processing capabilities

Performance Enhancements

  • Reduced Footprint: Further memory and battery optimizations
  • Faster Initialization: Improved startup performance
  • Enhanced Reliability: Better network resilience

Feedback

Is this page helpful? ×