Узнайте о сбоях в игре Unity с помощью расширенных функций Crashlytics. Узнайте о сбоях в игре Unity с помощью расширенных функций Crashlytics.

1. Введение

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

Вам предстоит добавить новый функционал в демонстрационную игру MechaHamster: Level Up with Firebase Edition . Эта демонстрационная игра представляет собой новую версию классической игры MechaHamster, использующей Firebase, в которой удалена большая часть встроенного функционала Firebase, что дает вам возможность реализовать новые способы использования Firebase.

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

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

Что вы узнаете

  • Типы ошибок, которые автоматически выявляются системой Crashlytics.
  • Дополнительные ошибки, которые можно целенаправленно фиксировать.
  • Как добавить больше информации к этим ошибкам, чтобы сделать их более понятными.

Что вам понадобится

  • Unity (минимальная рекомендуемая версия 2019+) с одним или обоими из следующих компонентов:
    • Поддержка сборки iOS
    • Поддержка сборки Android
  • (Только для Android) Интерфейс командной строки Firebase (используется для загрузки символов в отчеты о сбоях)

2. Настройте среду разработки.

В следующих разделах описано, как загрузить код Level Up with Firebase и открыть его в Unity.

Обратите внимание, что эта демонстрационная игра Level Up with Firebase используется в нескольких других практических заданиях по Firebase + Unity, поэтому вы, возможно, уже выполнили задания в этом разделе. В таком случае вы можете сразу перейти к последнему шагу на этой странице: «Добавить SDK Firebase для Unity».

Скачать код

Клонируйте репозиторий этого учебного пособия на GitHub из командной строки:

git clone https://github.com/firebase/level-up-with-firebase.git

В качестве альтернативы, если у вас не установлен Git, вы можете загрузить репозиторий в виде ZIP-файла .

Откройте Level Up with Firebase в редакторе Unity.

  1. Запустите Unity Hub и на вкладке «Проекты» нажмите стрелку раскрывающегося списка рядом с кнопкой «Открыть» .
  2. Нажмите «Добавить проект с диска» .
  3. Перейдите в каталог, содержащий код, и нажмите кнопку ОК .
  4. При появлении запроса выберите версию редактора Unity и целевую платформу (Android или iOS).
  5. Щёлкните по названию проекта, level-up-with-firebase , и проект откроется в редакторе Unity.
  6. Если ваш редактор не открывает его автоматически, откройте MainGameScene в Assets > Hamster на вкладке Project редактора Unity.
    ff4ea3f3c0d29379.png

Для получения дополнительной информации об установке и использовании Unity см. раздел «Работа в Unity» .

3. Добавьте Firebase в свой проект Unity.

Создайте проект Firebase.

  1. Войдите в консоль Firebase, используя свою учетную запись Google.
  2. Нажмите кнопку, чтобы создать новый проект, а затем введите название проекта (например, Mechahamster Codelab ).
  3. Нажмите «Продолжить» .
  4. Если появится запрос, ознакомьтесь с условиями использования Firebase и примите их, после чего нажмите «Продолжить» .
  5. (Необязательно) Включите помощь ИИ в консоли Firebase (в Firebase она называется "Gemini").
  6. Для выполнения этого практического задания вам потребуется Google Analytics для оптимального использования продуктов Firebase, поэтому оставьте переключатель Google Analytics включенным . Следуйте инструкциям на экране, чтобы настроить Google Analytics.
  7. Нажмите «Создать проект» , дождитесь завершения подготовки проекта, а затем нажмите «Продолжить» .

Зарегистрируйте свое приложение в Firebase.

  1. Оставаясь в консоли Firebase , в центре страницы обзора проекта щелкните значок Unity, чтобы запустить процесс настройки, или, если вы уже добавили приложение в свой проект Firebase, щелкните «Добавить приложение», чтобы отобразить параметры платформы.
  2. Выберите этот пункт, чтобы зарегистрировать целевые устройства сборки как для Apple (iOS), так и для Android.
  3. Введите идентификатор(ы) вашего проекта Unity, специфичные для платформы. Для этого практического задания введите следующее:
  4. (Необязательно) Введите псевдоним(-ы) вашего проекта Unity, специфичный(-ые) для данной платформы.
  5. Нажмите «Зарегистрировать приложение» , а затем перейдите к разделу «Скачать файл конфигурации» .

Добавьте файлы конфигурации Firebase.

После нажатия кнопки «Зарегистрировать приложение» вам будет предложено загрузить два конфигурационных файла (по одному конфигурационному файлу для каждой цели сборки). Вашему проекту Unity необходимы метаданные Firebase из этих файлов для подключения к Firebase.

  1. Загрузите оба доступных файла конфигурации:
    • Для Apple (iOS) : Загрузите файл GoogleService-Info.plist .
    • Для Android : скачайте файл google-services.json .
  2. Откройте окно проекта вашего проекта Unity, затем переместите оба файла конфигурации в папку Assets .
  3. Вернувшись в консоль Firebase, в процессе настройки нажмите «Далее» и перейдите к добавлению SDK Firebase для Unity.

Добавить SDK Firebase для Unity

  1. В консоли Firebase нажмите «Загрузить Firebase Unity SDK» .
  2. Распакуйте SDK в удобное для вас место.
  3. В открытом проекте Unity перейдите в Assets > Import Package > Custom Package .
  4. В диалоговом окне «Импорт пакета» перейдите в каталог, содержащий распакованный SDK, выберите FirebaseAnalytics.unitypackage , а затем нажмите « Открыть» .
  5. В появившемся диалоговом окне «Импорт пакета Unity» нажмите «Импорт» .
  6. Повторите предыдущие шаги, чтобы импортировать FirebaseCrashlytics.unitypackage .
  7. Вернитесь в консоль Firebase и в процессе настройки нажмите «Далее» .

Для получения дополнительной информации о добавлении SDK Firebase в проекты Unity см. раздел «Дополнительные параметры установки Unity» .

4. Настройте Crashlytics в своем проекте Unity.

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

Инициализируйте SDK Crashlytics.

  1. В Assets/Hamster/Scripts/MainGame.cs добавьте следующие операторы using :
    using Firebase.Crashlytics;
    using Firebase.Extensions;
    
    Первый модуль позволяет использовать методы из SDK Crashlytics, а второй содержит некоторые расширения API задач C# . Без обоих операторов using следующий код работать не будет.
  2. В файле MainGame.cs добавьте инициализацию Firebase к существующему методу Start() , вызвав InitializeFirebaseAndStartGame() :
    void Start()
    {
      Screen.SetResolution(Screen.width / 2, Screen.height / 2, true);
      InitializeFirebaseAndStartGame();
    }
    
  3. И снова, в MainGame.cs найдите метод InitializeFirebaseAndStartGame() , объявите переменную приложения, а затем переопределите реализацию метода следующим образом:
    public Firebase.FirebaseApp app = null;
    
    // Begins the firebase initialization process and afterwards, opens the main menu.
    private void InitializeFirebaseAndStartGame()
    {
      Firebase.FirebaseApp.CheckAndFixDependenciesAsync()
      .ContinueWithOnMainThread(
        previousTask => 
        {
          var dependencyStatus = previousTask.Result;
          if (dependencyStatus == Firebase.DependencyStatus.Available) {
            // Create and hold a reference to your FirebaseApp,
            app = Firebase.FirebaseApp.DefaultInstance;
            // Set the recommended Crashlytics uncaught exception behavior.
            Crashlytics.ReportUncaughtExceptionsAsFatal = true;
            InitializeCommonDataAndStartGame();
          } else {
            UnityEngine.Debug.LogError(
              $"Could not resolve all Firebase dependencies: {dependencyStatus}\n" +
              "Firebase Unity SDK is not safe to use here");
          }
        });
    }
    

Размещение логики инициализации здесь предотвращает взаимодействие игрока до инициализации зависимостей Firebase.

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

Создайте свой проект и загрузите символы.

Последовательность действий по созданию и загрузке символов различается для приложений iOS и Android.

iOS+ (платформа Apple)

  1. В диалоговом окне «Параметры сборки» экспортируйте свой проект в рабочую область Xcode.
  2. Создайте своё приложение.
    Для платформ Apple плагин Firebase Unity Editor автоматически настраивает ваш проект Xcode для генерации и загрузки совместимого с Crashlytics файла символов на серверы Firebase для каждой сборки. Эта информация о символах необходима для просмотра символизированных трассировок стека на панели мониторинга Crashlytics.

Android

  1. (Только во время первоначальной настройки, а не для каждой сборки) Настройте свою сборку:
    1. Создайте новую папку с именем Builds в корневом каталоге вашего проекта (то есть, рядом с каталогом Assets ), а затем создайте подпапку с именем Android .
    2. В меню Файл > Настройки сборки > Настройки проигрывателя > Конфигурация установите параметр «Бэкенд скриптов» на IL2CPP.
      • Как правило, IL2CPP позволяет уменьшить размер файлов сборки и повысить их производительность.
      • IL2CPP также является ЕДИНСТВЕННЫМ доступным вариантом на iOS, и его выбор здесь позволяет обеспечить большую совместимость двух платформ и упростить отладку различий между ними (если вы решите собрать обе системы).
  2. Создайте своё приложение. В меню «Файл» > «Настройки сборки» выполните следующие действия:
    1. Убедитесь, что установлен флажок «Создать symbols.zip» (или, если отображается выпадающее меню, выберите «Отладка» ).
    2. Создайте APK-файл непосредственно в редакторе Unity и скопируйте его в созданную вами подпапку Builds/Android .
  3. После завершения сборки необходимо сгенерировать файл символов, совместимый с Crashlytics, и загрузить его на серверы Firebase. Эта информация о символах необходима для просмотра символизированных трассировок стека для сбоев нативных библиотек на панели мониторинга Crashlytics.

    Создайте и загрузите этот файл символов, выполнив следующую команду Firebase CLI :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
    • FIREBASE_APP_ID : Идентификатор вашего Android-приложения Firebase (а не имя пакета). Найдите это значение в файле google-services.json , который вы скачали ранее. Это значение mobilesdk_app_id .
      Пример идентификатора Android-приложения Firebase: 1:567383003300:android:17104a2ced0c9b9b
    • PATH/TO/SYMBOLS : путь к заархивированному файлу символов, созданному в каталоге Builds/Android после завершения сборки (например: Builds/Android/myapp-1.0-v100.symbols.zip ).

Принудительное завершение процесса настройки путем сбоя теста.

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

  1. В MainGameScene найдите GameObject EmptyObject в иерархии редактора, добавьте в него следующий скрипт, а затем сохраните сцену. Этот скрипт вызовет сбой теста через несколько секунд после запуска приложения.
    using System;
    using UnityEngine;
    
    public class CrashlyticsTester : MonoBehaviour {
        // Update is called once per frame
        void Update()
        {
            // Tests your Crashlytics implementation by
            // throwing an exception every 60 frames.
            // You should see reports in the Firebase console
            // a few minutes after running your app with this method.
            if(Time.frameCount >0 && (Time.frameCount%60) == 0)
            {
                throw new System.Exception("Test exception; please ignore");
            }
        }
    }
    
  2. Соберите приложение и загрузите информацию о символах после завершения сборки.
    • iOS : Плагин Firebase Unity Editor автоматически настраивает ваш проект Xcode для загрузки файла символов.
    • Android : Выполните команду firebase CLI crashlytics:symbols:upload , чтобы загрузить файл символов.
  3. Запустите приложение. После запуска приложения следите за логами устройства и дождитесь появления исключения от CrashlyticsTester .
    • iOS : просмотр логов в нижней панели Xcode.
    • Android : Чтобы просмотреть логи, выполните следующую команду в терминале: adb logcat .
  4. Чтобы просмотреть исключение, перейдите на панель мониторинга Crashlytics ! Вы увидите его в таблице «Проблемы» внизу панели мониторинга. Позже в практическом задании вы узнаете больше о том, как изучать эти отчеты.
  5. После того, как вы убедитесь, что событие загружено в Crashlytics, выберите GameObject EmptyObject , к которому оно было прикреплено, удалите только компонент CrashlyticsTester , а затем сохраните сцену, чтобы восстановить ее до исходного состояния.

5. Включите и разберитесь в работе меню отладки.

К этому моменту вы добавили Crashlytics в свой проект Unity, завершили настройку и подтвердили, что SDK Crashlytics загружает события в Firebase. Теперь вы создадите меню в своем проекте Unity, которое продемонстрирует, как использовать более продвинутые функции Crashlytics в вашей игре. В проекте Level Up with Firebase Unity уже есть скрытое меню отладки, которое вы сделаете видимым и напишете для него соответствующий код.

Включите меню отладки

Кнопка для доступа к меню отладки существует в вашем проекте Unity, но в данный момент она неактивна. Для доступа к ней необходимо включить кнопку из префаба MainMenu :

  1. В редакторе Unity откройте префаб с именем MainMenu . 4148538cbe9f36c5.png
  2. В иерархии префабов найдите отключенный подобъект с именем DebugMenuButton и выберите его. 816f8f9366280f6c.png
  3. Чтобы активировать кнопку DebugMenuButton , установите флажок в верхнем левом углу слева от текстового поля, содержащего DebugMenuButton . 8a8089d2b4886da2.png
  4. Сохраните сборные дома.
  5. Запустите игру либо в редакторе, либо на своем устройстве. Теперь меню должно быть доступно.

Предварительно просмотрите и изучите тела методов для меню отладки.

В дальнейшем в этом практическом занятии вы напишете тела методов для некоторых предварительно настроенных методов отладки Crashlytics. Однако в проекте Level Up with Firebase Unity эти методы определены и вызываются из DebugMenu.cs .

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

Откройте DebugMenu.cs и найдите следующие методы:

Методы генерации и аннотирования проблем в Crashlytics:

  • CrashNow
  • LogNonfatalError
  • LogStringsAndCrashNow
  • SetAndOverwriteCustomKeyThenCrash
  • SetLogsAndKeysBeforeANR

Методы регистрации событий Analytics для облегчения отладки:

  • LogProgressEventWithStringLiterals
  • LogIntScoreWithBuiltInEventAndParams

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

6. Обеспечить предоставление отчетов о сбоях в процессе разработки.

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

В проектах Unity события сбоев и исключений в игре немедленно записываются на диск. Для необработанных исключений, которые не приводят к сбою игры (например, необработанные исключения C# в игровой логике), вы можете настроить SDK Crashlytics так, чтобы он сообщал о них как о фатальных событиях, установив свойство Crashlytics.ReportUncaughtExceptionsAsFatal в значение true при инициализации Crashlytics в вашем проекте Unity . Эти события передаются в Crashlytics в режиме реального времени без необходимости перезапуска игры конечным пользователем. Обратите внимание, что сбои, вызванные нативными функциями, всегда сообщаются как фатальные события и передаются при перезапуске игры конечным пользователем.

Кроме того, следует учитывать следующие небольшие, но существенные различия в том, как различные среды выполнения отправляют информацию Crashlytics в Firebase:

Симулятор iOS:

  • Информация Crashlytics передается только в том случае, если вы отсоедините Xcode от симулятора. Если Xcode подключен, он перехватывает ошибки на более высоком уровне, предотвращая передачу информации.

Мобильные физические устройства (Android и iOS):

  • Особенности Android: сообщения об ошибках ANR отображаются только на Android 11 и выше. Сообщения об ошибках ANR и некритических событиях будут отображаться при следующем запуске.

Редактор Unity:

Проверьте возможность сбоя игры одним нажатием кнопки в CrashNow()

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

  1. Чтобы продемонстрировать, что это действительно происходит автоматически: откройте DebugMenu.cs и переопределите метод CrashNow() следующим образом:
    void CrashNow()
    {
        TestCrash();
    }
    
  2. Создайте своё приложение.
  3. (Только для Android) Загрузите свои символы, выполнив следующую команду Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Нажмите кнопку «Сбой сейчас» и перейдите к следующему шагу этого практического занятия, чтобы узнать, как просмотреть и интерпретировать отчет о сбое.

7. Разберитесь в сообщениях об ошибках в консоли Firebase.

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

  1. Нажмите кнопку «Crash Now» , а затем перезапустите приложение.
  2. Перейдите на панель управления Crashlytics . Прокрутите вниз до таблицы «Проблемы» в нижней части панели, где Crashlytics группирует события с одной и той же первопричиной в категорию «проблемы».
  3. Щёлкните по новой проблеме, которая отображается в таблице « Проблемы» . Это отобразит сводку событий по каждому отдельному событию, отправленному в Firebase.

    Вы должны увидеть что-то подобное следующему скриншоту. Обратите внимание, как в сводке событий отчетливо отображается трассировка стека вызова, приведшего к сбою. 40c96abe7f90c3aa.png

Дополнительные метаданные

Ещё одна полезная вкладка — Unity Metadata . В этом разделе вы найдёте информацию об атрибутах устройства, на котором произошло событие, включая физические характеристики, модель/спецификации процессора и всевозможные показатели графического процессора.

Вот пример того, как информация на этой вкладке может быть полезна:
Представьте, что ваша игра активно использует шейдеры для достижения определённого визуального эффекта, но не все телефоны имеют графические процессоры, способные отображать эту функцию. Информация на вкладке «Метаданные Unity» поможет вам лучше понять, какое оборудование следует тестировать вашему приложению при принятии решения о том, какие функции следует автоматически включать или полностью отключать.

Хотя на вашем устройстве может и не произойти ни одной ошибки или сбоя, из-за огромного разнообразия устройств Android в реальных условиях, полезно лучше понимать конкретные «проблемные места» на устройствах вашей аудитории.

41d8d7feaa87454d.png

8. Выбросить, перехватить и зарегистрировать исключение.

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

  1. В Assets/Hamster/Scripts/States/DebugMenu.cs добавьте к операторам using следующее:
    // Import Firebase
    using Firebase.Crashlytics;
    
  2. В файле DebugMenu.cs переопределите LogNonfatalError() следующим образом:
    void LogNonfatalError()
    {
        try
        {
            throw new System.Exception($"Test exception thrown in {nameof(LogNonfatalError)}");
        }
        catch(System.Exception exception)
        {
            Crashlytics.LogException(exception);
        }
    }
    
  3. Создайте своё приложение.
  4. (Только для Android) Загрузите свои символы, выполнив следующую команду Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  5. Нажмите кнопку «Зарегистрировать некритическую ошибку» , а затем перезапустите приложение.
  6. Перейдите на панель управления Crashlytics , и вы должны увидеть что-то похожее на то, что вы видели на последнем шаге этого практического задания.
  7. Однако на этот раз ограничьте фильтр по типу события только некритическими ошибками , чтобы отображались только некритические ошибки, такие как та, которую вы только что зарегистрировали.
    a39ea8d9944cbbd9.png

9. Отправляйте строки логов в Crashlytics для лучшего понимания хода выполнения программы.

Вы когда-нибудь пытались понять, почему строка кода, вызываемая из множества путей, сотни, если не тысячи раз за сессию, может внезапно вызвать исключение или привести к сбою? Хотя было бы неплохо пошагово просмотреть код в IDE и более внимательно изучить значения, что, если это происходит лишь у ничтожно малого процента ваших пользователей? Хуже того, что вы будете делать, если не сможете воспроизвести этот сбой, несмотря ни на какие усилия?

В подобных ситуациях наличие контекста может иметь огромное значение. С помощью Crashlytics.Log вы можете записать необходимый контекст. Воспринимайте эти сообщения как подсказки для себя в будущем о том, что может происходить.

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

  1. В Assets/Hamster/Scripts/States/DebugMenu.cs переопределите функцию LogStringsAndCrashNow() следующим образом:
    void LogStringsAndCrashNow()
    {
        Crashlytics.Log($"This is the first of two descriptive strings in {nameof(LogStringsAndCrashNow)}");
        const bool RUN_OPTIONAL_PATH = false;
        if(RUN_OPTIONAL_PATH)
        {
            Crashlytics.Log(" As it stands, this log should not appear in your records because it will never be called.");
        }
        else
        {
            Crashlytics.Log(" A log that will simply inform you which path of logic was taken. Akin to print debugging.");
        }
        Crashlytics.Log($"This is the second of two descriptive strings in {nameof(LogStringsAndCrashNow)}");
        TestCrash();
    }
    
  2. Создайте своё приложение.
  3. (Только для Android) Загрузите свои символы, выполнив следующую команду Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Нажмите кнопку «Записать в журнал» и «Сбой» , а затем перезапустите приложение.
  5. Вернитесь на панель управления Crashlytics и щелкните по самой новой проблеме в таблице « Проблемы» . Вы снова должны увидеть что-то похожее на предыдущие проблемы.
    7aabe103b8589cc7.png
  6. Однако, если вы перейдете на вкладку «Журналы» в сводке события , вы увидите примерно следующее:
    4e27aa407b7571cf.png

10. Запись и перезапись пользовательского ключа.

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

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

Это пары ключ-значение, которые можно установить для сессии. В отличие от логов, которые накапливаются и являются чисто аддитивными, ключи можно перезаписывать, чтобы они отражали только самое последнее состояние переменной или условия.

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

  1. В Assets/Hamster/Scripts/States/DebugMenu.cs переопределите SetAndOverwriteCustomKeyThenCrash() следующим образом:
    void SetAndOverwriteCustomKeyThenCrash()
    {
        const string CURRENT_TIME_KEY = "Current Time";
        System.TimeSpan currentTime = System.DateTime.Now.TimeOfDay;
        Crashlytics.SetCustomKey(
            CURRENT_TIME_KEY,
            DayDivision.GetPartOfDay(currentTime).ToString() // Values must be strings
            );
    
        // Time Passes
        currentTime += DayDivision.DURATION_THAT_ENSURES_PHASE_CHANGE;
    
        Crashlytics.SetCustomKey(
            CURRENT_TIME_KEY,
            DayDivision.GetPartOfDay(currentTime).ToString()
            );
        TestCrash();
    }
    
  2. Создайте своё приложение.
  3. (Только для Android) Загрузите свои символы, выполнив следующую команду Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Нажмите кнопку «Установить пользовательскую клавишу и сбой» , а затем перезапустите приложение.
  5. Вернитесь на панель управления Crashlytics и щелкните по самой новой проблеме в таблице « Проблемы» . Вы снова должны увидеть что-то похожее на предыдущие проблемы.
  6. На этот раз, однако, щелкните вкладку «Клавиши» в сводке событий , чтобы просмотреть значения клавиш, включая Current Time :
    7dbe1eb00566af98.png

Зачем использовать пользовательские ключи вместо пользовательских логов?

  • Журналы хорошо подходят для хранения последовательных данных, но пользовательские ключи лучше, если вам нужно только самое последнее значение.
  • В консоли Firebase вы можете легко фильтровать задачи по значениям ключей в поле поиска таблицы Issues .

Как и в случае с логами, у пользовательских ключей есть ограничение. Crashlytics поддерживает максимум 64 пары ключ-значение. После достижения этого порога дополнительные значения не сохраняются. Размер каждой пары ключ-значение может составлять до 1 КБ.

11. (Только для Android) Используйте пользовательские ключи и журналы для понимания и диагностики ANR.

Одна из самых сложных для отладки проблем для разработчиков Android — это ошибка «Приложение не отвечает » (ANR). ANR возникает, когда приложение не реагирует на ввод более 5 секунд. В этом случае это означает, что приложение либо зависло, либо работает очень медленно. Пользователям отображается диалоговое окно, в котором они могут выбрать, «Подождать» или «Закрыть приложение».

ANR-ошибки ухудшают пользовательский опыт и (как упоминалось в ссылке выше) могут повлиять на видимость вашего приложения в Google Play Store. Из-за их сложности и того, что они часто вызваны многопоточным кодом с существенно различающимся поведением на разных моделях телефонов, воспроизведение ANR-ошибок в процессе отладки часто бывает очень сложным, если не практически невозможным. Поэтому аналитический и дедуктивный подход обычно является наилучшим.

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

  1. В Assets/Hamster/Scripts/States/DebugMenu.cs переопределите SetLogsAndKeysBeforeANR() следующим образом:
    void SetLogsAndKeysBeforeANR()
    {
        System.Action<string,long> WaitAndRecord =
        (string methodName, long targetCallLength)=>
        {
            System.Diagnostics.Stopwatch stopWatch = new System.Diagnostics.Stopwatch();
            const string CURRENT_FUNCTION = "Current Async Function";
    
            // Initialize key and start timing
            Crashlytics.SetCustomKey(CURRENT_FUNCTION, methodName);
            stopWatch.Start();
    
            // The actual (simulated) work being timed.
            BusyWaitSimulator.WaitOnSimulatedBlockingWork(targetCallLength);
    
            // Stop timing
            stopWatch.Stop();
    
            if(stopWatch.ElapsedMilliseconds>=BusyWaitSimulator.EXTREME_DURATION_MILLIS)
            {
              Crashlytics.Log($"'{methodName}' is long enough to cause an ANR.");
            }
            else if(stopWatch.ElapsedMilliseconds>=BusyWaitSimulator.SEVERE_DURATION_MILLIS)
            {
              Crashlytics.Log($"'{methodName}' is long enough it may cause an ANR");
            }
        };
    
        WaitAndRecord("DoSafeWork",1000L);
        WaitAndRecord("DoSevereWork",BusyWaitSimulator.SEVERE_DURATION_MILLIS);
        WaitAndRecord("DoExtremeWork",2*BusyWaitSimulator.EXTREME_DURATION_MILLIS);
    }
    
  2. Создайте своё приложение.
  3. Загрузите свои символы, выполнив следующую команду Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Нажмите кнопку «Set Logs And Keys → ANR» , а затем перезапустите приложение.
  5. Вернитесь на панель управления Crashlytics , затем щелкните по новой проблеме в таблице «Проблемы» , чтобы просмотреть сводку события . Если звонок прошел успешно, вы должны увидеть что-то подобное:
    876c3cff7037bd07.png

    Как видите, Firebase определил задержку в потоке как основную причину срабатывания ANR в вашем приложении.
  6. Если вы посмотрите журналы на вкладке «Журналы» в сводке событий , вы увидите, что последним методом, зарегистрированным как завершенный, является DoSevereWork .
    5a4bec1cf06f6984.png

    Напротив, последним методом, указанным как запускающийся, является DoExtremeWork , что указывает на то, что ошибка ANR произошла во время выполнения этого метода, и игра закрылась до того, как смогла зарегистрировать DoExtremeWork .

    89d86d5f598ecf3a.png

Зачем это делать?

  • Воспроизведение ошибок ANR невероятно сложно, поэтому получение подробной информации об областях кода и метриках крайне важно для их обнаружения дедуктивным методом.
  • Благодаря информации, хранящейся в пользовательских ключах, вы теперь знаете, какой асинхронный поток выполнялся дольше всего, а какие могли вызвать ошибки ANR. Подобные логические и числовые данные покажут вам, где в вашем коде наиболее необходима оптимизация.

12. Включение аналитических событий в отчеты для их дальнейшего обогащения.

Следующие методы также можно вызывать из меню отладки, но вместо того, чтобы самостоятельно генерировать ошибки, они используют Google Analytics в качестве дополнительного источника информации для лучшего понимания работы вашей игры.

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

  1. В Assets/Hamster/Scripts/States/DebugMenu.cs замените существующие реализации следующих методов:
    public void LogProgressEventWithStringLiterals()
    {
          Firebase.Analytics.FirebaseAnalytics.LogEvent("progress", "percent", 0.4f);
    }
    
    public void LogIntScoreWithBuiltInEventAndParams()
    {
          Firebase.Analytics.FirebaseAnalytics
            .LogEvent(
              Firebase.Analytics.FirebaseAnalytics.EventPostScore,
              Firebase.Analytics.FirebaseAnalytics.ParameterScore,
              42
            );
    }
    
  2. Соберите и разверните свою игру, а затем войдите в меню отладки .
  3. (Только для Android) Загрузите свои символы, выполнив следующую команду Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Для вызова указанных выше функций нажмите хотя бы одну из следующих кнопок один или несколько раз:
    • Событие в виде строки журнала
    • Событие логирования
  5. Нажмите кнопку «Сбой сейчас» .
  6. Перезапустите игру, чтобы она загрузила событие сбоя в Firebase.
  7. Когда вы регистрируете различные произвольные последовательности событий аналитики, а затем ваша игра генерирует событие, на основе которого Crashlytics создает отчет (как вы только что сделали), они добавляются на вкладку «Журналы» в сводке событий Crashlytics следующим образом:
    d3b16d78f76bfb04.png

13. Дальнейшие действия

Таким образом, у вас появится более надежная теоретическая основа для дополнения автоматически генерируемых отчетов о сбоях. Эта новая информация позволит вам использовать текущее состояние, записи прошлых событий и существующие события Google Analytics, чтобы лучше проанализировать последовательность событий и логику, которые привели к их результату.

Если ваше приложение ориентировано на Android 11 (уровень API 30) или выше, рассмотрите возможность использования GWP-ASan — функции распределения нативной памяти, полезной для отладки сбоев, вызванных ошибками нативной памяти, такими как ошибки использования памяти use-after-free и переполнения буфера кучи heap-buffer-overflow . Чтобы воспользоваться этой функцией отладки, явно включите GWP-ASan .

Следующие шаги

Перейдите к практическому занятию «Инструментирование вашей игры Unity с помощью Remote Config» , где вы узнаете об использовании Remote Config и A/B-тестирования в Unity.