Unity Application Integration¶
Prerequisites¶
Note: If you have activated the RUM Headless service, the prerequisites have already been automatically configured for you. Simply proceed with integrating your application.
- Install DataKit;
- Configure the RUM Collector;
- Ensure DataKit is accessible over the public internet and has the IP geolocation database installed: refer to this guide.
Application Integration¶
Currently, this version of Unity only supports Android and iOS platforms. Log in to the Guance console and navigate to the "User Access Monitoring" page. Click on "Create Application" in the top-left corner to start creating a new application.
-
Enter an "Application Name", "Application ID", and select the "Custom" application type.
-
Application Name: Used to identify the name of the monitored application.
- Application ID: A unique identifier for the application within the current workspace, corresponding to the field: app_id. Only English letters, numbers, and underscores are allowed, up to 48 characters.
Installation¶
Source Code Repository: https://github.com/GuanceCloud/datakit-unity
Demo Repository: https://github.com/GuanceCloud/datakit-unity/blob/dev/Assets/Scenes
- Download the latest ft-sdk-unity.unitypackage
Assets/Plugins
├── Android
│ ├── FTUnityBridge.java // Android bridge
│ ├── InnerClassProxy.java // Android Inner Setting Proxy
│ ├── ft-sdk-release.aar // Android SDK
│ ├── gson-2.8.5.jar // Android SDK 依赖第三方库
├── FTSDK.cs // FTSDK.prefab binding script
├── FTSDK.prefab // SDK Initialization prefab
├── FTUnityBridge.cs // Unity bridge for iOS, Android, etc.
├── FTViewObserver.cs // FTViewObserver.prefab binding script
├── FTViewObserver.prefab // View Page Listener prefab
├── UnityMainThreadDispatcher.cs // UnityMainThreadDispatcher.prefab binding script
├── UnityMainThreadDispatcher.prefab // Main Thread Queue prefab
├── iOS
│ ├── FTMobileSDK.xcframework // iOS SDK
│ ├── FTUnityBridge.mm // iOS bridge
- Go to
Asserts
->Import Package
->Custom Package...
and importft-sdk-unity.unitypackage
. - Add the third-party JSON parsing library
"com.unity.nuget.newtonsoft-json"
viaPackage Manager
->Add Package by name ...
. - Drag and drop the
FTSDK.prefab
onto the first scene page and initialize the SDK inside the_InitSDK
method ofFTSDK.cs
. If native Android and iOS projects have already integrated the native SDK, comment out the_InitSDK
method to avoid duplicate initialization. - Drag and drop the
FTViewObserver.prefab
onto other scene pages to monitor the lifecycle of views, including app sleep and wake-up events. - Monitor Unity crash data and regular logs through
Application.logMessageReceived
, as seen in theOnEnable
andOnDisable
methods ofFTSDK.cs
.
Note: If you have already integrated the native SDK (Android: gson-2.8.5.jar, ft-sdk-release.aar; iOS: FTMobileSDK.framework), you can remove them from the project. Additionally, Android Okhttp request and startup duration features require integration with ft-plugin. For detailed configuration, please refer to Android SDK.
Initialization¶
FTUnityBridge.Install(new SDKConfig
{
datakitUrl = "http://10.0.0.1:9529",
env = "prod",
debug = true,
});
Field | Type | Required | Description |
---|---|---|---|
datakitUrl | string | Yes | URL address for reporting in a local environment (Datakit). Example: http://10.0.0.1:9529. The default port is 9529, and the device running the SDK must be able to access this address. Note: Either datakitUrl or datawayUrl must be set. |
datawayUrl | string | Yes | Public network Dataway reporting URL obtained from the [User Access Monitoring] application. Example: https://open.dataway.url. The device running the SDK must be able to access this address. Note: Either datakitUrl or datawayUrl must be set. |
clientToken | string | Yes | Authentication token, must be used together with datawayUrl |
debug | boolean | No | Determines whether Debug logs should be printed. Default: false |
env | string | No | Environment, default: prod . Any characters are acceptable, but single words like test are recommended. |
serviceName | string | No | Name of the associated business or service. Default: df_rum_ios , df_rum_android |
globalContext | object | No | Adds custom tags |
autoSync | boolean | No | Whether to automatically sync collected data to the server. Default: YES . When set to NO , use the flushSyncData method to manage data syncing manually. |
syncPageSize | number | No | Sets the number of entries per sync request. Range: [5, ). Larger values mean more computational resources will be consumed during synchronization. Default: 10 |
syncSleepTime | number | No | Sets the interval time between sync requests. Range: [0,5000]. Not set by default. |
enableDataIntegerCompatible | boolean | No | Recommended to enable if coexistence with web data is required. This setting helps handle compatibility issues related to web data type storage. Enabled by default in versions 1.1.0 and above. |
compressIntakeRequests | boolean | No | Enables deflate compression for upload/sync requests. Disabled by default. Supported in versions 1.1.0 and above. |
enableLimitWithDbSize | boolean | No | Enables limiting data size using the database. Default limit is 100MB, unit: Byte. Larger databases increase disk pressure. Disabled by default. Note: Enabling this makes the logCacheLimitCount setting in Log configurations and rumCacheLimitCount in RUM configurations ineffective. Supported in versions 1.1.0 and above. |
dbCacheLimit | number | No | DB cache size limit. Range: [30MB, ). Default: 100MB, unit: byte. Supported in versions 1.1.0 and above. |
dbDiscardStrategy | string | No | Sets the data discard rule for the database. Discard strategies: discard (discard new data - default), discardOldest (discard old data). Supported in versions 1.1.0 and above. |
dataModifier | object | No | Modifies individual fields. Supported in versions 1.1.0 and above. See example usage here. |
lineDataModifier | object | No | Modifies entire lines of data. Supported in versions 1.1.0 and above. See example usage here. |
RUM Configuration¶
FTUnityBridge.InitRUMConfig(new RUMConfig()
{
androidAppId = "androidAppId",
iOSAppId = "iOSAppId",
sampleRate = 0.8f,
});
Field | Type | Required | Description |
---|---|---|---|
androidAppId | string | Yes | Set RUM appid to activate RUM collection functionality. How to get appid |
iOSAppId | string | Yes | Set RUM appid to activate RUM collection functionality. How to get appid |
sampleRate | float | No | Sampling rate, range [0,1], where 0 means no sampling and 1 means full sampling. Default: 1. Applies to all View, Action, LongTask, and Error data under the same session_id. |
sessionOnErrorSampleRate | float | No | Sets the error sampling rate. When a session is not sampled by sampleRate, data collected includes the one minute before an error occurs. Range [0,1], where 0 means no sampling and 1 means full sampling. Default: 0. Applies to all View, Action, LongTask, and Error data under the same session_id. |
enableNativeUserAction | boolean | No | Whether to track Native Action , e.g., Button click events. Pure uni-app applications are advised to disable this. Default: false . Not supported in Android cloud packaging. |
enableNativeUserResource | boolean | No | Whether to perform automatic tracking of Native Resource . Default: false . Not supported in Android cloud packaging. Since uniapp's network requests on iOS are implemented using system APIs, enabling this option allows collecting all resource data on iOS. In such cases, manual resource data collection on iOS should be disabled to prevent duplication. |
enableNativeUserView | boolean | No | Whether to perform automatic tracking of Native View . Pure uni-app applications are advised to disable this. Default: false . |
errorMonitorType | string/array | No | Additional error monitoring types: all , battery , memory , cpu . Not set by default. |
deviceMonitorType | string/array | No | Additional view monitoring types: all , battery (Android only), memory , cpu , fps . Not set by default. |
detectFrequency | string | No | View monitoring frequency: normal (default), frequent , rare . |
globalContext | object | No | Custom global parameters. Special key: track_id (used for tracking functions). |
enableResourceHostIP | boolean | No | Whether to collect the target domain's IP address for requests. Scope: only affects default collection when enableNativeUserResource is true. iOS: supported on iOS 13+. Android: due to Okhttp's IP caching mechanism for the same domain, the same OkhttpClient will only generate it once as long as the server IP remains unchanged. |
enableTrackNativeCrash | boolean | No | Whether to enable monitoring of Android Java Crash and OC/C/C++ crashes. Default: false . |
enableTrackNativeAppANR | boolean | No | Whether to enable monitoring of Native ANR . Default: false . |
enableTrackNativeFreeze | boolean | No | Whether to perform automatic tracking of Native Freeze . Default: false . |
nativeFreezeDurationMs | number | No | Sets the threshold for capturing Native Freeze lag. Range: [100, ), unit: milliseconds. Default: 250ms for iOS, 1000ms for Android. |
rumDiscardStrategy | string | No | Discard strategy: discard (discard new data - default), discardOldest (discard old data). |
rumCacheLimitCount | number | No | Local cache maximum RUM entry count limit [10_000, ), default: 100_000. |
Log Configuration¶
FTUnityBridge.InitLogConfig(new LogConfig
{
sampleRate = 0.9f,
enableCustomLog = true,
enableLinkRumData = true,
});
Field | Type | Required | Description |
---|---|---|---|
sampleRate | float | No | Sampling rate, range [0,1], where 0 means no sampling and 1 means full sampling. Default: 1. |
enableLinkRumData | boolean | No | Whether to link with RUM data |
enableCustomLog | boolean | No | Whether to enable custom logging |
discardStrategy | string | No | Log discard strategy: discard (discard new data - default), discardOldest (discard old data). |
logLevelFilters | array |
No | Log level filters. Array must include log levels: info (informational), warning (warning), error (error), critical , ok (recovered). |
globalContext | object | No | Custom global parameters |
logCacheLimitCount | number | No | Local cache maximum log entry count limit [1000, ), larger logs increase disk cache pressure. Default: 5000. |
Trace Configuration¶
FTUnityBridge.InitTraceConfig(new TraceConfig
{
sampleRate = 0.9f,
traceType = TraceType.DDTrace,
enableNativeAutoTrace = true,
enableLinkRumData = true
});
Field | Type | Required | Description |
---|---|---|---|
sampleRate | float | No | Sampling rate, range [0,1], where 0 means no sampling and 1 means full sampling. Default: 1. |
traceType | string | No | Trace type: ddTrace (default), zipkinMultiHeader , zipkinSingleHeader , traceparent , skywalking , jaeger |
enableLinkRUMData | boolean | No | Whether to link with RUM data. Default: false . |
enableNativeAutoTrace | boolean | No | Whether to enable native network auto-tracing for iOS NSURLSession and Android OKhttp . Default: false . Not supported in Android cloud packaging. Since uniapp's network requests on iOS are implemented using system APIs, enabling this option allows automatic tracing of network requests initiated by uniapp on iOS. In such cases, manual trace collection on iOS should be disabled to prevent incorrect linking of traces with RUM data. |
RUM User Data Tracking¶
Currently, RUM data transmission can only be achieved through manual method calls.
Action¶
Usage Method¶
/// <summary>
/// Add an Action
/// </summary>
/// <param name="actionName"> Action name</param>
/// <param name="actionType"> Action type</param>
public static void StartAction(string actionName, string actionType)
/// <summary>
/// Add an Action
/// </summary>
/// <param name="actionName">Action name</param>
/// <param name="actionType">Action type</param>
/// <param name="property">Additional property parameter</param>
public static void StartAction(string actionName, string actionType, Dictionary<string, object> property)
Code Example¶
View¶
Usage Method¶
/// <summary>
/// Start a View
/// </summary>
/// <param name="viewName">Current page name</param>
public static void StartView(string viewName)
/// <summary>
/// Start a View
/// </summary>
/// <param name="viewName">Current page name</param>
/// <param name="property">Additional property parameter</param>
public static void StartView(string viewName, Dictionary<string, object> property)
/// <summary>
/// End a View
/// </summary>
public static void StopView()
/// <summary>
/// End a View
/// </summary>
/// <param name="property">Additional property parameter</param>
public static void StopView(Dictionary<string, object> property)
Code Example¶
Resource¶
Usage Method¶
/// <summary>
/// Start a Resource
/// </summary>
/// <param name="resourceId">Resource Id</param>
/// <returns></returns>
public static async Task StartResource(string resourceId)
/// <summary>
/// Start a Resource
/// </summary>
/// <param name="resourceId">Resource Id</param>
/// <param name="property">Additional property parameter</param>
/// <returns></returns>
public static async Task StartResource(string resourceId, Dictionary<string, object> property)
/// <summary>
/// End a Resource
/// </summary>
/// <param name="resourceId">Resource Id</param>
/// <returns></returns>
public static async Task StopResource(string resourceId)
/// <summary>
/// End a Resource
/// </summary>
/// <param name="resourceId">Resource Id</param>
/// <param name="property">Additional property parameter</param>
/// <returns></returns>
public static async Task StopResource(string resourceId, Dictionary<string, object> property)
/// <summary>
/// Add network transfer content and metrics
/// </summary>
/// <param name="resourceId">Resource Id</param>
/// <param name="resourceParams">Data transfer content</param>
/// <param name="netStatus">Network metric data</param>
public static async Task AddResource(string resourceId, ResourceParams resourceParams)
ResourceParams¶
Method Name | Type | Required | Description |
---|---|---|---|
url | string | Yes | URL address |
requestHeader | string | No | Request header parameters, no format restrictions |
responseHeader | string | No | Response header parameters, no format restrictions |
responseConnection | string | No | Response connection |
responseContentType | string | No | Response ContentType |
responseContentEncoding | string | No | Response ContentEncoding |
resourceMethod | string | No | Request method, e.g., GET, POST |
responseBody | string | No | Response body content |
Code Example¶
FTUnityBridge.StartResource(resourceId);
FTUnityBridge.StopResource(resourceId);
ResourceParams resourceParams = new ResourceParams();
resourceParams.url = url;
resourceParams.requestHeader = client.DefaultRequestHeaders.ToDictionary(header => header.Key, header => string.Join(",", header.Value));
resourceParams.responseHeader = response.Headers.ToDictionary(header => header.Key, header => string.Join(",", header.Value));
resourceParams.resourceStatus = (int)response.StatusCode;
resourceParams.responseBody = responseData;
resourceParams.resourceMethod = "GET";
FTUnityBridge.AddResource(resourceId, resourceParams);
Error¶
Usage Method¶
/// <summary>
/// Add error information
/// </summary>
/// <param name="log">Log</param>
/// <param name="message">Message</param>
/// <param name="errorType">Error type</param>
/// <param name="state">Program runtime state</param>
/// <returns></returns>
public static async Task AddError(string log, string message)
/// <summary>
/// Add error information
/// </summary>
/// <param name="log">Log</param>
/// <param name="message">Message</param>
/// <param name="errorType">Error type</param>
/// <param name="state">Program runtime state</param>
/// <param name="property">Additional property parameter</param>
/// <returns></returns>
public static async Task AddError(string log, string message,
Dictionary<string, object> property)
Code Example¶
void OnEnable()
{
Application.logMessageReceived += LogCallBack;
}
void OnDisable()
{
Application.logMessageReceived -= LogCallBack;
}
void LogCallBack(string condition, string stackTrace, LogType type)
{
if (type == LogType.Exception)
{
FTUnityBridge.AddError(stackTrace, condition);
}
}
LongTask¶
Usage Method¶
/// <summary>
/// Add a long-running task
/// </summary>
/// <param name="log">Log content</param>
/// <param name="duration">Duration, in nanoseconds</param>
/// <returns></returns>
public static async Task AddLongTask(string log, long duration)
/// <summary>
/// Add a long-running task
/// </summary>
/// <param name="log">Log content</param>
/// <param name="duration">Duration, in nanoseconds</param>
/// <param name="property">Additional property parameter</param>
/// <returns></returns>
public static async Task AddLongTask(string log, long duration, Dictionary<string, object> property)
Code Example¶
Logging¶
Currently, log content is limited to 30 KB. Excess characters will be truncated.
Usage Method¶
/// <summary>
/// Add log
/// </summary>
/// <param name="log">Log content</param>
/// <param name="level">Log level: info, warning, error, critical, ok</param>
/// <returns></returns>
public static async Task AddLog(string log, LogLevel level)
/// <summary>
/// Add log
/// </summary>
/// <param name="log">Log content</param>
/// <param name="level">Log level: info, warning, error, critical, ok</param>
/// <param name="property">Additional property parameter</param>
/// <returns></returns>
public static async Task AddLog(string log, LogLevel level, Dictionary<string, object> property)
LogLevel¶
Method Name | Meaning |
---|---|
info | Informational |
warning | Warning |
error | Error |
critical | Critical |
ok | Recovered |
Code Example¶
Tracer Network Trace¶
Tracing is achieved by generating a Trace Header and then adding it to the HTTP request headers to implement the tracing functionality.
Usage Method¶
/// <summary>
/// Get Trace ID
/// </summary>
/// <param name="url">URL address</param>
/// <returns>JSON string</returns>
public static async Task<string> GetTraceHeaderWithUrl(string url)
/// <summary>
/// Get Trace
/// </summary>
/// <param name="resourceId">Resource ID</param>
/// <param name="url">URL address</param>
/// <returns>JSON string</returns>
public static async Task<string> GetTraceHeader(string resourceId, string url)
Code Example¶
string headData = FTUnityBridge.GetTraceHeader(resourceId, FAKE_URL);
string headData = FTUnityBridge.GetTraceHeader(FAKE_URL);
Clear SDK Cache Data¶
Use FTUnityBridge
to clear unreported cached data
/**
* Clears all data that has not yet been uploaded to the server.
*/
FTUnityBridge.clearAllData();
Manually Synchronize Data¶
When SDKConfig.autoSync
is set to true
, no additional operations are needed, as the SDK will automatically synchronize data.
When SDKConfig.autoSync
is set to false
, you need to manually trigger the data synchronization method to perform data synchronization.
/**
* Manually synchronizes data. When `FTMobileConfig.autoSync=false` is configured, you need to manually trigger this method to perform data synchronization.
* @returns a Promise.
*/
FTUnityBridge.flushSyncData();
Adding Custom Tags¶
/// <summary>
/// Add custom global parameters. Applied to RUM and Log data
/// </summary>
public static void AppendGlobalContext(Dictionary<string, object> property)
/// <summary>
/// Add custom global RUM parameters. Applied to RUM data
/// </summary>
public static void AppendRUMGlobalContext(Dictionary<string, object> property)
/// <summary>
/// Add custom global Log parameters. Applied to Log data
/// </summary>
public static void AppendLogGlobalContext(Dictionary<string, object> property)
Binding and Unbinding User Information¶
Usage Method¶
/// <summary>
/// Bind RUM user information
/// </summary>
/// <param name="userId">Unique user ID</param>
public static async Task BindUserData(string userId)
/// <summary>
/// Bind RUM user information
/// </summary>
/// <param name="userData"></param>
public static async Task BindUserData(UserData userData)
Method Name | Type | Required | Description |
---|---|---|---|
userId | string | Yes | User ID |
userName | string | No | Username |
userEmail | string | No | User email |
extra | dictionary | No | Assign values using KV pairs. Refer to this section for rules. |
Code Example¶
FTUnityBridge.BindUserData(new UserData
{
userId = "userid",
userName = "userName",
userEmail = "someone@email.com",
extra = new Dictionary<string, string>{
{"custom_data","custom data"}
}
});
FTUnityBridge.UnBindUserdata()
Disabling the SDK¶
Data Masking¶
If you want to fully mask certain fields, it is recommended to use SDKConfig.dataModifier
for better performance. If you need detailed rule-based replacements, use SDKConfig.lineDataModifier
.
Single Field Modification (dataModifier)
- Purpose: Modify the value of a single field in the data
- Parameter Format:
{key: newValue}
- Example:
{"device_uuid": "xxx"}
will replace thedevice_uuid
field value in the target data with "xxx"
Single Line Data Modification (lineDataModifier)
- Purpose: Modify specific fields in certain types of data
- Parameter Format:
{measurement: {key: newValue}}
- Example:
{"view": {"view_url": "xxx"}}
will modify theview_url
field value in allview
type data to "xxx" - List of
measurement
data types:- RUM data:
view
,resource
,action
,long_task
,error
- Log data:
log
- RUM data:
FTUnityBridge.Install(new SDKConfig
{
//...
dataModifier = new Dictionary<string, object>{
{"device_uuid","xxx"}
},
lineDataModifier = new Dictionary<string, Dictionary<string, object>>
{
{"view",new Dictionary<string, object>{
{"view_url","xxx"}
}
}
}
});
Native and Unity Hybrid Development¶
If your project involves native development with some pages or business processes implemented using Unity, follow these steps to install and configure the SDK:
-
Installation: Follow the installation instructions provided in Install.
-
Initialization: Refer to the initialization configuration for the iOS SDK and Android SDK and perform initialization in the native project.
- Disable the initialization part of the Unity SDK in
FTSDK.cs
to avoid duplicate initialization.
// FTSDK.cs
IEnumerator _LoadPrefabs()
{
yield return Instantiate(MainThreadDispatch);
//_InitSDK(); // Disable initialization
yield return Instantiate(ViewObserver);
}
Publish Package Related Configurations¶
Android¶
iOS¶
Frequently Asked Questions¶
Adding Project Prefixes to Avoid Conflicting Fields¶
To avoid conflicts between custom fields and SDK data, it is recommended to add a project abbreviation prefix to tag names, for example, df_tag_name
. You can check the list of keys used by the SDK globally by referring to the source code here. When there are overlapping variables between SDK global variables and RUM or Log data, RUM or Log data will overwrite the global variables.