| Выберите платформу: | iOS+ Android Flutter Unity |
Нажмите на проблему, чтобы получить подробный отчет о событии на панели управления DevOps & Engagement > Crashlytics в консоли Firebase. Вы можете настроить эти отчеты, чтобы лучше понимать, что происходит в вашем приложении, и обстоятельства, связанные с событиями, которые передаются в Crashlytics.
Добавьте в приложение код, который будет регистрировать специальные ключи, специальные сообщения журнала и идентификаторы пользователей.
Сообщайте о исключениях в Crashlytics.
Автоматически получать журналы хлебных крошек, если в приложении используется Firebase SDK для Google Analytics. Эти журналы позволяют отслеживать действия пользователей, которые привели к событию, собранному Crashlytics в вашем приложении.
Отключите автоматическую отправку отчетов о сбоях и включите отправку отчетов по запросу для пользователей. Обратите внимание, что по умолчанию Crashlytics автоматически собирает отчеты о сбоях для всех пользователей вашего приложения.
Как добавить специальные ключи
Специальные ключи помогают получить информацию о состоянии приложения непосредственно перед сбоем. Вы можете связать с отчетами о сбоях произвольные пары "ключ-значение", а затем использовать специальные ключи для поиска и фильтрации отчетов на панели DevOps & Engagement > 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")
Objective-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")
Objective-C
[[FIRCrashlytics crashlytics] setCustomValue:@(100) forKey:@"int_key"]; // Set int_key to 50 from 100. [[FIRCrashlytics crashlytics] setCustomValue:@(50) forKey:@"int_key"];
Добавлять пары "ключ-значение" можно массово, используя метод setCustomKeysAndValues с NSDictionary в качестве единственного параметра:
Swift
let keysAndValues = [ "string key" : "string value", "string key 2" : "string value 2", "boolean key" : true, "boolean key 2" : false, "float key" : 1.01, "float key 2" : 2.02 ] as [String : Any] Crashlytics.crashlytics().setCustomKeysAndValues(keysAndValues)
Objective-C
NSDictionary *keysAndValues = @{@"string key" : @"string value", @"string key 2" : @"string value 2", @"boolean key" : @(YES), @"boolean key 2" : @(NO), @"float key" : @(1.01), @"float key 2" : @(2.02)}; [[FIRCrashlytics crashlytics] setCustomKeysAndValues: keysAndValues];
Как добавить собственные сообщения журнала
Чтобы получить больше информации о событиях, которые привели к сбою, добавьте в приложение собственные журналы Crashlytics. Crashlytics связывает журналы с данными о сбоях и показывает их на вкладке Журналы, когда вы просматриваете сведения о проблеме (все проблемы можно найти на панели управления Crashlytics в разделе DevOps и вовлечение консоли 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
справочной документации.
Objective-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")
Objective-C
[[FIRCrashlytics crashlytics] setUserID:@"123456789"];
Если вам нужно удалить идентификатор пользователя после того, как вы его задали, сбросьте значение до пустой строки. При удалении идентификатора пользователя существующие записи не удаляются. Crashlytics Если вам нужно удалить записи, связанные с идентификатором пользователя, обратитесь в службу поддержки Firebase.
Как сообщать о некритических исключениях
Помимо автоматической отправки отчетов о сбоях приложения, Crashlytics позволяет записывать некритические исключения и отправлять их вам при следующем запуске приложения.
Чтобы записывать некритические исключения, регистрируйте объекты NSError с помощью метода recordError. recordError получает стек вызовов потока, вызывая [NSThread callStackReturnAddresses].
Swift
Crashlytics.crashlytics().record(error: error)
Objective-C
[[FIRCrashlytics crashlytics] recordError:error];
При использовании метода recordError важно понимать NSErrorструктуру и то, как Crashlytics использует данные для группировки сбоев. Неправильное использование метода recordError может привести к непредсказуемому поведению и ограничению количества сообщений об ошибках, регистрируемых в приложении с помощью Crashlytics.
Объект NSError имеет три аргумента:
domain: Stringcode: IntuserInfo: [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)
Objective-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, преобразуются в пары "ключ-значение" и отображаются в разделе ключей/журналов в информации об отдельной проблеме.
Журналы и специальные ключи
Как и в случае с отчетами о сбоях, вы можете встраивать журналы и специальные ключи, чтобы добавить контекст в 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(name:"FooException", reason:"There was a foo.") ex.stackTrace = [ StackFrame(symbol:"makeError", file:"handler.js", line:495), StackFrame(symbol:"then", file:"routes.js", line:102), StackFrame(symbol:"main", file:"app.js", line:12), ] crashlytics.record(exceptionModel:ex)
Objective-C
FIRExceptionModel *model = [FIRExceptionModel exceptionModelWithName:@"FooException" reason:@"There was a foo."]; model.stackTrace = @[ [FIRStackFrame stackFrameWithSymbol:@"makeError" file:@"handler.js" line:495], [FIRStackFrame stackFrameWithSymbol:@"then" file:@"routes.js" line:102], [FIRStackFrame stackFrameWithSymbol:@"main" file:@"app.js" line:12], ]; [[FIRCrashlytics crashlytics] recordExceptionModel:model];
Специальные фреймы стека также можно инициализировать только адресами:
Swift
var ex = ExceptionModel.init(name:"FooException", reason:"There was a foo.") ex.stackTrace = [ StackFrame(address:0xfa12123), StackFrame(address:12412412), StackFrame(address:194129124), ] crashlytics.record(exceptionModel:ex)
Objective-C
FIRExceptionModel *model = [FIRExceptionModel exceptionModelWithName:@"FooException" reason:@"There was a foo."]; model.stackTrace = @[ [FIRStackFrame stackFrameWithAddress:0xfa12123], [FIRStackFrame stackFrameWithAddress:12412412], [FIRStackFrame stackFrameWithAddress:194129124], ]; [[FIRCrashlytics crashlytics] recordExceptionModel:model];
Как получить журналы навигации
Журналы навигации позволяют лучше понять, как пользователь взаимодействовал с приложением до сбоя, некритической ошибки или события ANR. Эти журналы могут быть полезны при попытке воспроизвести и отладить проблему.
Журналы цепочки навигации создаются на основе данных Google Аналитики, поэтому, чтобы их получать, вам нужно включить Google Аналитику для проекта Firebase и добавить в приложение Firebase SDK для Google Analytics. После этого журналы цепочки навигации будут автоматически включаться в данные о событиях на вкладке Журналы при просмотре сведений о проблеме (все проблемы можно найти на панели DevOps и вовлеченность > Crashlytics в консоли Firebase).
Analytics SDK автоматически регистрирует событие screen_view, благодаря чему в журналах цепочки событий показывается список экранов, просмотренных до сбоя, некритической ошибки или события ANR. В журнале навигации screen_view есть параметр firebase_screen_class.
В журналы также добавляются специальные события, которые вы вручную регистрируете в течение сеанса пользователя, включая данные параметров событий. Эти данные позволяют отследить последовательность действий пользователя, которые привели к сбою, некритической ошибке или ошибке ANR.
Обратите внимание, что вы можете управлять сбором и использованием данных Google Analytics, в том числе данных, которые заполняют журналы цепочки навигации.
Как включить отчеты о согласии
По умолчанию Crashlytics автоматически собирает отчеты о сбоях для всех пользователей вашего приложения. Чтобы предоставить пользователям больше контроля над отправляемыми данными, вы можете включить отчеты с запросом согласия, отключив автоматическую отправку отчетов и отправляя данные в Crashlytics только тогда, когда вы сами решите это сделать в своем коде.
Чтобы отключить автоматический сбор данных, добавьте в файл
Info.plistновый ключ:- Клавиша:
FirebaseCrashlyticsCollectionEnabled - Значение:
false
- Клавиша:
Включите сбор данных для определенных пользователей, вызвав переопределение сбора данных Crashlytics во время выполнения. Переопределенное значение сохраняется при всех последующих запусках приложения, поэтому Crashlytics может автоматически собирать отчеты для этого пользователя.
Swift
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(true)
Objective-C
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:YES];
Если пользователь позже откажется от сбора данных, вы можете передать значение
falseв качестве переопределения. Оно будет применено при следующем запуске приложения и сохранится при всех последующих запусках.
Как управлять данными о сбоях
С помощью Crash Insights вы можете устранять проблемы, сравнивая анонимизированные трассировки стека с трассировками из других приложений Firebase и узнавая, является ли ваша проблема частью более масштабной тенденции. Для многих проблем Crash Insights даже предоставляет ресурсы, которые помогут вам отладить сбой.
Инструмент "Аналитика сбоев" использует агрегированные данные о сбоях, чтобы выявлять общие тенденции стабильности. Если вы не хотите делиться данными приложения, вы можете отключить функцию "Анализ сбоев" в меню Анализ сбоев вверху списка проблем на панели DevOps и вовлеченность > Crashlytics в консоли Firebase.
Дальнейшие действия
- Экспортируйте данные в BigQuery или Cloud Logging, чтобы использовать расширенные функции анализа, например отправлять запросы к данным, создавать собственные сводки и настраивать специальные оповещения.