This guide contains instructions for the latest version of the Firebase Crashlytics SDK. If you migrated your app from Fabric, make sure it's been upgraded and no longer uses the deprecated legacy Fabric SDK.
Эта страница была переведа с помощью Cloud Translation API.
Switch to English

Настройте отчеты о сбоях Firebase Crashlytics

В этом руководстве описывается, как настроить отчеты о сбоях с помощью Firebase Crashlytics SDK. По умолчанию Crashlytics автоматически собирает отчеты о сбоях для всех пользователей вашего приложения (вместо этого вы можете отключить автоматические отчеты о сбоях и включить отчеты о сбоях для своих пользователей). Crashlytics предоставляет четыре механизма ведения журнала из коробки: настраиваемые ключи , настраиваемые журналы , идентификаторы пользователей и перехваченные исключения .

Добавить собственные ключи

Пользовательские ключи помогают узнать конкретное состояние вашего приложения, ведущее к сбою. Вы можете связать произвольные пары ключ / значение со своими отчетами о сбоях и просмотреть их в консоли Firebase .

Используйте метод setCustomValue для установки пар ключ / значение. Например:

Swift

// Set int_key to 100.
Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key")

// Set str_key to "hello".
Crashlytics.crashlytics().setCustomValue("hello", forKey: "str_key")

Цель-C

При установке целых, логических или чисел с плавающей запятой установите значение как @( value ) .

// Set int_key to 100.
[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"];

// Set str_key to "hello".
[[FIRCrashlytics crashlytics] setCustomValue:@"hello" forKey:@"str_key"];

Вы также можете изменить значение существующего ключа, вызвав ключ и установив для него другое значение. Например:

Swift

Crashlytics.crashlytics().setCustomValue(100, forKey: "int_key")

// Set int_key to 50 from 100.
Crashlytics.crashlytics().setCustomValue(50, forKey: "int_key")

Цель-C

[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"];

// Set int_key to 50 from 100.
[[FIRCrashlytics crashlytics] setCustomValue:@(50) forKey:@"int_key"];

Добавить собственные сообщения журнала

Чтобы дать себе больше информации о событиях, ведущих к сбою, вы можете добавить в свое приложение пользовательские журналы Crashlytics. Crashlytics связывает журналы с данными о сбоях и отображает их на странице Crashlytics в консоли Firebase на вкладке « Журналы ».

Swift

Используйте log() или log(format:, arguments:) чтобы выявить проблемы. Если вы хотите получить полезный вывод журнала с сообщениями, объект, который вы передаете в log() должен соответствовать CustomStringConvertible . log() возвращает свойство описания, которое вы определяете для объекта. Например:

Crashlytics.crashlytics().log("Higgs-Boson detected! Bailing out…, \(attributesDict)")

.log(format:, arguments:) форматирует значения, возвращаемые при вызове getVaList() . Например:

Crashlytics.crashlytics().log(format: "%@, %@", arguments: getVaList(["Higgs-Boson detected! Bailing out…", attributesDict]))

Дополнительные сведения об использовании log() или log(format:, arguments:) см. В справочной документации по функциям Crashlytics.

Цель-C

Используйте log или logWithFormat чтобы выявить проблемы. Обратите внимание, что если вы хотите получить полезный вывод журнала с сообщениями, объект, который вы передаете любому методу, должен переопределить свойство экземпляра description . Например:

[[FIRCrashlytics crashlytics] log:@"Simple string message"];

[[FIRCrashlytics crashlytics] logWithFormat:@"Higgs-Boson detected! Bailing out... %@", attributesDict];

[[FIRCrashlytics crashlytics] logWithFormat:@"Logging a variable argument list %@" arguments:va_list_arg];

Дополнительные сведения об использовании log и logWithFormat см. В справочной документации по функциям Crashlytics.

Установить идентификаторы пользователей

Чтобы диагностировать проблему, часто бывает полезно знать, у кого из ваших пользователей произошел сбой. Crashlytics включает способ анонимной идентификации пользователей в ваших отчетах о сбоях.

Чтобы добавить идентификаторы пользователей в отчеты, назначьте каждому пользователю уникальный идентификатор в виде идентификатора, токена или хешированного значения:

Swift
Crashlytics.crashlytics().setUserID("123456789")
Цель-C
[[FIRCrashlytics crashlytics] setUserID:@"123456789"];

Если вам когда-нибудь понадобится очистить идентификатор пользователя после его установки, сбросьте значение на пустую строку. Очистка идентификатора пользователя не удаляет существующие записи Crashlytics. Если вам нужно удалить записи, связанные с идентификатором пользователя, обратитесь в службу поддержки Firebase .

Сообщать о некритических исключениях

Помимо автоматического сообщения о сбоях вашего приложения, Crashlytics позволяет вам записывать нефатальные исключения и отправлять их вам при следующем запуске приложения.

Вы можете записывать нефатальные исключения, записывая объекты NSError с recordError метода recordError . recordError захватывает стек вызовов потока, вызывая [NSThread callStackReturnAddresses] .

Swift

Crashlytics.crashlytics().record(error: error)

Цель-C

[[FIRCrashlytics crashlytics] recordError:error];

При использовании метода recordError важно понимать структуру NSError и то, как Crashlytics использует данные для группировки сбоев. Неправильное использование метода recordError может вызвать непредсказуемое поведение и может привести к тому, что Crashlytics ограничит создание отчетов о зарегистрированных ошибках для вашего приложения.

У объекта NSError есть три аргумента:

  • domain: String
  • code: Int
  • userInfo: [AnyHashable : Any]? = nil

В отличие от фатальных сбоев, которые группируются с помощью анализа трассировки стека, зарегистрированные ошибки группируются по domain и code . Это важное различие между фатальными сбоями и зарегистрированными ошибками. Например:

Swift

let userInfo = [
  NSLocalizedDescriptionKey: NSLocalizedString("The request failed.", comment: ""),
  NSLocalizedFailureReasonErrorKey: NSLocalizedString("The response returned a 404.", comment: ""),
  NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString("Does this page exist?", comment: ""),
  "ProductID": "123456",
  "View": "MainView"
]

let error = NSError.init(domain: NSCocoaErrorDomain,
                         code: -1001,
                         userInfo: userInfo)

Цель-C

NSDictionary *userInfo = @{
  NSLocalizedDescriptionKey: NSLocalizedString(@"The request failed.", nil),
  NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"The response returned a 404.", nil),
  NSLocalizedRecoverySuggestionErrorKey: NSLocalizedString(@"Does this page exist?", nil),
  @"ProductID": @"123456",
  @"View": @"MainView",
};

NSError *error = [NSError errorWithDomain:NSCocoaErrorDomain
                                     code:-1001
                                 userInfo:userInfo];

Когда вы регистрируете ошибку выше, она создает новую проблему, которая сгруппирована по NSSomeErrorDomain и -1001 . Дополнительные зарегистрированные ошибки, использующие тот же домен и значения кода, сгруппированы по одной и той же проблеме. Данные, содержащиеся в объекте userInfo , преобразуются в пары ключ-значение и отображаются в разделе ключей / журналов отдельной проблемы.

Предупреждение. Избегайте использования уникальных значений, таких как идентификатор пользователя, идентификатор продукта и отметки времени, в полях домена и кода. Использование уникальных значений в этих полях приводит к большому количеству проблем и может привести к тому, что Crashlytics потребуется ограничить отчетность о зарегистрированных ошибках в вашем приложении. Вместо этого в userInfo словаря userInfo следует добавлять уникальные значения.

Журналы и пользовательские ключи

Как и в случае с отчетами о сбоях, вы можете встроить журналы и пользовательские ключи, чтобы добавить контекст к NSError . Однако есть разница в том, какие журналы прикрепляются к сбоям и какие ошибки регистрируются. Когда происходит сбой и приложение перезапускается, Crashlytics извлекает с диска журналы, которые были записаны непосредственно до сбоя. Когда вы регистрируете NSError , приложение не прекращает работу немедленно. Поскольку Crashlytics отправляет зарегистрированный отчет об ошибке только при следующем запуске приложения и должен ограничивать объем пространства, выделенного для журналов на диске, после регистрации NSError можно записать достаточно места, чтобы все соответствующие журналы были заменены на время отправки Crashlytics отчет с устройства. Помните об этом балансе при регистрации NSErrors и использовании журналов и пользовательских ключей в вашем приложении.

Соображения производительности

Имейте в виду, что регистрация NSError может быть довольно дорогой. В то время, когда вы делаете вызов, Crashlytics захватывает стек вызовов текущего потока, используя процесс, называемый раскручиванием стека. Этот процесс может быть интенсивным для ЦП и ввода-вывода, особенно на архитектурах, поддерживающих раскручивание DWARF (arm64 и x86). После завершения раскрутки информация синхронно записывается на диск. Это предотвращает потерю данных в случае сбоя следующей строки.

Хотя вызывать этот API в фоновом потоке безопасно, помните, что при отправке этого вызова в другую очередь теряется контекст текущей трассировки стека.

А как насчет NSExceptions?

Crashlytics не предлагает возможности для непосредственной регистрации и записи экземпляров NSException . Вообще говоря, API-интерфейсы Cocoa и Cocoa Touch не являются безопасными в отношении исключений. Это означает, что использование @catch может иметь очень серьезные непреднамеренные побочные эффекты в вашем процессе, даже при использовании с особой осторожностью. Вы никогда не должны использовать в своем коде операторы @catch . Пожалуйста, обратитесь к документации Apple по этой теме.

Настроить трассировку стека

Если ваше приложение работает в неродной среде (например, C ++ или Unity), вы можете использовать API модели исключений для сообщения метаданных сбоя в собственном формате исключений вашего приложения. Зарегистрированные исключения помечаются как нефатальные.

Swift

var  ex = ExceptionModel.init(name:"FooException", reason:"There was a foo.")
ex.stackTrace = [
  StackFrame.init(symbol:"makeError" fileName:"handler.js" lineNumber:495),
  StackFrame.init(symbol:"then" fileName:"routes.js" lineNumber:102),
  StackFrame.init(symbol:"main" fileName:"app.js" lineNumber:12),
]

crashlytics.record(exceptionModel:ex)

Цель-C

FIRExceptionModel *model =
    [FIRExceptionModel exceptionModelWithName:@"FooException" reason:@"There was a foo."];
model.stackTrace = @[
  [FIRStackFrame stackFrameWithSymbol:@"makeError" fileName:@"handler.js" lineNumber:495],
  [FIRStackFrame stackFrameWithSymbol:@"then" fileName:@"routes.js" lineNumber:102],
  [FIRStackFrame stackFrameWithSymbol:@"main" fileName:@"app.js" lineNumber:12],
];

Включить отчеты о подписке

По умолчанию Crashlytics автоматически собирает отчеты о сбоях для всех пользователей вашего приложения. Чтобы предоставить пользователям больший контроль над отправляемыми ими данными, вы можете включить для своих пользователей возможность отчетности, отключив автоматический сбор и инициализировав Crashlytics только для выбранных пользователей:

  1. Отключите автоматический сбор, добавив новый ключ в файл Info.plist :

    • Ключ: FirebaseCrashlyticsCollectionEnabled
    • Значение: false
  2. Включите сбор данных для избранных пользователей, вызвав переопределение сбора данных Crashlytics во время выполнения. Значение переопределения сохраняется при запуске вашего приложения, поэтому Crashlytics может автоматически собирать отчеты. Чтобы отказаться от автоматических отчетов о сбоях, передайте false в качестве значения переопределения. Если установлено значение false , новое значение не применяется до следующего запуска приложения.

    Swift
    Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)
    Цель-C
    [[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];

Управление данными Crash Insights

Crash Insights помогает решать проблемы, сравнивая анонимные трассировки стека с трассировками из других приложений Firebase и сообщая вам, является ли ваша проблема частью более широкой тенденции. Для многих проблем Crash Insights даже предоставляет ресурсы, которые помогут вам отладить сбой.

Crash Insights использует агрегированные данные о сбоях для определения общих тенденций стабильности. Если вы предпочитаете не делиться данными своего приложения, вы можете отказаться от Crash Insights в меню Crash Insights в верхней части списка проблем Crashlytics в консоли Firebase .