跟踪是一个灵活的工具,可以帮助确保良好的性能,验证您的用户流程并确定您的应用程序中的工作单元是否有效。
译自 5 User Flows to Trace in Your Mobile App,作者 David Rifkin。
在移动应用程序中,与微服务系统不同,跟踪可以在框架之间发生,也可以只在一个视图中发生。无论复杂程度如何,目标都是一样的:评估应用程序的性能及其对用户体验的影响。现代可观察性 需要计划好的努力,但为了获得洞察力,这项工作是值得的。
但是,你如何知道何时使用跟踪?
当你想跟踪应用程序生态系统中操作的持续时间时,你应该使用跟踪。考虑你将在移动应用程序中描述的任何过程:你可能想查看视图何时进入用户界面 (UI) 或用户是否完成了登录。跟踪过程中的各个步骤,可以让你了解它是否成功或失败,所涉及的步骤是否有效,或者它们是否容易出错或导致意外结果。
大多数跟踪框架 提供手动检测,以便你可以在需要的地方添加跟踪。这可能很令人生畏,因为它需要在你要查看的每个步骤中添加代码。一个好的经验法则是添加你认为需要的检测——对于最重要的步骤——然后在你分析收集到的遥测数据后,改进你的方法。
我将使用 Embrace 的 iOS 性能跟踪 检测来演示移动应用程序中的关键流程。Embrace 的跟踪检测位于OpenTelemetry 跟踪 之上,它允许使用诸如SpanEvents、属性 和父子Span关系 之类的概念。
Span 是跟踪的关键元素。Embrace 库使用一个特定的Span,即根Span,来确定跟踪的名称及其与其中其他元素的关系。一个简单的跟踪,其父进程为 A,子进程为 B,将像这样进行检测:
let parentSpan = Embrace.client?
.buildSpan(name: "Process A")
// .markAsKeySpan marks the root span and makes
// it a searchable key in the Embrace trace dashboard
.markAsKeySpan()
.startSpan()
[...things happen]
let childSpan = Embrace.client?
.buildSpan(name: "SubProcess B")
.setParent(parentSpan)
.startSpan()
[...]
childSpan.end()
[...]
parentSpan.end()
完成后,父子跟踪将在仪表板中显示如下:
父子关系由向下箭头符号(在上面图像左侧的“Span”下)表示,随着你为给定进程连接更多工作单元,它将不断增长。这种显式检测模式允许你在整个应用程序中添加Span和跟踪。此外,绿色条表示Span已成功完成。在你的检测中,你在结束Span时确定Span的成功与否;所有Span都必须结束。失败将在 Embrace 的仪表板中生成红色条。
让我们看一下构成一些常见流程的方面,以及在跟踪完成后它们在 Embrace 仪表板中的样子。
一个人可能会使用你的应用程序搜索新信息,浏览库存或只是查看朋友的社交媒体帐户。在任何这些情况下,他们都会执行实时文本搜索,并期望立即看到一组结果,他们可以浏览这些结果并可能进行选择。你可能会为在交互过程中键入的短语添加一些有用的缓存。
可以使用应用程序中搜索过程的跟踪来捕获这些实时交互:
请注意,你希望特定操作的Span名称保持一致,并避免出现嘈杂的仪表板体验。但是,使用Span属性,你可以为每个Span添加更多上下文。例如,如果你想查看请求是否因特定搜索短语而失败,你可以将该短语的文本作为每个 Network/Search Text Request Made
创建的Span的属性添加,然后在仪表板中分析该信息。
用户通常希望登录您的应用程序以确保其个人资料安全。但是,有很多方法可以登录,并且在身份验证过程中有很多点可能会失败。跟踪可能涉及诸如凭据缓存、登录请求、双因素身份验证甚至生物识别等单元。
在这个流程中,用户成功和技术成功之间的区别具有概念上的重要性。从用户的角度来看,缓存的凭据步骤和生物识别步骤没有成功登录。但是,应用程序的这些组件运行正常,因此即使它们没有导致“最佳”用户结果,Span也被标记为“成功”。
如果您在应用程序中销售商品,您的用户将希望能够结账!这对他们来说很直观,但对您来说,完成销售需要很多步骤:他们需要添加商品,您需要检查商品是否有库存,您需要支付信息,您需要确保支付完成并且用户收到成功购买的通知。
请注意,我在这里标记了跟踪中每个部分所包含的广泛功能。在跨多个微服务的分布式跟踪中,Span的名称描述了其操作的来源服务。在像移动应用程序这样的单体软件中,采用类似的命名系统可能会将开发人员引导到正确的文件或库,以便在评估性能或调试问题时进行查看。
如果您使用设备级别的权限(例如位置)来执行用户操作,您可能需要在应用程序 UI 的各个点请求这些权限。由于这些操作完全在设备上进行,因此您可能不必担心应用程序与外部服务的交互。但是,由于您可能需要在应用程序体验的各个点访问位置,因此这些操作具有在许多地方被调用的额外风险。
最后,我将介绍跟踪网络请求的重要性。您的应用程序是通过其运行的移动设备与网络服务交互的软件,用于发送和接收关键信息和媒体。移动应用程序性能低下 的一些最常见原因源于不一致或不可靠的网络。
网络与我迄今为止介绍的每个跟踪场景都相关,因为大多数用户流程都使用外部服务来完成操作。网络功能可以完全是现成的,也可以是自定义构建的,甚至可以通过 Alamofire 等第三方库运行。
无论如何,您可能希望深入研究支持您的网络的代码,因为问题的根本原因可能是请求过程中各种设备、应用程序或用户因素——添加标头、查找工作服务、以正确的格式和有效负载大小接收数据或反序列化问题。
正如您从这些跟踪示例中看到的那样,在许多步骤中,您可能希望使用子Span进行更深入的挖掘。您可能不希望复制上面的跟踪,因为在更细粒度的级别上还有许多更小的子单元需要跟踪。根据应用程序的构建方式,您可能希望为流程的每个步骤构建单独的跟踪,而不是创建一个包含许多子项的单个大型跟踪。
跟踪允许您深入了解影响用户体验的细节,您可以根据代码的检测程度进行深入了解。能够将用户活动或应用程序性能的跟踪聚合到指标中,然后将滞后的指标回溯到用户活动,意味着您已经开始将遥测编织成用户体验的完整画面。
如果您存在可见性差距,请考虑在关键用户流程中检测一些跟踪作为起点。如果您有任何问题或想了解更多关于移动应用程序中跟踪的信息,您可以加入Embrace Slack 社区。此外,请查看Embrace 网站,了解如何提供最佳的用户体验。