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