Unity 应用接入¶
前置条件¶
注意:若您开通了 RUM Headless 服务,前置条件已自动帮您配置完成,直接接入应用即可。
- 安装 DataKit;
- 配置 RUM 采集器;
- DataKit 配置为公网可访问,并且安装 IP 地理信息库。
应用接入¶
当前 Unity 版本暂时支持 Android 和 iOS 平台。登录观测云控制台,进入「用户访问监测」页面,点击左上角「新建应用」,即可开始创建一个新的应用。
1.输入「应用名称」、「应用ID」,选择 「自定义」 应用类型
- 应用名称:用于识别当前用户访问监测的应用名称。
- 应用 ID :应用在当前工作空间的唯一标识,对应字段:app_id 。该字段仅支持英文、数字、下划线输入,最多 48 个字符。
安装¶
源码地址:https://github.com/GuanceCloud/datakit-unity
Demo 地址:https://github.com/GuanceCloud/datakit-unity/blob/dev/Assets/Scenes
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 依赖第三方库
├── iOS
│ ├── FTMobileSDK.xcframework // iOS SDK
│ ├── FTUnityBridge.mm // iOS bridge
├── FTSDK.cs // FTSDK.prefab 绑定脚本
├── FTSDK.prefab // SDK 初始化预制件
├── FTUnityBridge.cs // Unity bridge 桥接 iOS Android 等平台方法
├── FTViewObserver.cs // FTViewObserver.prefab 绑定脚本
├── FTViewObserver.prefab // View 页面监听预制件
├── UnityMainThreadDispatcher.cs // UnityMainThreadDispatcher.prefab 绑定脚本
├── UnityMainThreadDispatcher.prefab // 主线程消费队列预制件
Asserts
->Import Package
->Custom Package...
导入ft-sdk-unity.unitypackage
- 添加 json 解析第三方库
"com.unity.nuget.newtonsoft-json"
,可以在Pakcage Manager
->Add Package by name ...
- 将
FTSDK.prefab
拖拽至第一个场景页面,并在FTSDK.cs
中_InitSDK
方法中初始化 SDK,如果原生 Android 和 iOS 工程已集成了原生 SDK,需要注释_InitSDK
方法,避免重复设置 - 将
FTViewObserver.prefab
拖拽至其他场景页面,来达到页面View
生命周期监听的目的,包括应用休眠和唤醒 - 通过
Application.logMessageReceived
监听转化 Unity 崩溃数据和普通日志数据,见FTSDK.cs
OnEnable
OnDisable
方法
注意:如果已经集成原生 SDK Android gson-2.8.5.jar、ft-sdk-release.aar ,iOS FTMobileSDK.framework 可以在项目中移除。 另外,Android Okhttp 请求和启动耗时功能,需要配合 ft-plugin 使用,详细配置请见 Android SDK
初始化¶
FTUnityBridge.Install(new SDKConfig
{
datakitUrl = "http://10.0.0.1:9529",
env = "prod",
debug = true,
});
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
datakitUrl | string | 是 | 本地环境部署(Datakit)上报 URL 地址,例子:http://10.0.0.1:9529,端口默认 9529,安装 SDK 设备需能访问该地址。注意:datakitUrl 和 datawayUrl 配置两者二选一 |
datawayUrl | string | 是 | 公网 Dataway 上报 URL 地址,从 [用户访问监测] 应用中获取,例子:https://open.dataway.url,安装 SDK 设备需能访问这地址。注意:datakitUrl 和 datawayUrl 配置两者二选一 |
clientToken | string | 是 | 认证 token,需要与 datawayUrl 同时使用 |
debug | boolean | 否 | 设置是否允许打印 Debug 日志,默认false |
env | string | 否 | 环境,默认prod ,任意字符,建议使用单个单词,例如 test 等 |
serviceName | string | 否 | 设置所属业务或服务的名称 默认:df_rum_ios 、df_rum_android |
globalContext | object | 否 | 添加自定义标签 |
autoSync | boolean | 否 | 是否在采集数据后自动同步到服务器。默认 YES 。当为 NO 时使用 flushSyncData 方法自行管理数据同步 |
syncPageSize | number | 否 | 设置同步请求条目数。范围 [5,)注意:请求条目数越大,代表数据同步占用更大的计算资源,默认为 10 |
syncSleepTime | number | 否 | 设置同步间歇时间。范围 [0,5000],默认不设置 |
enableDataIntegerCompatible | boolean | 否 | 需要与 web 数据共存情况下,建议开启。此配置用于处理 web 数据类型存储兼容问题。SDK 1.1.0 以后版本默认开启 |
compressIntakeRequests | boolean | 否 | 对上传同步数据进行 deflate 压缩,默认关闭,SDK 1.1.0 以上版本支持这个参数 |
enableLimitWithDbSize | boolean | 否 | 开启使用 db 限制数据大小,默认 100MB,单位 Byte,数据库越大,磁盘压力越大,默认不开启。 注意:开启之后 Log 配置 logCacheLimitCount 及 RUM 配置rumCacheLimitCount 将失效。SDK 1.1.0 以上版本支持该参数 |
dbCacheLimit | number | 否 | DB 缓存限制大小。范围 [30MB,),默认 100MB,单位 byte,SDK 1.1.0 以上版本支持该参数 |
dbDiscardStrategy | string | 否 | 设置数据库中数据丢弃规则。 丢弃策略: discard 丢弃新数据(默认)、discardOldest 丢弃旧数据。SDK 1.1.0 以上版本支持该参数 |
dataModifier | object | 否 | 对单个字段进行更改。SDK 1.1.0 以上支持,使用示例请看此处 |
lineDataModifier | object | 否 | 对单条数据数据进行更改。 SDK 1.1.0 以上支持,使用示例请看此处 |
RUM 配置¶
FTUnityBridge.InitRUMConfig(new RUMConfig()
{
androidAppId = "androidAppId",
iOSAppId = "iOSAppId",
sampleRate = 0.8f,
});
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
androidAppId | string | 是 | 对应设置 RUM appid ,才会开启RUM 的采集功能,获取 appid 方法 |
iOSAppId | string | 是 | 对应设置 RUM appid ,才会开启RUM 的采集功能,获取 appid 方法 |
sampleRate | float | 否 | 采样率,取值范围 [0,1],0 表示不采集,1 表示全采集,默认值为 1。作用域为同一 session_id 下所有 View,Action,LongTask,Error 数据 |
sessionOnErrorSampleRate | float | 否 | 设置错误采集率,当会话未被 sampleRate 采样时,若会话期间发生错误,可以采集到错误前 1 分钟范围的数据,取值范围 [0,1],0 表示不采集,1 表示全采集,默认值为 0。作用域为同一 session_id 下所有 View,Action,LongTask,Error 数据 |
enableNativeUserAction | boolean | 否 | 是否进行 Native Action 追踪,Button 点击事件,纯 uni-app 应用建议关闭,默认为 false ,Android 云打包不支持 |
enableNativeUserResource | boolean | 否 | 是否进行 Native Resource 自动追踪,默认为 false ,Android 云打包不支持。由于 uniapp 的网络请求在 iOS 端是使用系统 API 实现的,所以开启后,iOS 所有 resource 数据能够一并采集,此时请屏蔽 iOS 端的手动采集,以防止数据重复采集。 |
enableNativeUserView | boolean | 否 | 是否进行 Native View 自动追踪,纯 uni-app 应用建议关闭,,默认为 false |
errorMonitorType | string/array | 否 | 错误监控补充类型:all 、battery 、 memory 、 cpu ,默认不设置 |
deviceMonitorType | string/array | 否 | 页面监控补充类型: all 、battery (仅Android支持)、 memory 、cpu 、fps ,默认不设置 |
detectFrequency | string | 否 | 页面监控频率:normal (默认)、 frequent 、rare |
globalContext | object | 否 | 自定义全局参数,特殊 key :track_id (用于追踪功能) |
enableResourceHostIP | boolean | 否 | 是否采集请求目标域名地址的 IP。作用域:只影响 enableNativeUserResource 为 true 的默认采集。iOS:>= iOS 13 下支持。Android:单个 Okhttp 对相同域名存在 IP 缓存机制,相同 OkhttpClient ,在连接服务端 IP 不发生变化的前提下,只会生成一次。 |
enableTrackNativeCrash | boolean | 否 | 是否开启 Android Java Crash 和 OC/C/C++ 崩溃的监测,默认为 `false |
enableTrackNativeAppANR | boolean | 否 | 是否开启 Native ANR 监测,默认为 false |
enableTrackNativeFreeze | boolean | 否 | 是否进行 Native Freeze 自动追踪,默认为 false |
nativeFreezeDurationMs | number | 否 | 设置采集 Native Freeze 卡顿的阈值,取值范围 [100,),单位毫秒。iOS 默认 250ms,Android 默认 1000ms |
rumDiscardStrategy | string | 否 | 丢弃策略:discard 丢弃新数据(默认)、discardOldest 丢弃旧数据 |
rumCacheLimitCount | number | 否 | 本地缓存最大 RUM 条目数量限制 [10_000,),默认 100_000 |
Log 配置¶
FTUnityBridge.InitLogConfig(new LogConfig
{
sampleRate = 0.9f,
enableCustomLog = true,
enableLinkRumData = true,
});
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
sampleRate | float | 否 | 采样率,取值范围 [0,1],0 表示不采集,1 表示全采集,默认值为 1。 |
enableLinkRumData | boolean | 否 | 是否与 RUM 关联 |
enableCustomLog | boolean | 否 | 是否开启自定义日志 |
discardStrategy | string | 否 | 日志丢弃策略:discard 丢弃新数据(默认)、discardOldest 丢弃旧数据 |
logLevelFilters | array |
否 | 日志等级过滤,数组中需填写 日志等级:info 提示、warning 警告、error 错误、critical 、ok 恢复 |
globalContext | object | 否 | 自定义全局参数 |
logCacheLimitCount | number | 否 | 本地缓存最大日志条目数量限制 [1000,),日志越大,代表磁盘缓存压力越大,默认 5000 |
Trace 配置¶
FTUnityBridge.InitTraceConfig(new TraceConfig
{
sampleRate = 0.9f,
traceType = TraceType.DDTrace,
enableNativeAutoTrace = true,
enableLinkRumData = true
});
字段 | 类型 | 必须 | 说明 |
---|---|---|---|
sampleRate | float | 否 | 采样率,取值范围 [0,1],0 表示不采集,1 表示全采集,默认值为 1。 |
traceType | string | 否 | 链路类型:ddTrace (默认)、zipkinMultiHeader 、zipkinSingleHeader 、traceparent 、skywalking 、jaeger |
enableLinkRUMData | boolean | 否 | 是否与 RUM 数据关联,默认false |
enableNativeAutoTrace | boolean | 否 | 是否开启原生网络自动追踪 iOS NSURLSession ,Android OKhttp ,默认false , Android 云打包不支持。 由于 uniapp 的网络请求在 iOS 端是使用系统 API 实现的,所以开启后,iOS 端 uniapp 发起的网络请求可以自动追踪,此时请屏蔽 iOS 端的手动链路追踪,以防止链路与 RUM 数据关联错误。 |
RUM 用户数据追踪¶
目前只能通过手动方法调用来实现 RUM 数据传输
Action¶
使用方法¶
/// <summary>
/// 添加 Action
/// </summary>
/// <param name="actionName"> action 名称</param>
/// <param name="actionType"> action 类型</param>
public static void StartAction(string actionName, string actionType)
/// <summary>
/// 添加 Action
/// </summary>
/// <param name="actionName">action 名称</param>
/// <param name="actionType">action 类型</param>
/// <param name="property">附加属性参数</param>
public static void StartAction(string actionName, string actionType, Dictionary<string, object> property)
代码示例¶
View¶
使用方法¶
/// <summary>
/// View 开始
/// </summary>
/// <param name="viewName">当前页面名称</param>
public static void StartView(string viewName)
/// <summary>
/// View 开始
/// </summary>
/// <param name="viewName">当前页面名称</param>
/// <param name="property">附加属性参数</param>
public static void StartView(string viewName, Dictionary<string, object> property)
/// <summary>
/// View 结束
/// </summary>
public static void StopView()
/// <summary>
/// View 结束
/// </summary>
/// <param name="property">附加属性参数</param>
public static void StopView(Dictionary<string, object> property)
代码示例¶
Resource¶
使用方法¶
/// <summary>
/// resource 开始
/// </summary>
/// <param name="resourceId">资源 Id</param>
/// <returns></returns>
public static async Task StartResource(string resourceId)
/// <summary>
/// resource 开始
/// </summary>
/// <param name="resourceId">资源 Id</param>
/// <param name="property">附加属性参数</param>
/// <returns></returns>
public static async Task StartResource(string resourceId, Dictionary<string, object> property)
/// <summary>
/// resource 结束
/// </summary>
/// <param name="resourceId">资源 Id</param>
/// <returns></returns>
public static async Task StopResource(string resourceId)
/// <summary>
/// resource 结束
/// </summary>
/// <param name="resourceId">资源 Id</param>
/// <param name="property">附加属性参数</param>
public static async Task StopResource(string resourceId, Dictionary<string, object> property)
/// <summary>
/// 添加网络传输内容和指标
/// </summary>
/// <param name="resourceId">资源 Id</param>
/// <param name="resourceParams">数据传输内容</param>
/// <param name="netStatus">网络指标数据</param>
public static async Task AddResource(string resourceId, ResourceParams resourceParams)
ResourceParams¶
方法名 | 类型 | 必须 | 说明 |
---|---|---|---|
url | string | 是 | url 地址 |
requestHeader | string | 否 | 请求头参数,没有格式限制 |
responseHeader | string | 否 | 响应头参数,没有格式限制 |
responseConnection | string | 否 | 响应 connection |
responseContentType | string | 否 | 响应 ContentType |
responseContentEncoding | string | 否 | 响应 ContentEncoding |
resourceMethod | string | 否 | 请求方法 GET,POST 等 |
responseBody | string | 否 | 返回 body 内容 |
代码示例¶
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¶
使用方法¶
/// <summary>
/// 添加错误信息
/// </summary>
/// <param name="log">日志</param>
/// <param name="message">消息</param>
/// <param name="errorType">错误类型</param>
/// <param name="state">程序运行状态</param>
/// <returns></returns>
public static async Task AddError(string log, string message)
/// <summary>
/// 添加错误信息
/// </summary>
/// <param name="log">日志</param>
/// <param name="message">消息</param>
/// <param name="errorType">错误类型</param>
/// <param name="state">程序运行状态</param>
/// <param name="property">附加属性参数</param>
/// <returns></returns>
public static async Task AddError(string log, string message,
Dictionary<string, object> property)
代码示例¶
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¶
使用方法¶
/// <summary>
/// 添加长耗时任务
/// </summary>
/// <param name="log">日志内容</param>
/// <param name="duration">持续时间,纳秒</param>
/// <returns></returns>
public static async Task AddLongTask(string log, long duration)
/// <summary>
/// 添加长耗时任务
/// </summary>
/// <param name="log">日志内容</param>
/// <param name="duration">持续时间,纳秒</param>
/// <param name="property">附加属性参数</param>
/// <returns></returns>
public static async Task AddLongTask(string log, long duration, Dictionary<string, object> property)
代码示例¶
Log 日志打印¶
目前日志内容限制为 30 KB,字符超出部分会进行截断处理
使用方法¶
/// <summary>
/// 添加日志
/// </summary>
/// <param name="log">日志内容</param>
/// <param name="level">日志等级 info,warning,error,critical,ok</param>
/// <returns></returns>
public static async Task AddLog(string log, LogLevel level)
/// <summary>
/// 添加日志
/// </summary>
/// <param name="log">日志内容</param>
/// <param name="level">日志等级 info,warning,error,critical,ok</param>
/// <param name="property">附加属性参数</param>
/// <returns></returns>
public static async Task AddLog(string log, LogLevel level, Dictionary<string, object> property)
LogLevel¶
方法名 | 含义 |
---|---|
info | 提示 |
warning | 警告 |
error | 错误 |
critical | 严重 |
ok | 恢复 |
代码示例¶
Tracer 网络链路追踪¶
链路通过生成 Trace Header,然后通过将 Header 添加到 http 请求头上来实现链路功能
使用方法¶
/// <summary>
/// 获取链路 Id
/// </summary>
/// <param name="url">url 地址</param>
/// <returns>json 字符</returns>
public static async Task<string> GetTraceHeaderWithUrl(string url)
/// <summary>
/// 获取链路
/// </summary>
/// <param name="resourceId">资源 Id</param>
/// <param name="url">url 地址</param>
/// <returns>json 字符</returns>
public static async Task<string> GetTraceHeader(string resourceId, string url)
代码示例¶
string headData = FTUnityBridge.GetTraceHeader(resourceId, FAKE_URL);
string headData = FTUnityBridge.GetTraceHeader(FAKE_URL);
清理 SDK 缓存数据¶
使用 FTUnityBridge
清理未上报的缓存数据
主动同步数据¶
当配置 SDKConfig.autoSync
为 true
时,无需做额外的操作,SDK 会进行自动同步。
当配置 SDKConfig.autoSync
为 false
时,需要主动触发数据同步方法,进行数据同步。
/**
* 主动同步数据,当配置 `FTMobileConfig.autoSync=false` 时,需要主动触发本方法,进行数据同步。
* @returns a Promise.
*/
FTUnityBridge.flushSyncData();
添加自定义标签¶
/// <summary>
/// 添加自定义全局参数。作用于 RUM、Log 数据
/// </summary>
public static void AppendGlobalContext(Dictionary<string, object> property)
/// <summary>
/// 添加自定义 RUM 全局参数。作用于 RUM 数据
/// </summary>
public static void AppendRUMGlobalContext(Dictionary<string, object> property)
/// <summary>
/// 添加自定义 RUM、Log 全局参数。作用于 Log 数据
/// </summary>
public static void AppendLogGlobalContext(Dictionary<string, object> property)
用户信息绑定与解绑¶
使用方法¶
/// <summary>
/// 绑定 RUM 用户信息
/// </summary>
/// <param name="userId">用户唯一id</param>
public static async Task BindUserData(string userId)
/// <summary>
/// 绑定 RUM 用户信息
/// </summary>
/// <param name="userData"></param>
public static async Task BindUserData(UserData userData)
方法名 | 类型 | 必须 | 说明 |
---|---|---|---|
userId | string | 是 | 用户 id |
userName | string | 否 | 用户名 |
userEmail | string | 否 | 用户邮箱 |
extra | dictionary | 否 | KV 方式赋值,添加规则请查阅 此处 |
代码示例¶
FTUnityBridge.BindUserData(new UserData
{
userId = "userid",
userName = "userName",
userEmail = "someone@email.com",
extra = new Dictionary<string, string>{
{"custom_data","custom data"}
}
});
FTUnityBridge.UnBindUserdata()
关闭 SDK¶
数据脱敏¶
如果是希望对字段做全脱敏,推荐使用 SDKConfig.dataModifier
,表现的性能更好。如果需要细致规则替换推荐 SDKConfig.lineDataModifier
。
单字段修改(dataModifier)
- 作用:修改数据中的单个字段值
- 参数格式:
{key: newValue}
- 示例:
{"device_uuid": "xxx"}
会将目标数据的device_uuid
字段值替换为 "xxx"
单条数据数据更改(lineDataModifier)
- 作用:修改某类数据中的指定字段值
- 参数格式:
{measurement: {key: newValue}}
- 示例:
{"view": {"view_url": "xxx"}}
会修改所有view
类型数据的view_url
字段值为 "xxx" measurement
数据类型清单:- RUM 数据:
view
、resource
、action
、long_task
、error
- 日志数据:
log
- RUM 数据:
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"}
}
}
}
});
原生与 Unity 混合开发¶
如果您的项目是原生开发,部分页面或业务流程使用 Unity 实现,SDK 的安装初始化配置方法如下:
-
安装:安装方式不变
-
初始化:请参考 iOS SDK 初始化配置 、Android SDK 初始化配置 在原生工程内进行初始化配置
- 取消
Unity SDK
中FTSDK.cs
原有初始化部分,避免重复初始化
// FTSDK.cs
IEnumerator _LoadPrefabs()
{
yield return Instantiate(MainThreadDispatch);
//_InitSDK(); // 取消初始化
yield return Instantiate(ViewObserver);
}
Publish Package 相关配置¶
Android¶
iOS¶
常见问题¶
添加局变量避免冲突字段¶
为了避免自定义字段与 SDK 数据冲突,建议标签命名添加 项目缩写 的前缀,例如 df_tag_name
,项目中使用 key
值可查询源码。SDK 全局变量中出现与 RUM、Log 相同变量时,RUM、Log 会覆盖 SDK 中的全局变量。