关于依赖和包名的说明Flashduty Android SDK 完全兼容 Datadog 开源协议,代码中的 import 语句使用 com.datadog.android.* 包名。您可以无缝复用 Datadog 生态的文档、示例和最佳实践,同时享受 Flashduty 平台的服务。
Android RUM SDK 提供丰富的高级配置选项,帮助您根据业务需求定制数据收集和上下文信息。
支持的配置场景:
- 丰富用户会话 - 添加自定义视图、操作、资源和错误信息
- 保护敏感数据 - 屏蔽个人身份信息等敏感数据
- 关联用户会话 - 将用户会话与内部用户标识关联
- 控制数据量 - 通过采样和事件过滤优化数据收集
- 增强上下文 - 为数据添加自定义属性
丰富用户会话
自定义视图
当使用 ActivityViewTrackingStrategy 或 FragmentViewTrackingStrategy 时,RUM SDK 会自动追踪视图。您也可以在视图变为可见或可交互时手动发送自定义 RUM 视图。
import com.datadog.android.rum.GlobalRumMonitor
fun onResume() {
GlobalRumMonitor.get().startView(viewKey, viewName, attributes)
}
fun onPause() {
GlobalRumMonitor.get().stopView(viewKey, attributes)
}
import com.datadog.android.rum.GlobalRumMonitor;
public void onResume() {
GlobalRumMonitor.get().startView(viewKey, viewName, attributes);
}
public void onPause() {
GlobalRumMonitor.get().stopView(viewKey, attributes);
}
参数说明:
viewKey (String) - 视图的唯一标识符,同一个 viewKey 用于调用 startView() 和 stopView()
viewName (String) - 视图的名称
attributes (Map<String, Any?>) - 附加到视图的属性(可选)
自定义操作
除了自动追踪的用户交互,您还可以追踪特定的自定义用户操作(如点击、滑动、点赞)。
import com.datadog.android.rum.GlobalRumMonitor
import com.datadog.android.rum.RumActionType
fun onUserInteraction() {
GlobalRumMonitor.get().addAction(
RumActionType.TAP,
name,
attributes
)
}
import com.datadog.android.rum.GlobalRumMonitor;
import com.datadog.android.rum.RumActionType;
public void onUserInteraction() {
GlobalRumMonitor.get().addAction(
RumActionType.TAP,
name,
attributes
);
}
| 类型 | 描述 | 使用场景 |
|---|
RumActionType.TAP | 点击操作 | 按钮、图标点击 |
RumActionType.SCROLL | 滚动操作 | 列表、页面滚动 |
RumActionType.SWIPE | 滑动操作 | 滑动切换、手势 |
RumActionType.CLICK | 单击操作 | 通用点击 |
RumActionType.CUSTOM | 自定义操作 | 业务特定操作 |
自定义资源
除了自动追踪的资源,您还可以手动追踪特定的自定义资源(如网络请求、第三方库加载)。
import com.datadog.android.rum.GlobalRumMonitor
import com.datadog.android.rum.RumResourceKind
fun loadResource() {
GlobalRumMonitor.get().startResource(resourceKey, method, url, attributes)
}
fun resourceLoadSuccess() {
GlobalRumMonitor.get().stopResource(
resourceKey, statusCode, size,
RumResourceKind.NATIVE, attributes
)
}
fun resourceLoadError() {
GlobalRumMonitor.get().stopResourceWithError(
resourceKey, statusCode, message, source, throwable
)
}
import com.datadog.android.rum.GlobalRumMonitor;
import com.datadog.android.rum.RumResourceKind;
public void loadResource() {
GlobalRumMonitor.get().startResource(resourceKey, method, url, attributes);
}
public void resourceLoadSuccess() {
GlobalRumMonitor.get().stopResource(
resourceKey, statusCode, size,
RumResourceKind.NATIVE, attributes
);
}
public void resourceLoadError() {
GlobalRumMonitor.get().stopResourceWithError(
resourceKey, statusCode, message, source, throwable
);
}
| 类型 | 描述 | 适用场景 |
|---|
BEACON | 信标请求 | 统计上报 |
FETCH | Fetch 请求 | 现代异步请求 |
XHR | XHR 请求 | 传统 Ajax |
DOCUMENT | 文档资源 | HTML 文档 |
IMAGE | 图片资源 | 图片加载 |
JS | JavaScript 资源 | JS 文件 |
FONT | 字体资源 | 字体文件 |
CSS | CSS 资源 | 样式文件 |
MEDIA | 媒体资源 | 音视频文件 |
NATIVE | 原生资源 | 原生模块加载 |
OTHER | 其他资源 | 未分类资源 |
自定义错误
要记录特定错误,当异常发生时通知 RUM SDK:
import com.datadog.android.rum.GlobalRumMonitor
GlobalRumMonitor.get().addError(
message,
source,
throwable,
attributes
)
import com.datadog.android.rum.GlobalRumMonitor;
GlobalRumMonitor.get().addError(
message,
source,
throwable,
attributes
);
自定义计时
除了 RUM SDK 默认的性能指标,您还可以使用 addTiming API 测量关键操作的耗时。计时是相对于当前 RUM 视图开始时间的偏移量。
import com.datadog.android.rum.GlobalRumMonitor
fun onHeroImageLoaded() {
GlobalRumMonitor.get().addTiming("hero_image")
}
import com.datadog.android.rum.GlobalRumMonitor;
public void onHeroImageLoaded() {
GlobalRumMonitor.get().addTiming("hero_image");
}
设置计时后,可通过 @view.custom_timings.<timing_name> 访问,例如 @view.custom_timings.hero_image。
添加用户属性
RUM SDK 会自动追踪用户属性。您还可以添加额外的自定义用户属性,例如用户计划、用户组等。
import com.datadog.android.rum.GlobalRumMonitor
GlobalRumMonitor.get().setUserInfo(
id = "1234",
name = "John Doe",
email = "john@doe.com",
extraInfo = mapOf(
"plan" to "premium",
"group" to "vip"
)
)
import com.datadog.android.rum.GlobalRumMonitor;
import java.util.HashMap;
import java.util.Map;
Map<String, Object> extraInfo = new HashMap<>();
extraInfo.put("plan", "premium");
extraInfo.put("group", "vip");
GlobalRumMonitor.get().setUserInfo(
"1234",
"John Doe",
"john@doe.com",
extraInfo
);
自定义用户属性可用于在分析看板中分组和过滤数据,帮助您了解不同用户群体的使用情况。
事件和数据管理
清除所有数据
使用 clearAllData 清除当前存储在 SDK 中的所有未发送数据:
import com.datadog.android.Datadog
Datadog.clearAllData()
import com.datadog.android.Datadog;
Datadog.clearAllData();
停止数据收集
使用 stopInstance 停止收集数据并清除所有本地数据:
import com.datadog.android.Datadog
Datadog.stopInstance()
import com.datadog.android.Datadog;
Datadog.stopInstance();
调用 stopInstance() 后,SDK 将完全停止工作,需要重新初始化才能恢复数据收集。
控制事件批量上传
RUM SDK 会自动批量上传事件。您可以通过配置参数控制批量上传的行为:
import com.datadog.android.core.configuration.Configuration
import com.datadog.android.core.configuration.UploadFrequency
val configuration = Configuration.Builder(
clientToken = clientToken,
env = environmentName,
variant = appVariantName
)
.setBatchSize(batchSize)
.setUploadFrequency(UploadFrequency.FREQUENT)
.build()
import com.datadog.android.core.configuration.Configuration;
import com.datadog.android.core.configuration.UploadFrequency;
Configuration configuration = new Configuration.Builder(
clientToken, environmentName, appVariantName
)
.setBatchSize(batchSize)
.setUploadFrequency(UploadFrequency.FREQUENT)
.build();
| 频率 | 描述 | 适用场景 |
|---|
FREQUENT | 频繁上传 | 实时性要求高的场景 |
AVERAGE | 平均上传 | 默认值,平衡性能和实时性 |
RARE | 少量上传 | 节省流量和电量 |
设置远程日志阈值
您可以为远程记录的消息定义最低日志级别。低于该级别的日志不会发送到 Flashduty:
import com.datadog.android.log.Logs
import com.datadog.android.log.LogsConfiguration
import android.util.Log
val logsConfig = LogsConfiguration.Builder()
.setRemoteSampleRate(100f)
.setRemoteLogThreshold(Log.WARN)
.build()
Logs.enable(logsConfig)
import com.datadog.android.log.Logs;
import com.datadog.android.log.LogsConfiguration;
import android.util.Log;
LogsConfiguration logsConfig = new LogsConfiguration.Builder()
.setRemoteSampleRate(100f)
.setRemoteLogThreshold(Log.WARN)
.build();
Logs.enable(logsConfig);
设置 Log.WARN 阈值后,只有 WARN、ERROR 级别的日志会被上传,DEBUG 和 INFO 级别的日志将被过滤。
追踪自定义全局属性
除了由 RUM SDK 自动捕获的默认属性外,您还可以向 RUM 事件添加额外的上下文信息,例如自定义属性。
自定义属性的用途:
- 根据业务信息(如购物车状态、用户等级、广告活动)过滤和分组用户行为
- 跟踪特定用户的浏览路径
- 了解哪些用户受错误影响最大
- 监控关键用户的性能表现
追踪用户会话
要识别用户会话,在初始化 SDK 后使用 setUserInfo API:
import com.datadog.android.rum.GlobalRumMonitor
GlobalRumMonitor.get().setUserInfo(
id = "1234",
name = "John Doe",
email = "john@doe.com"
)
import com.datadog.android.rum.GlobalRumMonitor;
GlobalRumMonitor.get().setUserInfo("1234", "John Doe", "john@doe.com", null);
参数说明:
id (String) - 唯一用户标识符
name (String) - 用户友好名称,默认在 RUM UI 中显示
email (String) - 用户电子邮件,若无名称则显示邮件
- 以上属性均为可选,建议至少提供一个
追踪属性
全局属性会被附加到所有 RUM 事件中,用于添加通用的上下文信息。
添加全局属性:
import com.datadog.android.rum.GlobalRumMonitor
GlobalRumMonitor.get().addAttribute("key", "value")
import com.datadog.android.rum.GlobalRumMonitor;
GlobalRumMonitor.get().addAttribute("key", "value");
删除全局属性:
import com.datadog.android.rum.GlobalRumMonitor
GlobalRumMonitor.get().removeAttribute("key")
import com.datadog.android.rum.GlobalRumMonitor;
GlobalRumMonitor.get().removeAttribute("key");
Widgets 不会自动追踪。要监控 Widget 的交互,需要手动调用 API。
import com.datadog.android.rum.GlobalRumMonitor
import com.datadog.android.rum.RumActionType
fun onWidgetClicked() {
GlobalRumMonitor.get().addAction(
RumActionType.TAP,
"widget_clicked",
mapOf("widget_name" to "HomeWidget")
)
}
import com.datadog.android.rum.GlobalRumMonitor;
import com.datadog.android.rum.RumActionType;
import java.util.HashMap;
import java.util.Map;
public void onWidgetClicked() {
Map<String, Object> attributes = new HashMap<>();
attributes.put("widget_name", "HomeWidget");
GlobalRumMonitor.get().addAction(
RumActionType.TAP,
"widget_clicked",
attributes
);
}
初始化参数
在初始化 Flashduty Android SDK 时,您可以使用 Configuration.Builder 配置多种选项。
自动追踪视图
要自动追踪视图(Activities、Fragments),在初始化时使用 useViewTrackingStrategy:
import com.datadog.android.rum.RumConfiguration
import com.datadog.android.rum.tracking.ActivityViewTrackingStrategy
val rumConfig = RumConfiguration.Builder(applicationId)
.useViewTrackingStrategy(ActivityViewTrackingStrategy(true))
.build()
import com.datadog.android.rum.RumConfiguration;
import com.datadog.android.rum.tracking.ActivityViewTrackingStrategy;
RumConfiguration rumConfig = new RumConfiguration.Builder(applicationId)
.useViewTrackingStrategy(new ActivityViewTrackingStrategy(true))
.build();
| 策略 | 参数 | 描述 | 适用场景 |
|---|
ActivityViewTrackingStrategy | trackExtras | 追踪每个 Activity 为一个单独的视图 | 传统 Activity 架构 |
FragmentViewTrackingStrategy | trackArguments | 追踪每个 Fragment 为一个单独的视图 | Fragment 为主的应用 |
MixedViewTrackingStrategy | trackExtras, trackArguments | 同时追踪 Activity 和 Fragment | 混合架构应用 |
NavigationViewTrackingStrategy | navigationViewId | 追踪 Navigation 组件的目的地 | 使用 Jetpack Navigation |
自动追踪网络请求
要自动追踪 HTTP 网络请求,请参考 SDK 接入指南 中的 OkHttp 拦截器配置。
自动追踪 Apollo GraphQL 请求
如果您使用 Apollo GraphQL 客户端进行网络调用,可以启用自动追踪。
添加 Apollo 依赖
在应用的 build.gradle 文件中添加依赖:dependencies {
implementation "cloud.flashcat:dd-sdk-android-apollo:<latest-version>"
}
配置 Apollo Client
import com.apollographql.apollo.ApolloClient
import com.apollographql.apollo.network.okHttpClient
import com.datadog.android.apollo.DatadogApolloInterceptor
val apolloClient = ApolloClient.Builder()
.serverUrl("GraphQL endpoint")
.addInterceptor(DatadogApolloInterceptor())
.okHttpClient(okHttpClient)
.build()
import com.apollographql.apollo.ApolloClient;
import com.datadog.android.apollo.DatadogApolloInterceptor;
ApolloClient apolloClient = new ApolloClient.Builder()
.serverUrl("GraphQL endpoint")
.addInterceptor(new DatadogApolloInterceptor())
.okHttpClient(okHttpClient)
.build();
Flashduty 追踪头将自动添加到您的 GraphQL 请求中,使其能够被追踪。
限制说明:
- 仅支持 Apollo 版本 4
- 仅追踪
query 和 mutation 类型的操作,不追踪 subscription 操作
启用 GraphQL Payload 发送(可选):
DatadogApolloInterceptor(sendGraphQLPayloads = true)
new DatadogApolloInterceptor(true)
自动追踪长任务
在主线程上执行的长时间运行的操作可能会影响应用的视觉性能和响应性。SDK 可以自动检测并追踪长任务。
import com.datadog.android.rum.RumConfiguration
// 使用默认阈值(100ms)
val rumConfig = RumConfiguration.Builder(applicationId)
.trackLongTasks(durationThreshold)
.build()
// 自定义阈值(250ms)
val rumConfig = RumConfiguration.Builder(applicationId)
.trackLongTasks(250L)
.build()
import com.datadog.android.rum.RumConfiguration;
// 使用默认阈值(100ms)
RumConfiguration rumConfig = new RumConfiguration.Builder(applicationId)
.trackLongTasks(durationThreshold)
.build();
// 自定义阈值(250ms)
RumConfiguration rumConfig = new RumConfiguration.Builder(applicationId)
.trackLongTasks(250L)
.build();
默认阈值为 100ms。您可以根据应用性能要求调整此阈值。
修改或丢弃 RUM 事件
要在批量处理之前修改 RUM 事件的某些属性,或完全丢弃某些事件,请在初始化时提供 EventMapper<T> 的实现。
import com.datadog.android.rum.RumConfiguration
val rumConfig = RumConfiguration.Builder(applicationId)
.setErrorEventMapper(rumErrorEventMapper)
.setActionEventMapper(rumActionEventMapper)
.setResourceEventMapper(rumResourceEventMapper)
.setViewEventMapper(rumViewEventMapper)
.setLongTaskEventMapper(rumLongTaskEventMapper)
.build()
import com.datadog.android.rum.RumConfiguration;
RumConfiguration rumConfig = new RumConfiguration.Builder(applicationId)
.setErrorEventMapper(rumErrorEventMapper)
.setActionEventMapper(rumActionEventMapper)
.setResourceEventMapper(rumResourceEventMapper)
.setViewEventMapper(rumViewEventMapper)
.setLongTaskEventMapper(rumLongTaskEventMapper)
.build();
可修改的事件属性
当实现 EventMapper<T> 接口时,每种事件类型只有部分属性可以修改:
| 属性键 | 描述 |
|---|
view.referrer | 链接到页面初始视图的 URL |
view.url | 视图的 URL |
view.name | 视图的名称 |
| 属性键 | 描述 |
|---|
action.target.name | 目标名称 |
view.referrer | 链接到页面初始视图的 URL |
view.url | 视图的 URL |
view.name | 视图的名称 |
| 属性键 | 描述 |
|---|
error.message | 错误消息 |
error.stack | 错误的堆栈跟踪 |
error.resource.url | 资源的 URL |
view.referrer | 链接到页面初始视图的 URL |
view.url | 视图的 URL |
view.name | 视图的名称 |
| 属性键 | 描述 |
|---|
resource.url | 资源的 URL |
view.referrer | 链接到页面初始视图的 URL |
view.url | 视图的 URL |
view.name | 视图的名称 |
| 属性键 | 描述 |
|---|
view.referrer | 链接到页面初始视图的 URL |
view.url | 视图的 URL |
view.name | 视图的名称 |
如果从 EventMapper<T> 实现中返回 null,则事件将被丢弃,不会发送到 Flashduty。
示例:丢弃敏感错误
val rumConfig = RumConfiguration.Builder(applicationId)
.setErrorEventMapper { errorEvent ->
if (errorEvent.error.message?.contains("sensitive_data") == true) {
null // 丢弃包含敏感数据的错误
} else {
errorEvent
}
}
.build()
RumConfiguration rumConfig = new RumConfiguration.Builder(applicationId)
.setErrorEventMapper(errorEvent -> {
if (errorEvent.error.message != null &&
errorEvent.error.message.contains("sensitive_data")) {
return null; // 丢弃包含敏感数据的错误
} else {
return errorEvent;
}
})
.build();
获取 RUM Session ID
检索 RUM Session ID 对于故障排查很有帮助。您可以将 Session ID 附加到支持请求、电子邮件或错误报告中,以便支持团队在 Flashduty 中找到用户会话。
import com.datadog.android.rum.GlobalRumMonitor
GlobalRumMonitor.get().getCurrentSessionId { sessionId ->
currentSessionId = sessionId
}
import com.datadog.android.rum.GlobalRumMonitor;
GlobalRumMonitor.get().getCurrentSessionId(sessionId -> {
currentSessionId = sessionId;
});
您可以在运行时访问 RUM Session ID,而无需等待 sessionStarted 事件。
采样控制
默认情况下,RUM 会收集所有会话的数据。您可以通过 sessionSampleRate 参数设置采样率来减少收集的会话数量。
import com.datadog.android.rum.RumConfiguration
val rumConfig = RumConfiguration.Builder(applicationId)
.setSessionSampleRate(90.0f) // 采集 90% 的会话
.build()
import com.datadog.android.rum.RumConfiguration;
RumConfiguration rumConfig = new RumConfiguration.Builder(applicationId)
.setSessionSampleRate(90.0f) // 采集 90% 的会话
.build();
采样率范围:0.0 - 100.0
100.0 - 收集所有会话(默认)
50.0 - 收集 50% 的会话
0.0 - 不收集任何会话
被采样丢弃的会话将不收集任何页面视图及其相关遥测数据。
用户跟踪同意
为遵守 GDPR、CCPA 等隐私法规,RUM 允许在初始化时设置用户跟踪同意状态。
同意状态说明
| 状态 | 行为 | 使用场景 |
|---|
TrackingConsent.GRANTED | 开始收集数据并发送到 Flashduty | 用户已同意数据收集 |
TrackingConsent.NOT_GRANTED | 不收集任何数据 | 用户拒绝数据收集 |
TrackingConsent.PENDING | 收集数据但不发送 | 等待用户确认 |
如果初始化时使用 TrackingConsent.PENDING,SDK 将开始收集数据,但在同意状态更改为 GRANTED 之前不会发送。
更改同意状态
您可以通过 setTrackingConsent API 在初始化后更改同意状态:
import com.datadog.android.Datadog
import com.datadog.android.privacy.TrackingConsent
Datadog.setTrackingConsent(TrackingConsent.GRANTED)
import com.datadog.android.Datadog;
import com.datadog.android.privacy.TrackingConsent;
Datadog.setTrackingConsent(TrackingConsent.GRANTED);
最佳实践
- 确保在适当的生命周期方法中调用
startView 和 stopView,避免视图重复追踪
- 为每个视图使用唯一的
viewKey
- 使用自定义资源追踪时,确保每个
startResource 都有对应的 stopResource 或 stopResourceWithError 调用
- 避免追踪内部资源或过于频繁的请求
- 修改事件时,只有表格中列出的属性可以修改,其他属性的修改将被忽略
- 返回
null 可丢弃整个事件
- 合理设置采样率和批量上传频率,平衡数据量与性能开销
- 避免在事件回调中执行耗时操作
相关文档