在 Crashlytics 中找出确切的崩溃时间

Find out exact crash time in Crashlytics

在我的应用程序中,我想找出上次会话发生任何崩溃的确切时间,通过 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);
    }];
}

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

来自 Crashlytics 的 Matt。

很遗憾,您发现了一个错误 :( 我已经注意到它,我会确保它得到关注。

我也很想知道您打算如何使用这些信息。就是一个use-case没听说过的

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

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

希望这对您有所帮助 - 并寻求我们的支持 forums/email 以获得进一步的帮助。堆栈溢出更难监控:)

更新:

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

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

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

但是,还有一个问题。如果设置了委托,并且实现了此方法,我们必须尊重 API 的约定,并询问委托是否可以在 之前 将报告入队发送。无论好坏,这个 API 也不会同步执行此操作。因此,当您实现此委托方法时,您将打开大量 window 时间,其中:

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

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

(就我个人而言,我发现这个 API 非常有问题,并希望将其删除。但是,我们需要保留它以向后兼容。没有实现新的 [=82= 确实是我的错] 不允许代表取消报告。这样的 API 不会延迟报告入队,并且可以避免所有这些问题。总有一天,我们会有那个,我们可以最后弃用这个。)

因此,为了改进 early-launch 崩溃处理,我建议如下:

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

唯一的例外应该是:

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

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