关于依赖和包名的说明Flashduty iOS SDK 完全兼容 Datadog 开源协议。在 Swift Package Manager 或 CocoaPods 中添加依赖时使用 FlashcatCore、FlashcatRUM 等名称,但在代码中 import 时使用 DatadogCore、DatadogRUM 等模块名。您可以无缝复用 Datadog 生态的文档、示例和最佳实践,同时享受 Flashduty 平台的服务。
Flashduty iOS RUM SDK 提供丰富的高级配置选项,帮助您根据业务需求定制数据收集和上下文信息。
支持的配置场景:
- 保护敏感数据 - 屏蔽个人身份信息等敏感数据
- 关联用户会话 - 将用户会话与内部用户标识关联
- 减少数据量 - 通过采样降低 RUM 数据收集量,优化成本
- 增强上下文 - 为数据添加自定义属性
丰富用户会话
自定义视图
默认情况下,RUM SDK 会自动追踪 UIViewController 或 SwiftUI View。您也可以手动追踪特定的视图或为自动追踪的视图添加自定义属性。
调用 RUMMonitor.shared().startView() 开始追踪新的 RUM 视图。同一 key 的所有视图将被分组在 RUM Explorer 中。
import DatadogRUM
// 在您的 UIViewController 中
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
RUMMonitor.shared().startView(
key: "view-key",
name: "View Name",
attributes: ["foo": "bar"]
)
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
RUMMonitor.shared().stopView(
key: "view-key",
attributes: ["foo": "bar"]
)
}
@import DatadogObjc;
// 在您的 UIViewController 中
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[[RUMMonitor shared] startViewWithKey:@"view-key"
name:@"View Name"
attributes:@{@"foo": @"bar"}];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[[RUMMonitor shared] stopViewWithKey:@"view-key"
attributes:@{@"foo": @"bar"}];
}
自定义操作
除了自动追踪用户操作外,您还可以手动追踪特定的自定义操作(如点击、滚动、滑动等)。
import DatadogRUM
// 在您的 UIViewController 中
@IBAction func didTapDownloadResourceButton(_ sender: UIButton) {
RUMMonitor.shared().addAction(
type: .tap,
name: sender.currentTitle ?? "",
attributes: ["resource_id": "123"]
)
}
@import DatadogObjc;
- (IBAction)didTapDownloadResourceButton:(UIButton *)sender {
[[RUMMonitor shared] addActionWithType:RUMActionTypeTap
name:sender.currentTitle
attributes:@{@"resource_id": @"123"}];
}
使用 addAction() 时,RUM SDK 会创建一个 RUM 操作,并将所有新的资源、错误和长任务附加到此操作,直到视图被视为已完成加载。
自定义资源
Flashduty iOS SDK 会自动追踪通过启用的 URLSession 发起的网络请求。您也可以手动追踪自定义资源(如第三方 API、GraphQL 查询等)。
import DatadogRUM
// 在您的网络客户端中
RUMMonitor.shared().startResource(
resourceKey: "resource-key",
request: request,
attributes: ["foo": "bar"]
)
// 加载成功时
RUMMonitor.shared().stopResource(
resourceKey: "resource-key",
response: response,
size: size,
attributes: ["foo": "bar"]
)
// 加载失败时
RUMMonitor.shared().stopResourceWithError(
resourceKey: "resource-key",
error: error,
attributes: ["foo": "bar"]
)
@import DatadogObjc;
// 在您的网络客户端中
[[RUMMonitor shared] startResourceWithResourceKey:@"resource-key"
request:request
attributes:@{@"foo": @"bar"}];
// 加载成功时
[[RUMMonitor shared] stopResourceWithResourceKey:@"resource-key"
response:response
size:size
attributes:@{@"foo": @"bar"}];
用于调用的 resourceKey 必须唯一,才能使 RUM iOS SDK 将资源的开始与其完成匹配。
自定义错误
要追踪特定错误,当错误发生时通知 RUMMonitor:
import DatadogRUM
RUMMonitor.shared().addError(
message: "Error message",
type: "ErrorType",
source: .source,
stack: "Error stack trace",
attributes: ["foo": "bar"],
file: #file,
line: #line
)
@import DatadogObjc;
[[RUMMonitor shared] addErrorWithMessage:@"Error message"
type:@"ErrorType"
source:DDRUMErrorSourceCustom
stack:@"Error stack trace"
attributes:@{@"foo": @"bar"}
file:file
line:line];
追踪自定义全局属性
iOS SDK 会自动捕获默认 RUM 属性。您还可以向 RUM 事件添加额外的上下文信息,例如自定义属性。
自定义属性的用途:
- 根据业务信息(如购物车价值、用户等级、广告活动)过滤和分组用户行为
- 跟踪特定用户群体的性能表现
- 了解不同用户群体的错误分布
设置自定义全局属性
import DatadogRUM
// 添加全局属性
RUMMonitor.shared().addAttribute(forKey: "user_plan", value: "premium")
// 删除全局属性
RUMMonitor.shared().removeAttribute(forKey: "user_plan")
@import DatadogObjc;
// 添加全局属性
[[RUMMonitor shared] addAttributeForKey:@"user_plan" value:@"premium"];
// 删除全局属性
[[RUMMonitor shared] removeAttributeForKey:@"user_plan"];
保留键名:
不能使用以下键名,因为它们被 SDK 内部使用:date、error.kind、error.message、error.stack、error.source_type、view.id、view.url、view.loading_time、view.referrer、application.id
追踪用户会话
为 RUM 会话添加用户信息,帮助您更好地了解用户行为和问题影响。
用户信息的用途:
- 跟踪特定用户的浏览路径
- 了解哪些用户受错误影响最大
- 监控关键用户的性能表现
import DatadogCore
Datadog.setUserInfo(
id: "1234",
name: "John Doe",
email: "john@doe.com",
extraInfo: [
"plan": "premium",
"signup_date": "2024-01-15"
]
)
@import DatadogObjc;
[DDDatadog setUserInfoWithId:@"1234"
name:@"John Doe"
email:@"john@doe.com"
extraInfo:@{@"plan": @"premium", @"signup_date": @"2024-01-15"}];
参数说明:
usr.id (字符串) - 唯一用户标识符
usr.name (字符串) - 用户友好名称,默认在 RUM UI 中显示
usr.email (字符串) - 用户电子邮件,若无名称则显示邮件
- 以上属性均为可选,建议至少提供一个
追踪后台事件
您可以追踪应用在后台运行时的事件(如崩溃和网络请求)。
import DatadogRUM
RUM.enable(
with: RUM.Configuration(
applicationID: "<RUM_APPLICATION_ID>",
trackBackgroundEvents: true
)
)
@import DatadogObjc;
DDRUMConfiguration *configuration = [[DDRUMConfiguration alloc]
initWithApplicationID:@"<RUM_APPLICATION_ID>"];
configuration.trackBackgroundEvents = YES;
[RUM enableWith:configuration];
追踪后台事件可能会产生额外的会话,从而影响计费。如有疑问,请联系 Flashduty 支持团队。
初始化参数
在创建 SDK 配置时,可以设置以下属性:
| 参数 | 类型 | 必填 | 说明 |
|---|
clientToken | String | ✅ | 客户端令牌 |
env | String | ✅ | 环境名称(如 production、staging) |
service | String | 可选 | 服务名称,默认为应用 bundle 标识符 |
batchSize | BatchSize | 可选 | 批量上传数据大小(.small、.medium、.large) |
uploadFrequency | UploadFrequency | 可选 | 数据上传频率(.frequent、.average、.rare) |
创建 RUM 配置时可以设置以下参数:| 参数 | 类型 | 必填 | 说明 |
|---|
applicationID | String | 是 | RUM 应用 ID |
sessionSampleRate | Float | 否 | 会话采样率 (0-100),默认 100 |
uiKitViewsPredicate | UIKitRUMViewsPredicate | 否 | UIKit 视图追踪策略 |
uiKitActionsPredicate | UIKitRUMActionsPredicate | 否 | UIKit 操作追踪策略 |
swiftUIViewsPredicate | SwiftUIRUMViewsPredicate | 否 | SwiftUI 视图追踪策略 |
swiftUIActionsPredicate | SwiftUIRUMActionsPredicate | 否 | SwiftUI 操作追踪策略 |
urlSessionTracking | URLSessionTracking | 否 | URLSession 网络请求追踪配置 |
trackBackgroundEvents | Bool | 可选 | 是否追踪后台事件,默认 false |
trackFrustrations | Bool | 可选 | 是否追踪用户挫败感(如错误点击),默认 true |
trackLongTasks | Bool | 可选 | 是否追踪长任务,默认 true |
| longTaskThreshold | TimeInterval | 否 | 长任务阈值(秒),默认 0.1 秒 |
| vitalsUpdateFrequency | VitalsFrequency | 否 | 性能指标更新频率,可选: .frequent, .average, .rare, .never |
自动追踪视图
要启用视图自动追踪,在初始化 RUM 时设置 uiKitViewsPredicate 或 swiftUIViewsPredicate。
对于 UIKit,使用 DefaultUIKitRUMViewsPredicate 类:
import DatadogRUM
RUM.enable(
with: RUM.Configuration(
applicationID: "<RUM_APPLICATION_ID>",
uiKitViewsPredicate: DefaultUIKitRUMViewsPredicate()
)
)
对于 SwiftUI,使用 DefaultSwiftUIRUMViewsPredicate 类:
import DatadogRUM
RUM.enable(
with: RUM.Configuration(
applicationID: "<RUM_APPLICATION_ID>",
swiftUIViewsPredicate: DefaultSwiftUIRUMViewsPredicate()
)
)
您还可以实现自定义的 predicate 来自定义追踪行为。
自动追踪用户操作
要启用用户操作自动追踪,在初始化 RUM 时设置 uiKitActionsPredicate 或 swiftUIActionsPredicate。
对于 UIKit:
import DatadogRUM
RUM.enable(
with: RUM.Configuration(
applicationID: "<RUM_APPLICATION_ID>",
uiKitActionsPredicate: DefaultUIKitRUMActionsPredicate()
)
)
对于 SwiftUI:
import DatadogRUM
RUM.enable(
with: RUM.Configuration(
applicationID: "<RUM_APPLICATION_ID>",
swiftUIActionsPredicate: DefaultSwiftUIRUMActionsPredicate(isLegacyDetectionEnabled: true)
)
)
自动追踪网络请求
要启用网络请求自动追踪(资源和错误),在初始化 RUM 时设置 urlSessionTracking 并启用 URLSessionInstrumentation:
import DatadogRUM
RUM.enable(
with: RUM.Configuration(
applicationID: "<RUM_APPLICATION_ID>",
urlSessionTracking: RUM.Configuration.URLSessionTracking()
)
)
URLSessionInstrumentation.enable(
with: .init(
delegateClass: SessionDelegate.self
)
)
您还可以配置 firstPartyHostsTracing 以启用分布式追踪,将 RUM 资源与后端 traces 关联:
import DatadogRUM
RUM.enable(
with: RUM.Configuration(
applicationID: "<RUM_APPLICATION_ID>",
urlSessionTracking: RUM.Configuration.URLSessionTracking(
firstPartyHostsTracing: .trace(hosts: ["example.com", "api.example.com"])
)
)
)
自动追踪错误
所有”致命”和”非致命”的 iOS 错误都会自动收集并附加当前 RUM 视图的完整错误详情和元数据。
致命错误包括应用崩溃。非致命错误包括:
- Swift errors: Swift
throw 的错误
- Objective-C exceptions: Objective-C 异常
您可以通过 RUM Explorer 和 Error Tracking 查看错误详情。
修改或丢弃 RUM 事件
在 RUM 事件发送到 Flashduty 之前,您可以通过事件映射器(Event Mappers)对其进行修改或完全丢弃。
事件映射器在创建 RUM 配置时设置:
import DatadogRUM
let configuration = RUM.Configuration(
applicationID: "<RUM_APPLICATION_ID>",
viewEventMapper: { RUMViewEvent in
return RUMViewEvent
},
errorEventMapper: { RUMErrorEvent in
return RUMErrorEvent
},
resourceEventMapper: { RUMResourceEvent in
return RUMResourceEvent
},
actionEventMapper: { RUMActionEvent in
return RUMActionEvent
},
longTaskEventMapper: { RUMLongTaskEvent in
return RUMLongTaskEvent
}
)
RUM.enable(with: configuration)
@import DatadogObjc;
DDRUMConfiguration *configuration = [[DDRUMConfiguration alloc] initWithApplicationID:@"<RUM_APPLICATION_ID>"];
[configuration setViewEventMapper:^DDRUMViewEvent * _Nonnull(DDRUMViewEvent * _Nonnull RUMViewEvent) {
return RUMViewEvent;
}];
[configuration setErrorEventMapper:^DDRUMErrorEvent * _Nullable(DDRUMErrorEvent * _Nonnull RUMErrorEvent) {
return RUMErrorEvent;
}];
[configuration setResourceEventMapper:^DDRUMResourceEvent * _Nullable(DDRUMResourceEvent * _Nonnull RUMResourceEvent) {
return RUMResourceEvent;
}];
[configuration setActionEventMapper:^DDRUMActionEvent * _Nullable(DDRUMActionEvent * _Nonnull RUMActionEvent) {
return RUMActionEvent;
}];
[configuration setLongTaskEventMapper:^DDRUMLongTaskEvent * _Nullable(DDRUMLongTaskEvent * _Nonnull RUMLongTaskEvent) {
return RUMLongTaskEvent;
}];
每个映射器都是一个签名为 (T) -> T? 的 Swift 闭包,其中 T 是具体的 RUM 事件类型。这允许在事件发送之前更改部分事件。
例如,要屏蔽 RUM Resource 的 url 中的敏感信息,实现一个自定义的 redacted(_:) -> String 函数并在 resourceEventMapper 中使用它:
let configuration = RUM.Configuration(
applicationID: "<RUM_APPLICATION_ID>",
resourceEventMapper: { RUMResourceEvent in
var RUMResourceEvent = RUMResourceEvent
RUMResourceEvent.resource.url = redacted(RUMResourceEvent.resource.url)
return RUMResourceEvent
}
)
DDRUMConfiguration *configuration = [[DDRUMConfiguration alloc] initWithApplicationID:@"<RUM_APPLICATION_ID>"];
[configuration setResourceEventMapper:^DDRUMResourceEvent * _Nullable(DDRUMResourceEvent * _Nonnull RUMResourceEvent) {
return RUMResourceEvent;
}];
从 error、resource 或 action 映射器返回 nil 将完全丢弃该事件;该事件不会发送到 Flashduty。从 view 事件映射器返回的值不能为 nil(要丢弃视图,请自定义 UIKitRUMViewsPredicate 的实现;详见追踪视图自动化)。
根据事件的类型,只有某些特定的属性可以被修改:
| 事件类型 | 属性键 | 说明 |
|---|
| RUMActionEvent | RUMActionEvent.action.target?.name | 操作名称 |
| RUMActionEvent.view.url | 与此操作关联的视图 URL |
| RUMErrorEvent | RUMErrorEvent.error.message | 错误消息 |
| RUMErrorEvent.error.stack | 错误堆栈跟踪 |
| RUMErrorEvent.error.resource?.url | 错误引用的资源 URL |
| RUMErrorEvent.view.url | 与此错误关联的视图 URL |
| RUMResourceEvent | RUMResourceEvent.resource.url | 资源 URL |
| RUMResourceEvent.view.url | 与此资源关联的视图 URL |
| RUMViewEvent | RUMViewEvent.view.name | 视图名称 |
| RUMViewEvent.view.url | 视图 URL |
| RUMViewEvent.view.referrer | 链接到页面初始视图的 URL |
获取 RUM 会话 ID
检索 RUM 会话 ID 对于故障排查非常有用。例如,您可以将会话 ID 附加到支持请求、电子邮件或错误报告中,以便您的支持团队稍后在 Flashduty 中找到用户会话。
您可以在运行时访问 RUM 会话 ID,无需等待 sessionStarted 事件:
import DatadogRUM
RUMMonitor.shared().currentSessionID(completion: { sessionId in
currentSessionId = sessionId
})
@import DatadogObjc;
[[RUMMonitor shared] currentSessionIDWithCompletion:^(NSString * _Nullable sessionId) {
// use session ID
}];
设置追踪同意(GDPR 合规)
为符合 GDPR 法规,Flashduty iOS SDK 在初始化时需要追踪同意值。
trackingConsent 设置可以是以下值之一:
.pending: Flashduty iOS SDK 开始收集和批处理数据,但不发送到 Flashduty。SDK 等待新的追踪同意值来决定如何处理批处理的数据。
.granted: Flashduty iOS SDK 开始收集数据并发送到 Flashduty。
.notGranted: iOS SDK 不收集任何数据。不会发送日志、traces 或 RUM 事件。
在 SDK 初始化后更改追踪同意值,请使用 Datadog.set(trackingConsent:) API 调用。SDK 会根据新值更改其行为。
例如,如果当前追踪同意是 .pending:
- 如果您将值更改为
.granted,SDK 将发送所有当前和未来的数据到 Flashduty;
- 如果您将值更改为
.notGranted,SDK 将清除所有当前数据并且不收集未来的数据。
import DatadogCore
Datadog.set(trackingConsent: .granted)
@import DatadogObjc;
[DDDatadog setWithTrackingConsent:DDTrackingConsentGranted];
添加用户属性
您可以使用 Datadog.addUserExtraInfo(_:) API 将额外的用户属性附加到先前设置的属性上。
import DatadogCore
Datadog.addUserExtraInfo(["company": "Flashduty"])
@import DatadogObjc;
[DDDatadog addUserExtraInfo:@{@"company": @"Flashduty"}];
数据管理
清除所有数据
您可以选择删除 SDK 存储的所有未发送数据,使用 Datadog.clearAllData() API:
import DatadogCore
Datadog.clearAllData()
@import DatadogObjc;
[DDDatadog clearAllData];
停止数据收集
您可以使用 Datadog.stopInstance() API 停止命名的 SDK 实例(如果名称为 nil 则停止默认实例)进一步收集和上传数据。
import DatadogCore
Datadog.stopInstance()
@import DatadogObjc;
[DDDatadog stopInstance];
调用此方法会禁用 SDK 和所有活跃的功能,如 RUM。要恢复数据收集,您必须重新初始化 SDK。如果您想动态更改配置,可以使用此 API。
默认情况下,RUM 会收集所有会话的数据。您可以通过 sessionSampleRate 参数设置采样率(百分比)来减少收集的会话数量。例如,采集 90% 的会话:
import DatadogRUM
RUM.enable(
with: RUM.Configuration(
applicationID: "<RUM_APPLICATION_ID>",
sessionSampleRate: 90
)
)
@import DatadogObjc;
DDRUMConfiguration *configuration = [[DDRUMConfiguration alloc] initWithApplicationID:@"<RUM_APPLICATION_ID>"];
configuration.sessionSampleRate = 90;
[RUM enableWith:configuration];
被采样的会话将不收集任何视图及其相关遥测数据。
集成 RUM 与分布式追踪
集成 RUM 与分布式追踪,可让您将 iOS 应用程序的请求与其对应的后端跟踪关联起来。这种组合让您能够一目了然地查看完整的前端和后端数据。
使用来自 RUM 的前端数据以及来自 trace ID 注入的后端、基础设施和日志信息来定位堆栈中任何地方的问题并了解用户的体验。
配置方法
初始化 RUM SDK,使用 firstPartyHostsTracing 来配置当前应用的 API 服务域名:
import DatadogRUM
RUM.enable(
with: RUM.Configuration(
applicationID: "<RUM_APPLICATION_ID>",
urlSessionTracking: RUM.Configuration.URLSessionTracking(
firstPartyHostsTracing: .trace(
hosts: [
"api.example.com",
"example.com"
],
sampleRate: 20
)
)
)
)
URLSessionInstrumentation.enable(
with: .init(
delegateClass: SessionDelegate.self
)
)
@import DatadogObjc;
DDRUMConfiguration *configuration = [[DDRUMConfiguration alloc] initWithApplicationID:@"<RUM_APPLICATION_ID>"];
DDURLSessionTracking *urlSessionTracking = [DDURLSessionTracking new];
[urlSessionTracking setFirstPartyHostsTracing:[DDRUMFirstPartyHostsTracing alloc] initWithHosts:@[@"api.example.com", @"example.com"] sampleRate:20];
configuration.urlSessionTracking = urlSessionTracking;
[RUM enableWith:configuration];
[DDURLSessionInstrumentation enableWithConfiguration:[DDURLSessionInstrumentationConfiguration alloc] initWithDelegateClass:[SessionDelegate class]]];
参数说明:
hosts: 需要追踪的域名列表
sampleRate: 要追踪的请求百分比(0-100),默认 100
如何关联
分布式追踪协议通过在 HTTP Header 上添加对应的头部字段(traceparent、tracestate)实现,以下是对相应 header 的说明:
traceparent: [version]-[trace id]-[parent id]-[trace flags]
version: 当前为 00
trace id: 128 bits 的 trace ID 通过 16 进制处理后变成 32 个字符
parent id: 64 bits 的 span ID,16 进制处理后为 16 个字符
trace flags: 代表是否有降采样,01 代表命中采样,00 代表非采样
tracestate: dd=s:[sampling priority];o:[origin]
sampling priority: 1 代表 trace 被采样
origin: 始终为 rum,代表通过 RUM SDK 采集
示例:
traceparent: 00-00000000000000008448eb211c80319c-b7ad6b7169203331-01
tracestate: dd=s:1;o:rum
如何验证
添加配置后,可在 Xcode 的网络调试工具或代理工具(如 Charles、Proxyman)中查看从应用中发送的请求,如能正确携带对应的 header 则说明配置无误。
最佳实践
确保正确配置 applicationID 和 clientToken,以避免数据上传失败。
根据应用需求调整采样率和隐私设置,平衡数据量与合规性。
事件映射器中修改的属性应遵循允许修改的属性列表,避免修改保留属性。
对于复杂的视图追踪场景,建议实现自定义的 ViewsPredicate。
相关文档