【问题标题】:Find out exact crash time in Crashlytics在 Crashlytics 中找出确切的崩溃时间
【发布时间】:2017-04-19 22:33:42
【问题描述】:

在我的应用程序中,我想找出之前会话中任何崩溃的确切时间,通过 Crashlytics 报告。我这样设置Crashlytics

- (void) setUpCrashlytics
{
    [[Fabric sharedSDK] setDebug:YES];
    [CrashlyticsKit setDebugMode:YES];
    [CrashlyticsKit setDelegate:self];
    [Fabric with:@[[Crashlytics class]]];
}

我正在模拟应用程序崩溃,在应用程序启动几分钟后按下按钮:

[CrashlyticsKit crash];

我尝试使用CrashlyticsDelegate 获取上次会话崩溃时间:

#pragma mark - CrashlyticsDelegate Methods
- (void) crashlyticsDidDetectReportForLastExecution:(CLSReport *) report completionHandler:(void (^)(BOOL)) completionHandler
{
    BOOL isCrash = report.isCrash; //this is TRUE

    NSDate *crashDate = report.crashedOnDate;
    NSDate *reportCreation = report.dateCreated;

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        completionHandler(YES);
    }];
}

但不幸的是,两个日期都显示的不是崩溃时间,而是上次会话启动时间。有任何想法吗?谢谢。

【问题讨论】:

  • 你检查过isCrash 是真的吗?有回溯吗?还会为所谓的“内存不足”错误生成报告。 “所谓”是因为我不相信 Crashlytics 能 100% 准确地检测到这些(检测起来很困难)。某些类型的后台终止(尤其是后台 OoM)永远不会让程序运行代码,因此 Crashlytics 无法存储崩溃时间。通过故意强制崩溃来测试这一点,看看 crashedOnDate 是否符合您的期望。
  • 此处来自 Crashlytics 的 Matt - 我们不会通过此机制检测 iOS 上的 OOM。因此,在内存不足终止后将永远不会调用此回调。你是对的,他们很难做到。我们是这样做的:docs.fabric.io/apple/crashlytics/OOMs.html

标签: ios objective-c crashlytics twitter-fabric


【解决方案1】:

来自 Crashlytics 的 Matt。

不幸的是,你发现了一个错误:(我已经注意到它,我会确保它被查看。

我也很想知道您打算如何使用这些信息。这只是一个我以前从未听说过的用例。

另外,请记住,特定的委托回调是有问题的。正如我们在头文件中指出的那样,该方法的 API 要求我们牺牲一些可靠性特性。我建议避免使用它,因为没有它我们成功报告崩溃的能力要好得多。是的,我们确实计划添加一个新的只读 API 来避免这种折衷。目前,我只会在您有无法以其他方式满足的非常紧迫的需求时推荐它。

此外,由于它是在 cmets 中提出的 - 此 API 将永远不会被调用用于内存不足的终止。这些在技术上不是崩溃,也不是这样报告的。我们使用的机制完全不同,并在我们的文档中进行了概述:https://docs.fabric.io/apple/crashlytics/OOMs.html。我们使用启发式方法,并且不是(也没有声称是)100% 可靠的。不过还是不错的。

希望这对您有所帮助 - 并访问我们的支持论坛/电子邮件以获取更多帮助。堆栈溢出更难监控:)

更新:

我认为这里有更多有用的信息,现在我了解了 Radu 想要实现的目标。结果就是使用这个委托方法不能达到他想要的效果,实际上只会让情况变得更糟。

在初始化 Crashlytics 的那一刻(在 -[Fabric with:] 调用期间),SDK 准备并将磁盘上的任何崩溃排入NSURLSession 的后台上传工具。我们这样做是因为我们想确保我们的上传过程不会被另一个崩溃中断。据我所知,这是我们实现的独特功能,我们已经使用了多年,而且效果非常好。 Crashlytics 基本上不会报告后续启动时崩溃导致的失败。

现在,为了确保这项工作尽可能顺利,我们必须在发布期间同步完成这项工作。因此,如果您在后台线程上启动 Crashlytics/Fabric,或者在初始化 SDK 的同时进行后台工作,则会影响我们在可能发生另一次潜在崩溃之前可靠地完成此过程的能力。

但是,还有另一个问题。如果设置了委托,并实现了此方法,我们必须尊重 API 的合同,并询问委托我们是否可以在发送报告之前将报告排入队列。无论好坏,此 API 也不会同步执行此操作。所以,当你实现这个委托方法时,你打开了一个很大的时间窗口:

  • Crashlytics 不会发送报告,因为它正在等待您的许可
  • 再次崩溃可能会导致未决报告丢失

在调用委托和调用回调之间的这段时间内,您不会有更多时间来发送报告。您只是在 SDK 知道您已允许我们发送它们之前添加延迟。

(我个人觉得这个 API 很成问题,想删除它。但是,为了向后兼容,我们需要保留它。没有实现不允许委托取消的新 API 确实是我的错报告。这样的 API 不会延迟报告队列,并且可以避免所有这些问题。总有一天,我们会拥有它,我们最终可以弃用它。)

因此,为了改进早期启动崩溃处理,我建议如下:

  • 切勿在后台线程上初始化 Crashlytics
  • 确保在启动时尽早初始化 Crashlytics,最好是您的应用程序做的第一件事
  • 永远不要使用这个委托方法

唯一的例外应该是:

  • 您正在尝试实现一个面向用户的崩溃报告权限对话框(它正是为这个用例而设计的)
  • 想要清除可能导致崩溃的敏感缓存数据
  • 拥有其他一些分析机制并且您想要计算崩溃次数

我还建议再次联系我们的支持人员。丢失的崩溃很常见。由 SDK 问题导致的丢失崩溃并不常见,并且会受到监控,我们有大量的 SDK 端和后端代码来理解和最小化它们。

【讨论】:

  • 出现了几次,应用刚启动就崩溃了,Crashlytics没有成功发送崩溃报告,因为它被终止得太早了。这就是我使用该委托方法的原因,我将在其中显示并警告几秒钟,以便将报告发送到服务器。此外,我只想过滤启动崩溃,这就是为什么我需要崩溃时间,以仅检测那些在启动时间后一秒钟内发生的崩溃。希望我清楚我要实现的目标。
  • 伟大的建议马特。我会跟着他们。谢谢。
猜你喜欢
  • 2019-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多