跳转到主要内容
关于依赖和包名的说明Flashduty iOS SDK 完全兼容 Datadog 开源协议。在 Swift Package Manager 或 CocoaPods 中添加依赖时使用 FlashcatCoreFlashcatRUM 等名称,但在代码中 import 时使用 DatadogCoreDatadogRUM 等模块名。您可以无缝复用 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 DatadogRUM

// 在您的 UIViewController 中
@IBAction func didTapDownloadResourceButton(_ sender: UIButton) {
    RUMMonitor.shared().addAction(
        type: .tap,
        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"]
)
用于调用的 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
)
更多错误上报详情,请参阅 iOS 异常上报

追踪自定义全局属性

iOS SDK 会自动捕获默认 RUM 属性。您还可以向 RUM 事件添加额外的上下文信息,例如自定义属性。
自定义属性的用途:
  • 根据业务信息(如购物车价值、用户等级、广告活动)过滤和分组用户行为
  • 跟踪特定用户群体的性能表现
  • 了解不同用户群体的错误分布

设置自定义全局属性

import DatadogRUM

// 添加全局属性
RUMMonitor.shared().addAttribute(forKey: "user_plan", value: "premium")

// 删除全局属性
RUMMonitor.shared().removeAttribute(forKey: "user_plan")
保留键名:
不能使用以下键名,因为它们被 SDK 内部使用:dateerror.kinderror.messageerror.stackerror.source_typeview.idview.urlview.loading_timeview.referrerapplication.id

追踪用户会话

为 RUM 会话添加用户信息,帮助您更好地了解用户行为和问题影响。
用户信息的用途:
  • 跟踪特定用户的浏览路径
  • 了解哪些用户受错误影响最大
  • 监控关键用户的性能表现
import DatadogCore

Datadog.setUserInfo(
    id: "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
    )
)
追踪后台事件可能会产生额外的会话,从而影响计费。如有疑问,请联系 Flashduty 支持团队。

初始化参数

在创建 SDK 配置时,可以设置以下属性:
参数类型必填说明
clientTokenString客户端令牌
envString环境名称(如 productionstaging
serviceString可选服务名称,默认为应用 bundle 标识符
batchSizeBatchSize可选批量上传数据大小(.small.medium.large
uploadFrequencyUploadFrequency可选数据上传频率(.frequent.average.rare
创建 RUM 配置时可以设置以下参数:
参数类型必填说明
applicationIDStringRUM 应用 ID
sessionSampleRateFloat会话采样率 (0-100),默认 100
uiKitViewsPredicateUIKitRUMViewsPredicateUIKit 视图追踪策略
uiKitActionsPredicateUIKitRUMActionsPredicateUIKit 操作追踪策略
swiftUIViewsPredicateSwiftUIRUMViewsPredicateSwiftUI 视图追踪策略
swiftUIActionsPredicateSwiftUIRUMActionsPredicateSwiftUI 操作追踪策略
urlSessionTrackingURLSessionTrackingURLSession 网络请求追踪配置
trackBackgroundEventsBool可选是否追踪后台事件,默认 false
trackFrustrationsBool可选是否追踪用户挫败感(如错误点击),默认 true
trackLongTasksBool可选是否追踪长任务,默认 true
| longTaskThreshold | TimeInterval | 否 | 长任务阈值(秒),默认 0.1 秒 | | vitalsUpdateFrequency | VitalsFrequency | 否 | 性能指标更新频率,可选: .frequent, .average, .rare, .never |

自动追踪视图

要启用视图自动追踪,在初始化 RUM 时设置 uiKitViewsPredicateswiftUIViewsPredicate 对于 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 时设置 uiKitActionsPredicateswiftUIActionsPredicate 对于 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 的实现;详见追踪视图自动化)。 根据事件的类型,只有某些特定的属性可以被修改:
事件类型属性键说明
RUMActionEventRUMActionEvent.action.target?.name操作名称
RUMActionEvent.view.url与此操作关联的视图 URL
RUMErrorEventRUMErrorEvent.error.message错误消息
RUMErrorEvent.error.stack错误堆栈跟踪
RUMErrorEvent.error.resource?.url错误引用的资源 URL
RUMErrorEvent.view.url与此错误关联的视图 URL
RUMResourceEventRUMResourceEvent.resource.url资源 URL
RUMResourceEvent.view.url与此资源关联的视图 URL
RUMViewEventRUMViewEvent.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 设置可以是以下值之一:
  1. .pending: Flashduty iOS SDK 开始收集和批处理数据,但不发送到 Flashduty。SDK 等待新的追踪同意值来决定如何处理批处理的数据。
  2. .granted: Flashduty iOS SDK 开始收集数据并发送到 Flashduty。
  3. .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 上添加对应的头部字段(traceparenttracestate)实现,以下是对相应 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 则说明配置无误。

最佳实践

确保正确配置 applicationIDclientToken,以避免数据上传失败。
根据应用需求调整采样率和隐私设置,平衡数据量与合规性。
事件映射器中修改的属性应遵循允许修改的属性列表,避免修改保留属性。
对于复杂的视图追踪场景,建议实现自定义的 ViewsPredicate

相关文档