Skip to content

Troubleshooting

This article provides basic troubleshooting entry points for HarmonyOS SDK initialization and reporting issues.

Initialization and Log Diagnostics

Initialization Failure

If SDK initialization fails, we recommend checking the following first:

  1. Whether datakitUrl, datawayUrl, and clientToken are correctly configured according to your deployment method
  2. Whether ft_sdk.har and ft_native.har are placed in the libs directory and declared in oh-package.json5 as @guancecloud/ft_sdk and @guancecloud/ft_native, then run ohpm install
  3. Whether the app has completed the oh-package.json5 dependency declarations as documented
  4. Whether SDK initialization occurs during the app startup phase

Checking SDK Initialization Exceptions

Check hilog for logs whose Tag has the [FT-SDK] prefix. Internal logs such as SDK initialization, configuration installation, and data synchronization are output with this prefix, which can be used to locate issues such as initialization failures, configurations not taking effect, or network synchronization exceptions.

Enabling Debug Mode

You can enable SDK Debug mode with the following configuration. setDebug(true) is the master switch for SDK internal logs. After enabling it, the console hilog outputs SDK debug logs. You can filter by the [FT-SDK] characters to locate SDK internal logs. setSdkLogLevel(...) controls the output threshold:

Log Level Output
SDKLogLevel.V, SDKLogLevel.D Outputs all current SDK diagnostic logs: D, I, W, E
SDKLogLevel.I Outputs I, W, E
SDKLogLevel.W Outputs W, E
SDKLogLevel.E Outputs only E
import { FTSDK, FTSDKConfig, SDKLogLevel } from '@guancecloud/ft_sdk/Index';

const sdkConfig = FTSDKConfig.builder(datawayUrl, clientToken)
  .setDebug(true)
  .setSdkLogLevel(SDKLogLevel.D);

FTSDK.install(sdkConfig, this.context);

We recommend disabling this configuration when releasing a Release build.

Writing SDK Internal Logs to Local Files

To troubleshoot production or intermittent issues, you can write SDK internal diagnostic logs to local files in the app sandbox for later export and analysis. You must enable setDebug(true) at the same time. You can use setSdkLogLevel(...) to control the log level to record.

import { FTSDK, FTSDKConfig, SDKLogLevel } from '@guancecloud/ft_sdk/Index';

const sdkConfig = FTSDKConfig.builder(datawayUrl, clientToken)
  .setDebug(true)
  .setSdkLogLevel(SDKLogLevel.D)
  .setEnableInnerLogFile(true, {
    singleFileMaxSize: 5 * 1024 * 1024,
    totalFileMaxSize: 50 * 1024 * 1024,
    flushBatchSize: 20,
    flushIntervalMs: 200
  });

FTSDK.install(sdkConfig, this.context);

FTInnerLogFileConfig

setEnableInnerLogFile(true, config) accepts an FTInnerLogFileConfig to adjust the internal log file writing policy:

Field Type Required Description
singleFileMaxSize number No Size of a single log file. Default 5MB, range 1MB ~ 10MB
totalFileMaxSize number No Total size threshold of log files. Default 50MB, range 10MB ~ 100MB. When the threshold is exceeded, cleanup starts from the earliest historical rotated files, and the current file is retained
flushBatchSize number No Number of entries written per batch. Default 20, range 1 ~ 100
flushIntervalMs number No Flush interval. Default 200ms, range 50ms ~ 5000ms

Log files are written by default to the filesDir/ft_sdk_logs/ directory in the app sandbox:

  • Current log file: ft_inner_current.log
  • Historical rotated files: ft_inner_*.log

When the total log size exceeds the configured threshold, the SDK cleans up starting from the earliest historical rotated files, and the current log file is retained. Internal log files record only the SDK's own diagnostic logs and do not include business Logs written by FTLogger.

To ensure the completeness of internal logs, set this configuration before FTSDK.install(...) and enable setDebug(true) at the same time. Values outside the configured range are truncated to the allowed range and rounded by the SDK.

Data Reporting and Cache

No Data Reported

We recommend troubleshooting in the following order:

  1. Confirm the prerequisites are completed, especially the DataKit and RUM collector configurations
  2. Confirm the app device can access datakitUrl or datawayUrl
  3. If setProxy(...), setProxyAuthenticator(...), or setDns(...) is configured, confirm the proxy, authentication information, DNS server, or DoH address is correct. These configurations only affect SDK data upload requests
  4. Refer to Enabling Debug Mode to check the initialization and reporting logs
  5. Confirm that RUM has executed installRUMConfig and at least one collection item to verify is enabled
  6. The SDK enables deflate compression for uploaded data by default. If you suspect server-side or network path incompatibility, you can temporarily set setCompressIntakeRequests(false) for comparison

Cache and Synchronization

  • The SDK auto-sync uses a 10-second aggregation window. It is normal for uploads not to be initiated immediately after collection
  • If auto-sync is disabled via FTSDKConfig.setAutoSync(false) or FTSDK.setAutoSync(false), you need to manually call FTSDK.flushSyncData() as described in SDK Initialization
  • After SDK initialization, you can re-enable auto-sync with FTSDK.setAutoSync(true)
  • FTSDK.flushSyncData() does not wait for the 10-second aggregation window. It schedules the upload immediately after flushing the pending RUM and Log worker queues as much as possible
  • If the local cache is abnormal, use FTSDK.clearAllData() to clear unreported data and then verify again
  • When using FileStore, first confirm whether shadow mode is active. In shadow mode, SQLite still handles reading and uploading, while writes are mirrored to FileStore for pre-migration validation. See SDK Initialization for detailed configuration
  • Migrating old SQLite caches for the first time requires explicitly calling setNeedTransformOldCache(true). If capacity is insufficient or the old cache is corrupted, the source cache is retained. After fixing the conditions, restart to continue processing

RUM Automatic Collection

UI Block Not Collected

Confirm that setEnableTrackAppUIBlock(true, blockDurationMs) is enabled in the RUM configuration. HarmonyOS UI block collection relies only on the system MAIN_THREAD_JANK event. The SDK calculates the duration using the event's begin_time and end_time, and reports only foreground blocks that exceed the blockDurationMs threshold.

System events have a startup grace period, consecutive timeout requirements, and process-level reporting restrictions. Therefore, a single blocking test cannot be the sole basis for determining whether collection is effective. When troubleshooting, enable SDK Debug logs and filter hilog for [FT-UI-BLOCK] to confirm whether the system event listener is registered and whether the block has been reported.

Automatic Network Request Collection

HttpInterceptorChain Not Taking Effect

If automatic collection using HttpInterceptorChain from @kit.NetworkKit does not take effect, we recommend checking the following first:

  1. Whether the current device or compilation target is HarmonyOS API 22 or higher. This capability is not supported below API 22
  2. Whether the project has installed ft_sdk.har and ft_sdk_ext.har, declared them in oh-package.json5 as @guancecloud/ft_sdk and @guancecloud/ft_sdk_ext, and completed ohpm install
  3. Whether setEnableTraceUserResource(true) is enabled. To automatically inject Trace Headers, you also need to enable setEnableAutoTrace(true) in the Trace configuration
  4. It is known that in concurrent request scenarios of @kit.NetworkKit, even when creating independent HttpRequest and HttpInterceptorChain instances for each request, the following exception may still be triggered: {"code":2300003,"message":"Invalid URL format or missing URL"}
  5. If you encounter the above error, we recommend falling back to serial verification first. In concurrent scenarios, you can switch to RCP or Axios compatibility mode, or temporarily avoid using HttpInterceptorChain in high-concurrency paths

Resource Not Collected

If HTTP requests are created and automatic collection interceptors are attached, but SDK initialization and RUM configuration are executed afterward, requests may succeed while Resource data is not generated.

We recommend checking the following first:

  1. Whether HttpRequest is created and createFTHttpInterceptorChain() or applyFTHttpTrack() is called before FTSDK.installRUMConfig() is executed
  2. Whether setEnableTraceUserResource(true) is enabled in the RUM configuration

Cause:

  • When HttpInterceptorChain is created, the current RUM configuration is read immediately to determine whether to enable automatic Resource collection
  • If this step occurs before FTSDK.installRUMConfig(), the SDK reads the default value false
  • Even if SDK initialization is completed afterward, the already-created automatic collection interceptor instances will not automatically refresh to the enabled state, so Resource data will not be generated

Recommended approach:

  1. Complete FTSDK.install() and FTSDK.installRUMConfig() first, then create HttpRequest and attach HttpInterceptorChain
  2. If the request object or interceptor chain was created in advance, recreate and re-attach it after SDK initialization is completed
  3. If you really need to create automatic collection objects before SDK initialization, explicitly pass the switches when creating them to avoid relying on default configuration values

Optional code example:

applyFTAxiosTrack(client, {
  enableTraceInterceptor: true,
  enableResourceInterceptor: true
});

sdk.init();

Notes:

  • Explicitly passing enableTraceInterceptor and enableResourceInterceptor only ensures that the automatic collection mechanism itself is enabled
  • Requests already sent before SDK initialization is completed may still fail to generate or fill in Resource data because the RUM context has not been fully initialized
  • Therefore, the recommended approach is still to complete SDK initialization first, and then create and use automatic collection objects

The same approach also applies to RCP and HttpInterceptorChain:

  • Axios: applyFTAxiosTrack(client, { enableTraceInterceptor: true, enableResourceInterceptor: true })
  • RCP: createFTRCPInterceptors(true, true) or createFTRCPTrackConfig({ enableTraceInterceptor: true, enableResourceInterceptor: true })
  • HTTP: createFTHttpInterceptorChain({ enableTraceInterceptor: true, enableResourceInterceptor: true }) or applyFTHttpTrack(request, { enableTraceInterceptor: true, enableResourceInterceptor: true })

Feedback

Is this page helpful?