crash - 框架中的崩溃分析工具
问题描述
我的团队正在开发一个供客户使用的 iOS 框架,当我们希望在我们的框架中拥有某种崩溃报告工具(例如 Crashlytics、KSCrash 等)以便我们可以追踪崩溃时,我们遇到了瓶颈当客户在他们的应用程序中使用我们的框架时。
但是,问题是如果(框架和客户端)都使用相同的崩溃报告工具,这些第 3 方崩溃报告工具似乎不起作用。例如,如果我们的框架和客户端应用程序都依赖 Crashlytics 来报告崩溃,那么由于 API 受限,它就无法工作。大多数其他开源项目几乎一直使用sharedInstance
初始化类。所以,这也行不通。
我的问题是......我确信那里有公司和软件使用某种崩溃报告工具来分析他们自己的框架上的崩溃,他们分发给许多客户。这是怎么做到的?有什么见解吗?
解决方案
我是 Apple 平台的 Crashlytics SDK 的前维护者。过去,一些非常受欢迎的框架供应商曾多次问过我这个问题。而且,我在这些领域投入了大量工作——报告工具互操作性和非主机应用报告。
我想更详细地说明为什么这如此困难。
问题 1:崩溃本质上是每个进程的
到目前为止,您注意到的问题与报告框架的 API 有关,但问题更深层次。崩溃会导致整个过程中断。iOS(macOS、tvOS)上存在的设施不能在每个库的基础上应用。(我相信有些可以是每线程的,但我不确定这实际上会给你带来什么。)
这就是为什么互操作性(即使与 Apple 自己的 ReportCrash)如此具有挑战性的核心原因。进程内报告工具设置它们的机器,然后期望它们的设置在实际发生崩溃时保持不变。这种机器的两个副本(即两个 Crashlytics)没有意义。只能有一个,因为正在使用的资源仅存在于每个进程的基础上。
通常,报告工具需要在可能的最佳报告和可能的最佳互操作性之间进行权衡。例如,如果我没记错的话,如果您在同一进程中同时使用 Crashlytics 和 KSCrash,Crashlytics 正确捕获有关 C++ 异常信息的能力就会受到影响。
问题 2:谁拥有崩溃?
忽略问题1,记者怎么知道崩溃是库VS应用?这是一个广泛的话题,基本上可以归结为崩溃责任的核心问题。崩溃是一种效果,但大多数开发人员不会立即以这种方式想到崩溃。当你想修复崩溃时,你需要一个原因。确定图书馆是原因并不容易。在您认为“它不应该只是让我的库框架崩溃吗?”之前,想象一下它是如何为 UIKit 或 Foundation 工作的。
有很多方法可以解决这个问题。然而,这里没有太多离题,我相信崩溃总是由主机应用程序拥有,但第三方也可能会感兴趣。这带来了一系列其他问题,包括验证库所有者和处理主机应用程序的隐私/安全问题。这是一整件事。
无论您如何处理,我认为解决方案只能在服务器端使用报告服务完成。理论上,他们可以抓取报告并进行分析。Crashlytics 的 Insights系统是朝这个方向迈出的一步。但是,它目前不向图书馆供应商提供查看这些报告的能力。它的重点更多地是将崩溃(影响)与众所周知的原因(或原因类别)联系起来。
概括
尝试使您的库尽可能稳定是一个很好的目标。不幸的是,我只是不认为可以通过专门的进程内报告来完成。
您实际上应该做的是帮助您的客户开发人员更好地了解您的库在做什么。因此,当它确实崩溃时,可以更轻松地调试并向您报告。
- 命名所有队列/线程
- 包括某种记录工具
- 积极检查有效参数/输入
- 使您从 API 传回的错误尽可能具有描述性和全面性
- 永远不要在生产中断言(我对主机应用程序的看法相反)
- 永远不要抛出 ObjC 和/或 C++ 异常
- 永远不要在你的代码中使用@catch/catch
- 查看
NSProcessInfo
API,这有助于更好地展示您的库在调试期间所做的事情
我希望这是有帮助的,即使它并没有真正让你到达你想要的地方。
推荐阅读
- for-loop - 在 for 循环中给出多个条件 - Groovy
- node.js - 如何使用 base64 图像发送 post 请求?
- python - NavigationLayout Kivy err0r
- swift - SwiftUI 小部件区域设置不适用
- date - 有没有办法从 x++ 中的日期中删除符号?
- bots.business - 如何向机器人业务 webhook 发送 ajax 请求?
- xslt - 在 n 个元素之后将一个输出文件拆分为多个 xml
- apache-spark - 为什么这个嵌套的“何时”在 pyspark 中不起作用?
- office-js - Office Js,`/hosted/office.debug.js`和`hosted/office.js`有什么不同
- python - 根据每列的唯一值剪切 Pandas 数据框