> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flashduty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# HarmonyOS SDK data collection

> Learn which event types, fields, session rules, and upload behavior the HarmonyOS RUM SDK collects automatically and manually

The HarmonyOS SDK assembles RUM data as NDJSON batches and uploads them to Flashduty. The current version collects four RUM event types: view, action, resource, and error. Crashes and hangs enter the same pipeline as error events with `is_crash`.

## Default context

After initialization, the SDK attaches shared context to every event.

| Field                                           | Source                                                       | Description                                                               |
| ----------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------- |
| `source`                                        | Fixed value                                                  | Always `harmony`                                                          |
| `service`                                       | `ConfigurationBuilder.setService()` or application bundle id | Service name for filtering                                                |
| `version`                                       | HarmonyOS bundle information                                 | Application version                                                       |
| `application.id`                                | `RumConfigurationBuilder(applicationId)`                     | RUM application ID                                                        |
| `session.id`                                    | Generated by SDK                                             | User session ID                                                           |
| `os.name` / `os.version`                        | `@kit.BasicServicesKit.deviceInfo`                           | OS name and version                                                       |
| `device.brand` / `device.model` / `device.type` | `deviceInfo`                                                 | Device brand, model, and type                                             |
| `connectivity.status`                           | SDK network context                                          | Currently defaults to `unknown`                                           |
| `usr.id` / `usr.name` / `usr.email`             | `setUserInfo()`                                              | Identified user information; the server does not accept other user fields |
| `context.*`                                     | Global or per-event attributes                               | Custom business context                                                   |

<Note>
  `clientToken` is only used for report authentication and is never attached to RUM events.
</Note>

## Session rules

The SDK manages sampling and lifecycle at the session level.

| Rule               | Current behavior                                                                                            |
| ------------------ | ----------------------------------------------------------------------------------------------------------- |
| Session sampling   | The SDK performs one random sampling decision when a session is created; unsampled sessions write no events |
| Inactivity timeout | A session expires after 15 minutes without real events; keep-alive does not refresh inactivity              |
| Maximum duration   | A single session lasts up to 4 hours                                                                        |
| View keep-alive    | The active view refreshes `time_spent` every 30 seconds                                                     |
| Start condition    | `keepAlive` never creates a new session; only real view, action, error, or resource events do               |

## View events

A view represents a page or business screen. Generate views through automatic route tracking or manual APIs.

```ts theme={null}
import { GlobalRumMonitor } from '@flashcatcloud/rum';

const monitor = GlobalRumMonitor.get();

monitor.startView('product-detail', 'ProductDetail', {
  'view.url': 'pages/ProductDetail'
});

monitor.stopView('product-detail');
```

View events include:

| Field                  | Description                                                                   |
| ---------------------- | ----------------------------------------------------------------------------- |
| `view.id`              | Unique view ID generated by the SDK                                           |
| `view.name`            | View name                                                                     |
| `view.url`             | Uses the `view.url` attribute first, then falls back to the view key          |
| `view.time_spent`      | Duration from view start to the current update, in nanoseconds                |
| `view.is_active`       | Whether the view is still active                                              |
| `view.action.count`    | Number of actions under the view                                              |
| `view.error.count`     | Number of errors under the view                                               |
| `view.resource.count`  | Number of resources under the view                                            |
| `view.crash.count`     | Number of `is_crash` errors under the view, used to calculate crash-free rate |
| `_dd.document_version` | Update version for the same view                                              |

## Action events

An action represents user interaction. Record instantaneous actions with `addAction()`, or timed actions with `startAction()` and `stopAction()`.

```ts theme={null}
import {
  GlobalRumMonitor,
  RumActionType
} from '@flashcatcloud/rum';

const monitor = GlobalRumMonitor.get();

monitor.addAction(RumActionType.TAP, 'pay_button');

monitor.startAction(RumActionType.SCROLL, 'feed_scroll');
monitor.stopAction(RumActionType.SCROLL, 'feed_scroll');
```

Supported action types:

| Enum                   | Value    |
| ---------------------- | -------- |
| `RumActionType.TAP`    | `tap`    |
| `RumActionType.SCROLL` | `scroll` |
| `RumActionType.SWIPE`  | `swipe`  |
| `RumActionType.CLICK`  | `click`  |
| `RumActionType.BACK`   | `back`   |
| `RumActionType.CUSTOM` | `custom` |

Action events include `action.id`, `action.type`, `action.target.name`, and `action.loading_time`. Actions recorded through `FlashcatRum.trackTap()` use type `tap`.

## Resource events

A resource represents a network request. The SDK generates resources in these cases:

* You use an `rcp` session with `FlashcatTrace.interceptor()`
* You use `FlashcatHttp.request()` to wrap `@kit.NetworkKit` requests
* You manually call `GlobalRumMonitor.get().startResource()` and `stopResource()`

```ts theme={null}
import {
  GlobalRumMonitor,
  RumResourceKind,
  RumResourceMethod
} from '@flashcatcloud/rum';

const monitor = GlobalRumMonitor.get();

monitor.startResource('order-request', RumResourceMethod.GET, 'https://api.example.com/orders');
monitor.stopResource('order-request', 200, 2048, RumResourceKind.NATIVE);
```

Resource events include:

| Field                          | Description                                                                                                                    |
| ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| `resource.id`                  | Resource ID generated by the SDK                                                                                               |
| `resource.type`                | Resource type; automatic network collection classifies by response `Content-Type` and falls back to `native` when unrecognized |
| `resource.url`                 | Request URL                                                                                                                    |
| `resource.method`              | Request method                                                                                                                 |
| `resource.status_code`         | HTTP status code                                                                                                               |
| `resource.size`                | Response body size in bytes                                                                                                    |
| `resource.duration`            | Request duration in nanoseconds                                                                                                |
| `_dd.trace_id` / `_dd.span_id` | Written when the request received `traceparent`, used to correlate backend Trace                                               |

Automatic network collection maps resource types as follows:

| Response `Content-Type` | `resource.type` |
| ----------------------- | --------------- |
| `image/*`               | `image`         |
| `video/*` / `audio/*`   | `media`         |
| `font/*`                | `font`          |
| `text/css`              | `css`           |
| `text/javascript`       | `js`            |
| Other or missing        | `native`        |

If the request fails, the SDK generates an error event with `source: "network"` and includes method, status code, and URL in `error.resource`.

## Error events

Errors represent manually reported errors, unhandled ArkTS exceptions, network errors, crashes, or hangs.

```ts theme={null}
import {
  GlobalRumMonitor,
  RumErrorSource
} from '@flashcatcloud/rum';

GlobalRumMonitor.get().addError(
  'checkout failed',
  RumErrorSource.CUSTOM,
  'at checkout'
);
```

Supported error sources:

| Enum      | Value     | Description                       |
| --------- | --------- | --------------------------------- |
| `NETWORK` | `network` | Network request failure           |
| `SOURCE`  | `source`  | ArkTS / JS runtime error or crash |
| `CONSOLE` | `console` | Console-originated error          |
| `WEBVIEW` | `webview` | WebView-originated error          |
| `AGENT`   | `agent`   | Agent-originated error            |
| `CUSTOM`  | `custom`  | Business-defined manual error     |

Error events include:

| Field                 | Description                                           |
| --------------------- | ----------------------------------------------------- |
| `error.message`       | Error message                                         |
| `error.source`        | Error source                                          |
| `error.stack`         | Error stack, when present                             |
| `error.handling`      | `handled` or `unhandled`                              |
| `error.is_crash`      | `true` for crashes and hangs                          |
| `error.category`      | Crash module writes `Exception` or `App Hang`         |
| `error.source_type`   | Crash module writes `harmony`                         |
| `error.binary_images` | Dynamic library symbol information for native crashes |
| `build_id`            | Build-id used to match native symbols                 |

## Crashes and hangs

The Crash module listens to HarmonyOS `hiAppEvent` for `APP_CRASH` and `APP_FREEZE`. The system persists faults and replays them on the next launch, so enable the Crash module early in startup.

Crash events are reported through the RUM error pipeline:

* ArkTS / JS stacks are parsed as V8-style frames
* Native C/C++ stacks are parsed in `#NN pc <address> <lib.so>` form
* If you upload `sourceMaps.map`, `nameCache.json`, and unstripped `.so` files, the server resolves source files, function names, lines, columns, and native symbols

## Upload behavior

The SDK uploads events as NDJSON batches.

| Behavior                | Current implementation                                                                                             |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Upload URL              | `{site}/api/v2/rum`; the default site is `https://browser.flashcat.cloud`                                          |
| Request method          | `POST`                                                                                                             |
| Content-Type            | `text/plain;charset=UTF-8`                                                                                         |
| Authentication          | `DD-API-KEY: <clientToken>` request header                                                                         |
| User-Agent              | `flashcat-sdk-harmony/0.1.3`                                                                                       |
| Query parameters        | `ddsource=harmony`; `ddtags` includes `sdk_version:0.1.3` and appends `env`, `service`, and `version` when present |
| Default upload interval | 5 seconds                                                                                                          |
| Network timeout         | 30-second connect timeout and 30-second read timeout                                                               |
| Retry                   | Network errors, `401`, `403`, `408`, `429`, and `5xx` keep the batch and retry with exponential backoff            |
| Drop                    | Other `4xx` responses are treated as permanent errors and drop the current batch                                   |
| Force flush             | Error and crash events trigger faster flushing                                                                     |
| Background flush        | When the application backgrounds, the SDK refreshes the active view and triggers upload                            |

## Currently not collected

The current HarmonyOS SDK does not automatically collect:

* Session Replay
* Web Vitals or browser page performance metrics
* HarmonyOS page rendering performance metrics
* Automatic frustration events
* Network connectivity changes; `connectivity.status` currently remains `unknown`
