Skip to content

Commit 3898b25

Browse files
authored
Merge pull request #94 from flashcatcloud/doc-review/2026-06-23-harmony-sdk
docs(rum): add HarmonyOS SDK documentation
2 parents dff18f3 + a9404b8 commit 3898b25

9 files changed

Lines changed: 1814 additions & 0 deletions

File tree

‎docs.json‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,15 @@
396396
"zh/rum/sdk/ios/performance-impact"
397397
]
398398
},
399+
{
400+
"group": "HarmonyOS",
401+
"pages": [
402+
"zh/rum/sdk/harmony/sdk-integration",
403+
"zh/rum/sdk/harmony/advanced-config",
404+
"zh/rum/sdk/harmony/compatible",
405+
"zh/rum/sdk/harmony/data-collection"
406+
]
407+
},
399408
{
400409
"group": "微信小程序",
401410
"pages": [
@@ -1516,6 +1525,15 @@
15161525
"en/rum/sdk/ios/performance-impact"
15171526
]
15181527
},
1528+
{
1529+
"group": "HarmonyOS",
1530+
"pages": [
1531+
"en/rum/sdk/harmony/sdk-integration",
1532+
"en/rum/sdk/harmony/advanced-config",
1533+
"en/rum/sdk/harmony/compatible",
1534+
"en/rum/sdk/harmony/data-collection"
1535+
]
1536+
},
15191537
{
15201538
"group": "WeChat Mini Program",
15211539
"pages": [
Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
---
2+
title: "HarmonyOS SDK advanced configuration"
3+
description: "Configure HarmonyOS RUM SDK sampling, tracking consent, event mapping, Trace, crash reporting, and symbol upload"
4+
keywords: ["RUM", "HarmonyOS SDK", "advanced configuration", "Trace", "Crash", "Sourcemap"]
5+
---
6+
7+
This page describes core configuration, RUM configuration, privacy controls, Trace correlation, crash reporting, and symbol upload for the HarmonyOS SDK. All options come from the current ArkTS SDK public API.
8+
9+
## Core configuration
10+
11+
Create core configuration with `ConfigurationBuilder` and pass it to `Flashcat.initialize()`.
12+
13+
```ts
14+
import {
15+
ConfigurationBuilder,
16+
FlashcatSite
17+
} from '@flashcatcloud/core';
18+
19+
const config = new ConfigurationBuilder('<CLIENT_TOKEN>', 'production')
20+
.setService('shopping-app')
21+
.setVariant('default')
22+
.useSite(FlashcatSite.CN)
23+
.setBatchUploadFrequencyMs(5000)
24+
.build();
25+
```
26+
27+
| Method / parameter | Type | Default | Description |
28+
|--------------------|------|---------|-------------|
29+
| `new ConfigurationBuilder(clientToken, env)` | string, string | Required | `clientToken` authenticates client-side reporting; `env` is the environment name |
30+
| `setService(service)` | string | Application bundle id | Service name written to the RUM event `service` field |
31+
| `setVariant(variant)` | string | `""` | Build variant name |
32+
| `useSite(site)` | `FlashcatSite` | `FlashcatSite.CN` | Intake site; production uses `https://browser.flashcat.cloud` |
33+
| `setCustomEndpoint(endpoint)` | string | `""` | Overrides the intake host, usually for local proxying or private forwarding; the SDK still appends `/api/v2/rum` |
34+
| `setBatchUploadFrequencyMs(frequencyMs)` | number | `5000` | Foreground batch upload cadence in milliseconds |
35+
| `setVerbose(enabled)` | boolean | `false` | Emits SDK internal HiLog entries with the `Flashcat` tag |
36+
37+
<Note>
38+
`Flashcat.initialize()` initializes a given instance name only once. A duplicate call returns the existing instance and does not re-register feature modules.
39+
</Note>
40+
41+
## Tracking consent
42+
43+
Pass `TrackingConsent` during initialization. You can also update it at runtime with `Flashcat.setTrackingConsent()`.
44+
45+
```ts
46+
import { Flashcat, TrackingConsent } from '@flashcatcloud/core';
47+
48+
Flashcat.setTrackingConsent(TrackingConsent.PENDING);
49+
Flashcat.setTrackingConsent(TrackingConsent.GRANTED);
50+
```
51+
52+
| State | Behavior |
53+
|-------|----------|
54+
| `GRANTED` | Writes to the main upload directory and starts batch uploads |
55+
| `PENDING` | Writes events to a separate pending buffer; when consent changes to `GRANTED`, the SDK migrates and uploads them |
56+
| `NOT_GRANTED` | Drops new events, clears the pending buffer, and stops uploads |
57+
58+
<Warning>
59+
Trace headers also honor tracking consent. The SDK injects correlatable `traceparent` and `tracestate` headers only when consent is `GRANTED`.
60+
</Warning>
61+
62+
## RUM configuration
63+
64+
Create RUM configuration with `RumConfigurationBuilder` and pass it to `FlashcatRum.enable()`.
65+
66+
```ts
67+
import {
68+
FlashcatRum,
69+
RumConfigurationBuilder
70+
} from '@flashcatcloud/rum';
71+
72+
FlashcatRum.enable(
73+
new RumConfigurationBuilder('<APPLICATION_ID>')
74+
.setSessionSampleRate(50)
75+
.setTrackUserInteractions(true)
76+
.setTrackNavigation(true)
77+
.setTrackNetworkRequests(true)
78+
.build()
79+
);
80+
```
81+
82+
| Method / parameter | Type | Default | Description |
83+
|--------------------|------|---------|-------------|
84+
| `new RumConfigurationBuilder(applicationId)` | string | Required | RUM application ID written to `application.id` |
85+
| `setSessionSampleRate(rate)` | number | `100` | Session sample rate as a percentage; `100` collects all sessions, `0` collects no events |
86+
| `setTrackUserInteractions(enabled)` | boolean | `false` | Controls whether `FlashcatRum.trackTap()` records tap actions |
87+
| `setTrackNavigation(enabled)` | boolean | `false` | Controls whether `FlashcatRum.startViewTracking()` registers the ArkUI `routerPageUpdate` observer |
88+
| `setTrackNetworkRequests(enabled)` | boolean | `false` | Controls whether network lifecycle events published by Trace become RUM resources |
89+
| `setTrackFrustrations(enabled)` | boolean | `false` | Reserved toggle; the current version does not generate frustration events |
90+
| `setEventMapper(mapper)` | function | `null` | Modifies or drops view, action, error, and resource events before disk write |
91+
92+
### Event mapping and redaction
93+
94+
Use `setEventMapper()` to perform lightweight processing before events are reported. Return the modified event to keep it, or `null` to drop it.
95+
96+
```ts
97+
import { RumConfigurationBuilder } from '@flashcatcloud/rum';
98+
99+
const rumConfig = new RumConfigurationBuilder('<APPLICATION_ID>')
100+
.setEventMapper((event) => {
101+
if (event.type === 'resource') {
102+
const resource = event.resource as Record<string, Object>;
103+
const url = resource.url;
104+
if (typeof url === 'string') {
105+
resource.url = url.split('?')[0];
106+
}
107+
}
108+
109+
if (event.type === 'action') {
110+
const action = event.action as Record<string, Object>;
111+
const target = action.target as Record<string, Object>;
112+
if (String(target.name).includes('secret')) {
113+
return null;
114+
}
115+
}
116+
117+
return event;
118+
})
119+
.build();
120+
```
121+
122+
<Warning>
123+
The event mapper runs on the SDK write path. Keep it fast, synchronous, and non-throwing. The SDK catches mapper errors and preserves the original event, but expensive logic increases client overhead.
124+
</Warning>
125+
126+
## Global attributes and user information
127+
128+
Global attributes are merged into the `context` object on subsequent events.
129+
130+
```ts
131+
import {
132+
GlobalRumMonitor,
133+
RumErrorSource
134+
} from '@flashcatcloud/rum';
135+
136+
const monitor = GlobalRumMonitor.get();
137+
138+
monitor.addAttribute('tenant', 'acme');
139+
monitor.addError('checkout failed', RumErrorSource.CUSTOM);
140+
monitor.removeAttribute('tenant');
141+
```
142+
143+
Set user information through the core instance. `id`, `name`, and `email` are written to the `usr` object on subsequent events.
144+
145+
```ts
146+
import { Flashcat } from '@flashcatcloud/core';
147+
148+
Flashcat.getInstance().setUserInfo({
149+
id: 'user-1001',
150+
name: 'Alice',
151+
email: 'alice@example.com'
152+
});
153+
```
154+
155+
<Warning>
156+
`setUserInfo()` currently sets only `id`, `name`, and `email`. The server does not accept other user fields; use RUM global attributes or per-event attributes to write business dimensions to `context`.
157+
</Warning>
158+
159+
## Trace configuration
160+
161+
The Trace module generates W3C `traceparent` and `tracestate`, then correlates the generated trace id and span id to RUM resources through `_dd.trace_id` and `_dd.span_id`. `tracestate` carries the Datadog vendor entry `dd=s:{0|1};o:rum`.
162+
163+
```ts
164+
import {
165+
FlashcatTrace,
166+
TraceConfigurationBuilder
167+
} from '@flashcatcloud/trace';
168+
169+
FlashcatTrace.enable(
170+
new TraceConfigurationBuilder()
171+
.setSampleRate(100)
172+
.setFirstPartyHosts(['api.example.com'])
173+
.build()
174+
);
175+
```
176+
177+
| Method | Type | Default | Description |
178+
|--------|------|---------|-------------|
179+
| `setSampleRate(rate)` | number | `100` | Controls the sampled flag in `traceparent` and `tracestate` |
180+
| `setFirstPartyHosts(hosts)` | string[] | `[]` | Restricts `FlashcatHttp` Trace header injection to these first-party hosts and subdomains; an empty array means all hosts |
181+
182+
<Note>
183+
`setFirstPartyHosts()` is currently used only by the `FlashcatHttp` wrapper. The `rcp` interceptor itself is an explicit per-session opt-in, so requests made through a session with the interceptor receive Trace headers. If a request already has `traceparent`, the SDK does not overwrite the existing Trace context. Existing `tracestate` keeps other vendors and moves the updated `dd=` member to the front.
184+
</Note>
185+
186+
## Crash reporting configuration
187+
188+
The Crash module listens to HarmonyOS `hiAppEvent` for `APP_CRASH` and `APP_FREEZE`. The system replays fault events on the next launch, and the SDK reports them through the RUM error pipeline.
189+
190+
```ts
191+
import {
192+
FlashcatCrash,
193+
CrashConfigurationBuilder
194+
} from '@flashcatcloud/crash';
195+
196+
FlashcatCrash.enable(
197+
new CrashConfigurationBuilder()
198+
.setTrackCrashes(true)
199+
.setTrackAppHangs(true)
200+
.setSampleRate(100)
201+
.build()
202+
);
203+
```
204+
205+
| Method | Type | Default | Description |
206+
|--------|------|---------|-------------|
207+
| `setTrackCrashes(enabled)` | boolean | `true` | Captures ArkTS / JS and native C/C++ crashes |
208+
| `setTrackAppHangs(enabled)` | boolean | `true` | Captures `APP_FREEZE`, such as main-thread hangs or watchdog timeouts |
209+
| `setSampleRate(rate)` | number | `100` | Crash and hang sample rate; the SDK clamps the value to `0` through `100` |
210+
211+
<Warning>
212+
Enable Crash after `Flashcat.initialize()` and `FlashcatRum.enable()`, and do it early. Crash events are written through the RUM feature. If RUM is not enabled, the Crash module drops received crash replays.
213+
</Warning>
214+
215+
## Background and deferred upload
216+
217+
By default, the SDK uploads on the foreground cadence configured by `setBatchUploadFrequencyMs()` and triggers `flush()` when the application backgrounds. If you want HarmonyOS WorkScheduler to wake the app for uploads, register deferred upload work.
218+
219+
```ts
220+
const config = new ConfigurationBuilder('<CLIENT_TOKEN>', 'production')
221+
.setDeferredUploadWork('FlashcatUploadAbility', 71001)
222+
.setUploadOnWifiOnly(true)
223+
.setDeferredUploadRequiresCharging(false)
224+
.build();
225+
```
226+
227+
| Method | Default | Description |
228+
|--------|---------|-------------|
229+
| `setDeferredUploadWork(abilityName, workId?)` | Disabled, `workId` defaults to `71001` | Registers a system WorkScheduler task; the host application must declare the matching `WorkSchedulerExtensionAbility` |
230+
| `setUploadOnWifiOnly(enabled)` | `false` | Restricts deferred upload work to Wi-Fi |
231+
| `setDeferredUploadRequiresCharging(enabled)` | `true` | Restricts deferred upload work to charging state |
232+
233+
<Note>
234+
The SDK registers the WorkScheduler task. When your `WorkSchedulerExtensionAbility` wakes, call `Flashcat.flushAndWait()` to perform a bounded batch drain.
235+
</Note>
236+
237+
## Upload HarmonyOS crash symbols
238+
239+
To de-obfuscate ArkTS stacks and symbolicate native `.so` stacks in the console, upload build artifacts with `@flashcatcloud/hvigor-plugin`.
240+
241+
The plugin uploads two artifact types:
242+
243+
| Type | Files | Purpose |
244+
|------|-------|---------|
245+
| ArkTS Sourcemap | `sourceMaps.map`, optional `nameCache.json` | Restores ArkTS / TS files, functions, lines, and columns |
246+
| Native symbols | Unstripped `.so` files | Resolves C/C++ frames by GNU build-id |
247+
248+
The plugin ships as an npm package (on **npm**, not ohpm); install it as a build-time dev dependency in your project's root `package.json`, not in `oh-package.json5`:
249+
250+
```bash
251+
npm install -D @flashcatcloud/hvigor-plugin
252+
```
253+
254+
Then register the plugin in the module's `hvigorfile.ts`:
255+
256+
```ts hvigorfile.ts
257+
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
258+
import { flashcatSymbolUploadPlugin } from '@flashcatcloud/hvigor-plugin';
259+
260+
export default {
261+
system: hapTasks,
262+
plugins: [
263+
flashcatSymbolUploadPlugin({
264+
endpoint: 'https://browser.flashcat.cloud',
265+
apiKey: process.env.FLASHCAT_API_KEY ?? '',
266+
service: 'shopping-app',
267+
version: '1.0.0',
268+
enabled: process.env.FLASHCAT_UPLOAD === '1'
269+
})
270+
]
271+
};
272+
```
273+
274+
<Note>
275+
`flashcatSymbolUploadPlugin()` also accepts two optional fields: `buildDir` (build output directory, default `build/default`) and `pluginVersion` (the version sent in the `DD-EVP-ORIGIN-VERSION` upload header, default `0.1.0`). Neither is normally required.
276+
</Note>
277+
278+
Run the upload task after a release build:
279+
280+
```bash
281+
FLASHCAT_UPLOAD=1 FLASHCAT_API_KEY=*** \
282+
hvigorw uploadFlashcatSymbols --mode module -p module=entry@default -p product=default
283+
```
284+
285+
The plugin sends `multipart/form-data` to `{endpoint}/sourcemap/upload`:
286+
287+
| Header | Value |
288+
|--------|-------|
289+
| `DD-API-KEY` | Flashduty API Key used to resolve the account |
290+
| `DD-EVP-ORIGIN` | `flashcat-hvigor-plugin` |
291+
| `DD-EVP-ORIGIN-VERSION` | Plugin version |
292+
293+
Upload event types:
294+
295+
| Event type | Form fields |
296+
|------------|-------------|
297+
| `harmony_sourcemap` | `event`, `source_map`, optional `name_cache` |
298+
| `harmony_symbol_file` | `event`, `symbol_file` |
299+
300+
<Tip>
301+
Native symbolication depends on the GNU build-id in each `.so`. The HarmonyOS NDK generates build-id by default. If your build pipeline disables it, add `-Wl,--build-id` for the `.so`.
302+
</Tip>

0 commit comments

Comments
 (0)