SDK API 参考
KMonitor SDK 的公共 API 参考,以及 Android 和 iOS 的每个平台代码示例。
初始化 SDK
在调用任何其他方法之前,先通过 init 初始化 SDK。请在应用启动时尽早调用它,以便从一开始就捕获崩溃、错误和事件。
import sh.measure.android.Measure
import sh.measure.android.config.ClientInfo
import sh.measure.android.config.MeasureConfig
Measure.init(
this,
MeasureConfig(),
ClientInfo(apiKey = "YOUR_API_KEY", apiUrl = "YOUR_API_URL"),
)import Measure
let clientInfo = ClientInfo(apiKey: "<apiKey>", apiUrl: "<apiUrl>")
Measure.initialize(with: clientInfo, config: BaseMeasureConfig())SDK 配置选项
将配置对象传递给init自定义 SDK。可用选项因平台而异。
| 选项 | 类型 | 默认 | 描述 |
|---|---|---|---|
enableLogging | Boolean | false | 打开内部 SDK 日志。 |
autoStart | Boolean | true | 在 init 上自动开始跟踪。设置为false延迟开始收集。 |
maxDiskUsageInMb | Int | 50 | 限制用于缓冲数据的磁盘空间。夹在中间20MB和1500MB. |
trackActivityIntentData | Boolean | false | 捕获用于启动活动的意图数据。 |
requestHeadersProvider | MsrRequestHeadersProvider? | null | 添加自定义 HTTP 标头以请求 SDK 发送到 KMonitor API,这对于自托管设置很有用。 |
enableFullCollectionMode | Boolean | false | 覆盖所有采样并收集每个事件和跟踪。增加成本,因此仅将其用于调试。 |
enableDiagnosticMode | Boolean | false | 将所有 SDK 日志写入您可以在报告 SDK bug 时附加的文件。 |
| 选项 | 类型 | 默认 | 描述 |
|---|---|---|---|
enableLogging | Bool | false | 打开内部 SDK 日志。 |
autoStart | Bool | true | init 后自动开始采集。设置为 false 可延后启动采集。 |
maxDiskUsageInMb | Int | 50 | 限制用于缓存数据的磁盘空间,范围为 20MB 到 1500MB。 |
requestHeadersProvider | MsrRequestHeadersProvider? | nil | 为 SDK 发往 KMonitor API 的请求添加自定义 HTTP Header,常用于自托管部署。 |
enableFullCollectionMode | Bool | false | 覆盖所有采样设置,采集每个事件和 Trace。会增加成本,仅建议调试时使用。 |
enableDiagnosticMode | Bool | false | 将所有 SDK 日志写入您可以在报告 SDK bug 时附加的文件。 |
enableDiagnosticModeGesture | Bool | false | 使用两指双击共享表导出 SDK 日志。需要enableDiagnosticMode. |
开始追踪
SDK 开始自动收集数据init。如果你设置autoStart到false在配置中,调用start当您准备好开始跟踪时。
import sh.measure.android.Measure
Measure.start()import Measure
Measure.start()停止追踪
暂停数据收集stop。停止时,SDK 不会收集任何数据。称呼start恢复。
import sh.measure.android.Measure
Measure.stop()import Measure
Measure.stop()跟踪错误
您可以报告已发现并恢复的错误。这些错误不会导致应用崩溃,但通常表示存在值得修复的问题。崩溃和 ANR 会自动捕获,因此无需手动记录它们。
跟踪已处理的错误
import sh.measure.android.Measure
try {
methodThatThrows()
} catch (e: Exception) {
Measure.trackHandledException(e)
}import Measure
// Track a Swift Error or an NSError with trackError
do {
try someThrowingFunction()
} catch {
Measure.trackError(error)
}添加属性
看属性限制对于允许的键和值。
import sh.measure.android.Measure
import sh.measure.android.attributes.AttributesBuilder
val attributes = AttributesBuilder().put("screen", "Login").build()
Measure.trackHandledException(e, attributes)import Measure
Measure.trackError(error, attributes: ["screen": .string("Login")])记录自定义事件
使用 trackEvent 记录应用特有的事件,例如用户操作或功能使用情况。
- 事件名称最多可包含 64 个字符。
- 事件名称只能包含字母、数字、连字符和下划线。
跟踪事件
import sh.measure.android.Measure
Measure.trackEvent("event_name")import Measure
Measure.trackEvent(name: "event_name", attributes: [:])设置自定义时间戳
记录特定时间(自纪元以来的毫秒数)的事件。使用getCurrentTime以获得准确的单调值。
import sh.measure.android.Measure
Measure.trackEvent("event_name", timestamp = Measure.getCurrentTime())import Measure
Measure.trackEvent(name: "event_name", attributes: [:], timestamp: Measure.getCurrentTime())添加属性
看属性限制对于允许的键和值。
import sh.measure.android.Measure
import sh.measure.android.attributes.AttributesBuilder
val attributes = AttributesBuilder().put("is_premium_user", true).build()
Measure.trackEvent("event_name", attributes = attributes)import Measure
Measure.trackEvent(name: "event_name", attributes: ["is_premium_user": .boolean(true)])跟踪屏幕视图
SDK自动跟踪屏幕视图来自每个平台的导航系统。通过自定义导航设置录制屏幕trackScreenView.
跟踪屏幕视图
import sh.measure.android.Measure
Measure.trackScreenView("Home")import Measure
Measure.trackScreenView("Home", attributes: nil)添加属性
看属性限制对于允许的键和值。
import sh.measure.android.Measure
import sh.measure.android.attributes.AttributesBuilder
val attributes = AttributesBuilder().put("source", "deep_link").build()
Measure.trackScreenView("Home", attributes)import Measure
Measure.trackScreenView("Home", attributes: ["source": .string("deep_link")])记录性能 Trace
KMonitor 可以记录任意操作在 Span 中花费的时间。一个 Span 代表一个工作单元;通过设置 parent 可以跟踪多步骤流程。
- Span 名称最多可包含 64 个字符。
- Span 名称不能为空。
开始一个 Span
通过 startSpan 立即开始一个 Span。
import sh.measure.android.Measure
val span = Measure.startSpan("span-name")import Measure
let span = Measure.startSpan(name: "span-name")从时间戳开始
对于已经开始的操作,可以传入 getCurrentTime 返回的开始时间来创建 Trace,避免设备时钟变化造成时间偏差。
import sh.measure.android.Measure
val span = Measure.startSpan("span-name", timestamp = Measure.getCurrentTime())import Measure
let span = Measure.startSpan(name: "span-name", timestamp: Measure.getCurrentTime())结束 Span
通过 end 结束 Span。结束前请先设置状态。
import sh.measure.android.Measure
import sh.measure.android.tracing.SpanStatus
val span = Measure.startSpan("span-name")
span.setStatus(SpanStatus.Ok).end()import Measure
let span = Measure.startSpan(name: "span-name")
span.setStatus(.ok).end()以时间戳结束
对于已经完成的 Span,可以传入 getCurrentTime 返回的结束时间来结束它。
import sh.measure.android.Measure
import sh.measure.android.tracing.SpanStatus
val span = Measure.startSpan("span-name")
span.setStatus(SpanStatus.Ok).end(timestamp = Measure.getCurrentTime())import Measure
let span = Measure.startSpan(name: "span-name")
span.setStatus(.ok).end(timestamp: Measure.getCurrentTime())设置状态
设置操作的结果setStatus。值为Ok, Error和Unset(默认)。
import sh.measure.android.Measure
import sh.measure.android.tracing.SpanStatus
val span = Measure.startSpan("span-name")
span.setStatus(SpanStatus.Ok)import Measure
let span = Measure.startSpan(name: "span-name")
span.setStatus(.ok)设置父级
通过 setParent 设置父 Span,构建操作层级。
import sh.measure.android.Measure
val parent = Measure.startSpan("parent-span")
val child = Measure.startSpan("child-span").setParent(parent)import Measure
let parent = Measure.startSpan(name: "parent-span")
let child = Measure.startSpan(name: "child-span").setParent(parent)添加属性
给 Span 添加键值上下文。可以一次添加一个属性,也可以通过 setAttributes 一次添加多个属性,或通过 removeAttribute 删除属性。允许的 key 和 value 请查看属性限制。
import sh.measure.android.Measure
import sh.measure.android.attributes.AttributesBuilder
val span = Measure.startSpan("span-name")
span.setAttribute("key", "value")
span.setAttribute("count", 10)
val attributes = AttributesBuilder().put("key", "value").put("count", 10).build()
span.setAttributes(attributes)
span.removeAttribute("key")import Measure
let span = Measure.startSpan(name: "span-name")
span.setAttribute("key", value: "value")
span.setAttribute("count", value: 10)
let attributes: [String: AttributeValue] = ["key": .string("value"), "count": .int(10)]
span.setAttributes(attributes)
span.removeAttribute("key")重命名 Span
在 Span 开头后更新其名称setName.
import sh.measure.android.Measure
val span = Measure.startSpan("span-name")
span.setName("updated-name")import Measure
let span = Measure.startSpan(name: "span-name")
span.setName("updated-name")添加检查点
通过 setCheckpoint 标记 Span 中的重要时刻。一个 Span 最多可以包含 100 个 checkpoint。
import sh.measure.android.Measure
val span = Measure.startSpan("span-name")
span.setCheckpoint("checkpoint-name")import Measure
let span = Measure.startSpan(name: "span-name")
span.setCheckpoint("checkpoint-name")延后启动 Span
通过 createSpanBuilder 先配置 Span,稍后再启动。
import sh.measure.android.Measure
val builder = Measure.createSpanBuilder("span-name")
val span = builder?.startSpan()import Measure
let builder = Measure.createSpanBuilder(name: "span-name")
let span = builder?.startSpan()分布式追踪
通过在出站请求中添加 W3C traceparent Header,在服务之间传播 Trace。使用 getTraceParentHeaderKey 获取 Header 名称,使用 getTraceParentHeaderValue 获取对应的 Span 值。
import sh.measure.android.Measure
val span = Measure.startSpan("http")
val key = Measure.getTraceParentHeaderKey()
val value = Measure.getTraceParentHeaderValue(span)import Measure
let span = Measure.startSpan(name: "http")
let key = Measure.getTraceParentHeaderKey()
let value = Measure.getTraceParentHeaderValue(span: span)跟踪 HTTP 事件
KMonitor 会自动跟踪 Android 上的 OkHttp 和 iOS 上的 URLSession。使用trackHttpEvent记录来自任何其他 HTTP 客户端的请求,并使用getCurrentTime开始和结束时间以避免时钟偏差。
import sh.measure.android.Measure
val startTime = Measure.getCurrentTime()
// make the request
val endTime = Measure.getCurrentTime()
Measure.trackHttpEvent(
url = "https://api.example.com/users",
method = "GET",
startTime = startTime,
endTime = endTime,
statusCode = 200,
)import Measure
let startTime = UInt64(Measure.getCurrentTime())
// make the request
let endTime = UInt64(Measure.getCurrentTime())
Measure.trackHttpEvent(
url: "https://api.example.com/users",
method: "GET",
startTime: startTime,
endTime: endTime,
statusCode: 200
)跟踪错误报告
让用户从应用内提交 Bug Report。通过一次调用打开 Bug Report UI,或从自己的 UI 使用 trackBugReport 提交报告。描述最多可包含 4000 个字符,最多可包含 5 个附件。可使用 captureScreenshot 附加屏幕截图,也可以通过摇动设备触发报告。
打开错误报告屏幕
import sh.measure.android.Measure
Measure.launchBugReportActivity(takeScreenshot = true)import Measure
Measure.launchBugReport(takeScreenshot: true)跟踪错误报告
构建自定义 Bug Report 流程并提交 trackBugReport。
import sh.measure.android.Measure
Measure.trackBugReport(description = "Cart items disappear after reopening the app")import Measure
Measure.trackBugReport(description: "Cart items disappear after reopening the app")添加属性
给报告附加元数据。打开 Bug Report UI 或从自己的 UI 提交报告时都可以传递属性。查看属性限制,了解允许的键和值。
import sh.measure.android.Measure
import sh.measure.android.attributes.AttributesBuilder
val attributes = AttributesBuilder().put("screen", "Cart").build()
Measure.launchBugReportActivity(takeScreenshot = true, attributes = attributes)
Measure.trackBugReport(description = "...", attributes = attributes)import Measure
let attributes: [String: AttributeValue] = ["screen": .string("Cart")]
Measure.launchBugReport(takeScreenshot: true, attributes: attributes)
Measure.trackBugReport(description: "...", attributes: attributes)摇一摇报告
注册 shake handler,让用户可以通过摇动设备打开 Bug Report。传递空 handler 可禁用。
import sh.measure.android.Measure
import sh.measure.android.bugreport.MsrShakeListener
Measure.setShakeListener(object : MsrShakeListener {
override fun onShake() {
Measure.launchBugReportActivity()
}
})import Measure
Measure.onShake {
Measure.launchBugReport()
}追踪日志
使用五个严重级别之一记录日志logDebug, logInfo, logWarning, logError或者logFatal。日志显示在会话时间线上并在调试时添加上下文。超过 1000 个字符的正文将被截断。
跟踪日志
import sh.measure.android.Measure
Measure.logDebug("Cache miss for key user_42")
Measure.logInfo("User signed in")
Measure.logWarning("Payment failed, retrying")
Measure.logError("Checkout request failed")
Measure.logFatal("Unrecoverable database error")import Measure
Measure.logDebug("Cache miss for key user_42")
Measure.logInfo("User signed in")
Measure.logWarning("Payment failed, retrying")
Measure.logError("Checkout request failed")
Measure.logFatal("Unrecoverable database error")添加属性
看属性限制对于允许的键和值。
import sh.measure.android.Measure
import sh.measure.android.attributes.AttributesBuilder
val attributes = AttributesBuilder().put("screen", "Checkout").build()
Measure.logWarning("Payment failed", attributes)import Measure
Measure.logWarning("Payment failed", attributes: ["screen": .string("Checkout")])识别用户
设置用户 ID,以便在调试时将会话与用户关联起来。该 ID 会在应用启动后保持存在;用户登出时请清除它。
避免在用户 ID 中包含个人身份信息 (PII),例如电子邮件或电话号码。请改用哈希值或匿名值。
import sh.measure.android.Measure
Measure.setUserId("user-id")
Measure.clearUserId()import Measure
Measure.setUserId("user-id")
Measure.clearUserId()获取会话ID
读取当前会话 ID 以将应用数据与 KMonitor 会话关联起来。退货null如果 SDK 未初始化。
import sh.measure.android.Measure
val sessionId: String? = Measure.getSessionId()import Measure
let sessionId: String? = Measure.getSessionId()获取当前时间
从单调时钟读取 epoch 时间(毫秒)。将它用于事件、Span 和 HTTP 时间戳,可以避免设备时钟偏差。
import sh.measure.android.Measure
val currentTime: Long = Measure.getCurrentTime()import Measure
let currentTime: Int64 = Measure.getCurrentTime()遮罩 SwiftUI 视图
默认情况下,截图会遮罩所有 SwiftUI 内容,不受遮罩级别影响,因为 SDK 无法单独检查 SwiftUI 视图。可以用 .msrUnmask() 显示不敏感视图;对于自动检测遗漏的视图,例如 List 外的独立 Text,可以用 .msrMask() 强制遮罩。
import Measure
VStack {
Text("Order confirmed")
.msrUnmask()
Text(cardNumber)
.msrMask()
}属性限制
属性是附加到事件、Span、日志、Bug Report、screen view 和错误上的键值对。它们在所有地方都遵循相同规则:
- 键是字符串,最多 256 个字符。
- 键只能包含字母、数字、连字符和下划线。
- 值为字符串、整数、长整型、双精度型、浮点型或布尔型。
- 字符串值最多可达 256 个字符。