> ## Documentation Index
> Fetch the complete documentation index at: https://test-8ad8522e-feat-ai-sre.mintlify.site/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                                          | `connected` / `not_connected` / `maybe` (`maybe` is the schema's unknown value, used when the permission is missing or the API is unavailable)           |
| `connectivity.interfaces`                       | SDK network context                                          | Active network interfaces: `wifi`, `cellular`, `ethernet`, or `other`; an empty array when unknown                                                       |
| `usr.id` / `usr.name` / `usr.email`             | `setUserInfo()`                                              | Identified user information; the server does not accept other user fields                                                                                |
| `usr.anonymous_id`                              | Generated and persisted by the SDK                           | Anonymous device identifier attached to every event, used to correlate sessions before the user signs in; never generated or written under `NOT_GRANTED` |
| `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 wire an axios instance up with `trackAxios()` from `@flashcatcloud/axios`
* You wire another network stack up with `FlashcatTrace.startTracedResource()`

All four require `setTrackNetworkRequests(true)`. You can also record resources
manually with `GlobalRumMonitor.get().startResource()` and `stopResource()`,
which the toggle does not affect.

```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, unhandled Promise rejections, 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     |

RUM automatically listens to `errorManager.on('error')` and `errorManager.on('unhandledRejection')`. Unhandled Promise rejections are reported as ordinary, non-crashing errors and never trigger exit or recovery policies.

Error events include:

| Field                 | Description                                                                                                                                                                                                                                  |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `error.message`       | Error message                                                                                                                                                                                                                                |
| `error.source`        | Error source                                                                                                                                                                                                                                 |
| `error.stack`         | Error stack, when present. Frames only: the `Error name:` / `Error message:` / `Stacktrace:` label lines and the sourcemap banner in the errorManager callback text are stripped, since they are a callback format rather than stack content |
| `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`; unhandled Promise rejections write `promise`                                                                                                                                                                  |
| `crash.recovered`     | Present and `true` on crashes soft-landed through `REPORT_AND_RECOVER` and replayed on a later launch                                                                                                                                        |
| `crash.crashed_at_ms` | Written only when the crash cannot be attributed back to its original session and lands in the current one instead; preserves the real fault time in milliseconds                                                                            |
| `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 collects faults through live and post-mortem paths:

* Uncaught main-thread ArkTS exceptions enter the live JS crash-policy path. `REPORT_THEN_EXIT` and `REPORT_AND_RECOVER` synchronously persist an SDK pending crash incident before the process exits or restarts
* On the next launch, the Crash module replays its own pending incident into RUM, marks it as consumed, and deletes the persisted file
* HarmonyOS `hiAppEvent` replays `APP_CRASH` and `APP_FREEZE` on a later launch to capture ArkTS crashes, native C/C++ crashes, and hangs

One ArkTS crash can reach `onUnhandledException`, `onException`, and the later `hiAppEvent.APP_CRASH`. The SDK deduplicates the two live callbacks by fingerprint and uses a persisted consumed record to deduplicate the system replay, ensuring that one policy-managed crash produces exactly one crash error event in the RUM pipeline.

Unhandled Promise rejections are collected separately as ordinary, non-crashing RUM errors with `error.source_type: promise`. They do not terminate the process or enter the crash-policy path.

### Crash attribution

Crashes and hangs are attributed to **the session and view the application was actually in when the fault happened**, not to the launch that replays them. The two kinds of fault are attributed from different sources:

* Faults the SDK can observe in-process (uncaught main-thread ArkTS exceptions) record their RUM session and view into the pending incident before the process exits, and the next launch replays them against that record
* Faults the SDK cannot observe in-process (native signal crashes, hangs) kill the process with no chance to record anything. Starting in `0.3.2`, the SDK snapshots every view event it writes to local storage, then reads that snapshot on the next launch (deleting it immediately after the read) to recover the session and view the crash belongs to. On `0.3.1` and earlier these faults landed in the live post-restart session at replay time, which put the crash in a session the user never crashed in and left the session that actually died reading crash-free

When replaying such a fault, the SDK writes two documents: an `is_crash` error stamped with the real fault time, and an updated view document (`document_version` incremented, `is_active` set to `false`, `crash` and `error` counts each incremented by one). The pending incident is deleted only after both are persisted; if only one write succeeds the incident is retained and retried on the next launch, so the session never settles as crash-free.

The SDK falls back to reporting into the **current session** at the current time — preserving the real fault time in the `crash.crashed_at_ms` attribute — in these cases:

* The view behind the snapshot started more than 4 hours ago. That is the maximum session lifetime, so the session has already closed on the backend and its document must not be rewritten
* The fault happened more than 23 hours ago. The intake silently discards events older than 24 hours, so a backdated crash would be marked delivered yet actually lost
* The crash happened before the first session was established, or no view snapshot is available locally

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`                                                                                                                |
| Content-Encoding        | `deflate` (since 0.3.0 the request body is zlib-compressed by default; the SDK falls back to an uncompressed upload if compression fails) |
| Authentication          | `DD-API-KEY: <clientToken>` request header                                                                                                |
| User-Agent              | `flashcat-sdk-harmony/0.3.2`                                                                                                              |
| Query parameters        | `ddsource=harmony`; `ddtags` includes `sdk_version:0.3.2` 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
