Comprendre les crashs d'un jeu Unity à l'aide des fonctionnalités avancées de Crashlytics

1. Introduction

Dans cet atelier de programmation, vous apprendrez à utiliser les fonctionnalités avancées de Crashlytics qui vous donneront une meilleure visibilité sur les plantages et les circonstances qui ont pu les provoquer.

Vous ajouterez de nouvelles fonctionnalités à un exemple de jeu, MechaHamster : Level Up with Firebase Edition . Cet exemple de jeu est une nouvelle version du jeu Firebase classique MechaHamster qui supprime la plupart de ses fonctionnalités Firebase intégrées, vous donnant la possibilité d'implémenter de nouvelles utilisations de Firebase à leur place.

Vous ajouterez un menu de débogage au jeu. Ce menu de débogage appelle les méthodes que vous allez créer et vous permet d'exercer les différentes fonctionnalités de Crashlytics. Ces méthodes vous montreront comment annoter vos rapports de plantage automatiques avec des clés personnalisées, des journaux personnalisés, des erreurs non fatales, etc.

Après avoir créé le jeu, vous utiliserez le menu de débogage et inspecterez les résultats pour comprendre la vue unique qu'ils fournissent sur la façon dont votre jeu fonctionne dans la nature.

Ce que vous apprendrez

  • Les types d'erreurs automatiquement détectées par Crashlytics.
  • Erreurs supplémentaires qui peuvent être délibérément enregistrées.
  • Comment ajouter plus d'informations à ces erreurs pour les rendre plus faciles à comprendre.

Ce dont vous aurez besoin

  • Unity (version minimale recommandée 2019+) avec un ou les deux éléments suivants :
    • Prise en charge des versions iOS
    • Prise en charge des versions Android
  • (Pour Android uniquement) La CLI Firebase (utilisée pour télécharger des symboles pour les rapports d'erreur)

2. Configurez votre environnement de développement

Les sections suivantes décrivent comment télécharger le code Level Up with Firebase et l'ouvrir dans Unity.

Notez que cet exemple de jeu Level Up with Firebase est utilisé par plusieurs autres ateliers de programmation Firebase + Unity. Vous avez donc peut-être déjà effectué les tâches de cette section. Si tel est le cas, vous pouvez passer directement à la dernière étape de cette page : "Ajouter des SDK Firebase pour Unity".

Téléchargez le code

Clonez le dépôt GitHub de cet atelier de programmation à partir de la ligne de commande :

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

Alternativement, si git n'est pas installé, vous pouvez télécharger le référentiel sous forme de fichier ZIP .

Ouvrez Level Up avec Firebase dans l'éditeur Unity

  1. Lancez Unity Hub et, dans l'onglet Projets , cliquez sur la flèche déroulante en regard de Ouvrir .
  2. Cliquez sur Ajouter un projet à partir du disque .
  3. Accédez au répertoire contenant le code, puis cliquez sur OK .
  4. Si vous y êtes invité, sélectionnez une version de l'éditeur Unity à utiliser et votre plate-forme cible (Android ou iOS).
  5. Cliquez sur le nom du projet, level-up-with-firebase , et le projet s'ouvrira dans l'éditeur Unity.
  6. Si votre éditeur ne l'ouvre pas automatiquement, ouvrez MainGameScene dans Assets > Hamster dans l'onglet Projet de l'éditeur Unity.
    ff4ea3f3c0d29379.png

Pour plus d'informations sur l'installation et l'utilisation de Unity, consultez Travailler dans Unity .

3. Ajoutez Firebase à votre projet Unity

Créer un projet Firebase

  1. Dans la console Firebase , cliquez sur Ajouter un projet .
  2. Pour créer un nouveau projet, entrez le nom du projet souhaité.
    Cela définira également l'ID du projet (affiché sous le nom du projet) sur quelque chose basé sur le nom du projet. Vous pouvez éventuellement cliquer sur l'icône d'édition sur l'ID du projet pour le personnaliser davantage.
  3. Si vous y êtes invité, consultez et acceptez les conditions d'utilisation de Firebase .
  4. Cliquez sur Continuer .
  5. Sélectionnez l'option Activer Google Analytics pour ce projet , puis cliquez sur Continuer .
  6. Sélectionnez un compte Google Analytics existant à utiliser ou sélectionnez Créer un nouveau compte pour créer un nouveau compte.
  7. Cliquez sur Créer un projet .
  8. Une fois le projet créé, cliquez sur Continuer .

Enregistrez votre application avec Firebase

  1. Toujours dans la console Firebase , depuis le centre de la page de présentation du projet, cliquez sur l'icône Unity pour lancer le workflow de configuration ou, si vous avez déjà ajouté une application à votre projet Firebase, cliquez sur Ajouter une application pour afficher les options de la plateforme.
  2. Sélectionnez pour enregistrer les cibles de build Apple (iOS) et Android.
  3. Saisissez le(s) ID spécifique(s) à la plateforme de votre projet Unity. Pour cet atelier de programmation, saisissez les informations suivantes :
  4. (Facultatif) Saisissez le(s) surnom(s) spécifique(s) à la plateforme de votre projet Unity.
  5. Cliquez sur Enregistrer l'application , puis passez à la section Télécharger le fichier de configuration .

Ajouter des fichiers de configuration Firebase

Après avoir cliqué sur Register app , vous serez invité à télécharger deux fichiers de configuration (un fichier de configuration pour chaque cible de build). Votre projet Unity a besoin des métadonnées Firebase contenues dans ces fichiers pour se connecter à Firebase.

  1. Téléchargez les deux fichiers de configuration disponibles :
    • Pour Apple (iOS) : Téléchargez GoogleService-Info.plist .
    • Pour Android : Téléchargez google-services.json .
  2. Ouvrez la fenêtre Projet de votre projet Unity, puis déplacez les deux fichiers de configuration dans le dossier Assets .
  3. De retour dans la console Firebase, dans le workflow de configuration, cliquez sur Suivant et passez à Ajouter des SDK Firebase pour Unity.

Ajouter des SDK Firebase pour Unity

  1. Cliquez sur Télécharger le SDK Firebase Unity dans la console Firebase.
  2. Décompressez le SDK dans un endroit pratique.
  3. Dans votre projet Unity ouvert, accédez à Assets > Import Package > Custom Package .
  4. Dans la boîte de dialogue Importer le package , accédez au répertoire contenant le SDK décompressé, sélectionnez FirebaseAnalytics.unitypackage , puis cliquez sur Ouvrir .
  5. Dans la boîte de dialogue Importer un package Unity qui apparaît, cliquez sur Importer .
  6. Répétez les étapes précédentes pour importer FirebaseCrashlytics.unitypackage .
  7. Revenez à la console Firebase et, dans le workflow de configuration, cliquez sur Suivant .

Pour plus d'informations sur l'ajout de SDK Firebase aux projets Unity, consultez Options d'installation supplémentaires de Unity .

4. Configurez Crashlytics dans votre projet Unity

Pour utiliser Crashlytics dans des projets Unity, vous devrez effectuer quelques étapes de configuration supplémentaires. Bien entendu, vous devrez initialiser le SDK. Mais vous devrez également télécharger vos symboles afin de pouvoir voir les traces de pile symbolisées dans la console Firebase, et vous devrez forcer un crash test pour vous assurer que Firebase reçoit vos événements de crash.

Initialiser le SDK Crashlytics

  1. Dans Assets/Hamster/Scripts/MainGame.cs , ajoutez les instructions using suivantes :
    using Firebase.Crashlytics;
    using Firebase.Extensions;
    
    Le premier module vous permet d'utiliser les méthodes du SDK Crashlytics et le second contient des extensions de l' API de tâches C# . Sans les deux instructions using , le code suivant ne fonctionnera pas.
  2. Toujours dans MainGame.cs , ajoutez l'initialisation Firebase à la méthode Start() existante en appelant InitializeFirebaseAndStartGame() :
    void Start()
    {
      Screen.SetResolution(Screen.width / 2, Screen.height / 2, true);
      InitializeFirebaseAndStartGame();
    }
    
  3. Et encore une fois, dans MainGame.cs , recherchez InitializeFirebaseAndStartGame() , déclarez une variable d'application, puis écrasez l'implémentation de la méthode comme ceci :
    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");
          }
        });
    }
    

Placer la logique d'initialisation ici empêche l'interaction du joueur avant que les dépendances Firebase ne soient initialisées.

Les avantages et les effets du signalement des exceptions non gérées comme fatales sont abordés dans la FAQ Crashlytics .

Construisez votre projet et téléchargez des symboles

Les étapes de création et de téléchargement de symboles sont différentes pour les applications iOS et Android.

iOS+ (plateforme Apple)

  1. Dans la boîte de dialogue Paramètres de construction , exportez votre projet vers un espace de travail Xcode.
  2. Créez votre application.
    Pour les plates-formes Apple, le plugin Firebase Unity Editor configure automatiquement votre projet Xcode pour générer et télécharger un fichier de symboles compatible Crashlytics sur les serveurs Firebase pour chaque build. Ces informations sur les symboles sont nécessaires pour voir les traces de pile symbolisées dans le tableau de bord Crashlytics.

Android

  1. (uniquement lors de la configuration initiale, pas pour chaque build) Configurez votre build :
    1. Créez un nouveau dossier appelé Builds à la racine du répertoire de votre projet (c'est-à-dire en tant que frère de votre répertoire Assets ), puis créez un sous-dossier appelé Android .
    2. Dans File > Build Settings > Player Settings > Configuration , définissez Scripting Backend sur IL2CPP.
      • IL2CPP entraîne généralement des builds plus petits et de meilleures performances.
      • IL2CPP est également la SEULE option disponible sur iOS et la sélectionner ici permet aux deux plates-formes d'être en meilleure parité et de simplifier les différences de débogage entre les deux (si vous choisissez de créer les deux).
  2. Créez votre application. Dans Fichier > Paramètres de construction , procédez comme suit :
    1. Assurez-vous que Create symbol.zip est coché (ou si une liste déroulante s'affiche, sélectionnez Debugging ).
    2. Créez votre APK directement depuis l'éditeur Unity dans le sous-dossier Builds/Android que vous venez de créer.
  3. Une fois votre build terminé, vous devez générer un fichier de symboles compatible Crashlytics et le télécharger sur les serveurs Firebase. Ces informations sur les symboles sont nécessaires pour afficher les traces de pile symbolisées pour les pannes de bibliothèque native dans le tableau de bord Crashlytics.

    Générez et téléchargez ce fichier de symboles en exécutant la commande Firebase CLI suivante :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
    • FIREBASE_APP_ID : votre identifiant d'application Android Firebase (et non le nom de votre package). Recherchez cette valeur dans le fichier google-services.json que vous avez téléchargé précédemment. C'est la valeur mobilesdk_app_id .
      Exemple d'ID d'application Android Firebase : 1:567383003300:android:17104a2ced0c9b9b
    • PATH/TO/SYMBOLS : le chemin du fichier de symboles compressé généré dans le répertoire Builds/Android une fois votre build terminé (par exemple : Builds/Android/myapp-1.0-v100.symbols.zip ).

Forcer un crash test pour terminer la configuration

Pour terminer la configuration de Crashlytics et consulter les données initiales dans le tableau de bord Crashlytics de la console Firebase, vous devez forcer un crash de test.

  1. Dans MainGameScene, recherchez le EmptyObject GameObject dans l'éditeur Hierarchy , ajoutez-y le script suivant, puis enregistrez la scène. Ce script provoquera un crash de test quelques secondes après l'exécution de votre application.
    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. Créez votre application et téléchargez les informations sur les symboles une fois votre construction terminée.
    • iOS : Le plugin Firebase Unity Editor configure automatiquement votre projet Xcode pour télécharger votre fichier de symboles.
    • Android : exécutez la commande Firebase CLI crashlytics:symbols:upload pour télécharger votre fichier de symboles.
  3. Exécutez votre application. Une fois votre application en cours d'exécution, surveillez le journal de l'appareil et attendez que l'exception se déclenche à partir de CrashlyticsTester .
    • iOS : affichez les journaux dans le volet inférieur de Xcode.
    • Android : affichez les journaux en exécutant la commande suivante dans le terminal : adb logcat .
  4. Visitez le tableau de bord Crashlytics pour voir l'exception ! Vous le verrez dans le tableau Problèmes en bas du tableau de bord. Plus loin dans l'atelier de programmation, vous en apprendrez davantage sur la manière d'explorer ces rapports.
  5. Une fois que vous avez confirmé que l'événement a été téléchargé sur Crashlytics, sélectionnez l' EmptyObject GameObject auquel vous l'avez attaché, supprimez uniquement le composant CrashlyticsTester , puis enregistrez la scène pour la restaurer dans son état d'origine.

5. Activer et comprendre le menu de débogage

Jusqu'à présent, vous avez ajouté Crashlytics à votre projet Unity, terminé la configuration et confirmé que le SDK Crashlytics télécharge les événements sur Firebase. Vous allez maintenant créer un menu dans votre projet Unity qui montrera comment utiliser les fonctionnalités Crashlytics plus avancées dans votre jeu. Le projet Level Up with Firebase Unity dispose déjà d'un menu de débogage caché que vous rendrez visible et pour lequel vous écrirez les fonctionnalités.

Activer le menu de débogage

Le bouton permettant d'accéder au menu Debug existe dans votre projet Unity, mais il n'est pas actuellement activé. Vous devez activer le bouton pour y accéder depuis le préfabriqué MainMenu :

  1. Dans l'éditeur Unity, ouvrez le préfabriqué nommé MainMenu . 4148538cbe9f36c5.png
  2. Dans la hiérarchie préfabriquée, recherchez le sous-objet désactivé nommé DebugMenuButton , puis sélectionnez-le. 816f8f9366280f6c.png
  3. Activez le DebugMenuButton en cochant la case dans le coin supérieur gauche à gauche du champ de texte contenant DebugMenuButton . 8a8089d2b4886da2.png
  4. Enregistrez le préfabriqué.
  5. Exécutez le jeu dans l'éditeur ou sur votre appareil. Le menu devrait maintenant être accessible.

Prévisualisez et comprenez les corps de méthode pour le menu Debug

Plus loin dans cet atelier de programmation, vous écrirez des corps de méthode pour certaines méthodes Crashlytics de débogage préconfigurées. Cependant, dans le projet Level Up with Firebase Unity, les méthodes sont définies et appelées depuis DebugMenu.cs .

Bien que certaines de ces méthodes appellent à la fois des méthodes Crashlytics et génèrent des erreurs, la capacité de Crashlytics à détecter ces erreurs ne dépend pas de l'appel préalable de ces méthodes. Au lieu de cela, les rapports d'erreur générés par la détection automatique des erreurs seront améliorés par les informations ajoutées par ces méthodes.

Ouvrez DebugMenu.cs , puis recherchez les méthodes suivantes :

Méthodes de génération et d'annotation des problèmes Crashlytics :

  • CrashNow
  • LogNonfatalError
  • LogStringsAndCrashNow
  • SetAndOverwriteCustomKeyThenCrash
  • SetLogsAndKeysBeforeANR

Méthodes de journalisation des événements Analytics pour faciliter le débogage :

  • LogProgressEventWithStringLiterals
  • LogIntScoreWithBuiltInEventAndParams

Dans les étapes ultérieures de cet atelier de programmation, vous mettrez en œuvre ces méthodes et découvrirez comment elles permettent de résoudre des situations spécifiques pouvant survenir lors du développement de jeux.

6. Assurer la livraison des rapports d'accident en cours de développement

Avant de commencer à implémenter ces méthodes de débogage et de voir comment elles affectent les rapports de plantage, assurez-vous de comprendre comment les événements sont signalés à Crashlytics.

Pour les projets Unity, les événements de crash et d'exception de votre jeu sont immédiatement écrits sur le disque. Pour les exceptions non interceptées qui ne font pas planter votre jeu (par exemple, les exceptions C# non interceptées dans la logique du jeu), vous pouvez demander au SDK Crashlytics de les signaler comme événements fatals en définissant la propriété Crashlytics.ReportUncaughtExceptionsAsFatal sur true à l'endroit où vous initialisez Crashlytics dans votre projet Unity. . Ces événements sont signalés à Crashlytics en temps réel sans qu'il soit nécessaire pour l'utilisateur final de redémarrer le jeu. Notez que les crashs natifs sont toujours signalés comme des événements fatals et envoyés lorsqu'un utilisateur final redémarre le jeu.

De plus, soyez conscient des différences petites, mais significatives, suivantes entre la manière dont les différents environnements d'exécution envoient les informations Crashlytics à Firebase :

Simulateur iOS :

  • Les informations Crashlytics sont signalées si et seulement si vous détachez Xcode du simulateur. Si Xcode est joint, il détecte les erreurs en amont, empêchant la livraison des informations.

Appareils physiques mobiles (Android et iOS) :

  • Spécifique à Android : les ANR ne sont signalés que sur Android 11+. Les ANR et les événements non mortels sont signalés lors de l'exécution suivante.

Éditeur Unity :

Testez le crash de votre jeu en appuyant simplement sur un bouton dans CrashNow()

Une fois Crashlytics configuré dans votre jeu, le SDK Crashlytics enregistre automatiquement les plantages et les exceptions non détectées et les télécharge sur Firebase pour analyse. Et les rapports sont affichés dans le tableau de bord Crashlytics de la console Firebase.

  1. Pour démontrer que c'est effectivement automatique : ouvrez DebugMenu.cs , puis écrasez la méthode CrashNow() comme suit :
    void CrashNow()
    {
        TestCrash();
    }
    
  2. Créez votre application.
  3. (Android uniquement) Téléchargez vos symboles en exécutant la commande Firebase CLI suivante :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Appuyez sur le bouton Crash Now et passez à l'étape suivante de cet atelier de programmation pour découvrir comment afficher et interpréter le rapport de crash.

7. Comprendre les rapports de problèmes dans la console Firebase

Lorsqu'il s'agit d'afficher vos rapports d'erreur, vous devez en savoir un peu plus sur la façon d'en tirer le meilleur parti. Chacune des méthodes que vous écrivez montrera comment ajouter différents types d'informations aux rapports Crashlytics.

  1. Appuyez sur le bouton Crash Now , puis redémarrez votre application.
  2. Accédez au tableau de bord Crashlytics . Faites défiler jusqu'au tableau Problèmes en bas du tableau de bord, où Crashlytics regroupe les événements qui ont tous la même cause première en « problèmes ».
  3. Cliquez sur le nouveau problème répertorié dans le tableau Problèmes . Cela affiche le résumé de l'événement pour chaque événement individuel envoyé à Firebase.

    Vous devriez voir quelque chose comme la capture d'écran suivante. Remarquez comment le résumé de l'événement met en évidence la trace de pile de l'appel qui a conduit au crash. 40c96abe7f90c3aa.png

Métadonnées supplémentaires

Un autre onglet utile est l'onglet Métadonnées Unity . Cette section vous informe sur les attributs de l'appareil sur lequel l'événement s'est produit, y compris les caractéristiques physiques, le modèle/les spécifications du processeur et toutes sortes de métriques GPU.

Voici un exemple où les informations de cet onglet peuvent être utiles :
Imaginez que votre jeu utilise beaucoup de shaders pour obtenir un certain look, mais tous les téléphones ne disposent pas de GPU capables de restituer cette fonctionnalité. Les informations contenues dans l'onglet Métadonnées Unity peuvent vous donner une meilleure idée du matériel que votre application doit tester pour décider quelles fonctionnalités rendre automatiquement disponibles ou désactiver entièrement.

Bien qu'un bug ou un crash puisse ne jamais se produire sur votre appareil, en raison de la grande diversité des appareils Android dans la nature, cela aide à mieux comprendre les « points chauds » particuliers des appareils de votre public.

41d8d7feaa87454d.png

8. Lancez, interceptez et enregistrez une exception

Souvent, en tant que développeur, même si votre code détecte et gère correctement une exception d'exécution, il est bon de noter qu'elle s'est produite et dans quelles circonstances. Crashlytics.LogException peut être utilisé dans ce but précis : envoyer un événement d'exception à Firebase afin que vous puissiez déboguer davantage le problème dans la console Firebase.

  1. Dans Assets/Hamster/Scripts/States/DebugMenu.cs , ajoutez ce qui suit aux instructions using :
    // Import Firebase
    using Firebase.Crashlytics;
    
  2. Toujours dans DebugMenu.cs , écrasez LogNonfatalError() comme suit :
    void LogNonfatalError()
    {
        try
        {
            throw new System.Exception($"Test exception thrown in {nameof(LogNonfatalError)}");
        }
        catch(System.Exception exception)
        {
            Crashlytics.LogException(exception);
        }
    }
    
  3. Créez votre application.
  4. (Android uniquement) Téléchargez vos symboles en exécutant la commande Firebase CLI suivante :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  5. Appuyez sur le bouton Consigner les erreurs non fatales , puis redémarrez votre application.
  6. Accédez au tableau de bord Crashlytics et vous devriez voir quelque chose de similaire à ce que vous avez vu lors de la dernière étape de cet atelier de programmation.
  7. Cette fois, cependant, limitez le filtre de type d'événement à Non fatals afin que vous n'affichiez que les erreurs non fatales, telles que celle que vous venez d'enregistrer.
    a39ea8d9944cbbd9.png

9. Enregistrez les chaînes dans Crashlytics pour mieux comprendre le flux d'exécution du programme

Avez-vous déjà essayé de comprendre pourquoi une ligne de code appelée depuis plusieurs chemins, des centaines, voire des milliers de fois par session, peut soudainement générer une exception ou un crash ? Même s'il peut être intéressant de parcourir le code dans un IDE et d'examiner les valeurs de plus près, que se passe-t-il si cela ne se produit que parmi un pourcentage infime de vos utilisateurs ? Pire encore, que feriez-vous si vous ne parveniez pas à reproduire ce crash, quoi que vous fassiez ?

Dans des situations comme celle-ci, avoir un certain contexte peut faire toute la différence. Avec Crashlytics.Log , vous avez la possibilité d'écrire le contexte dont vous avez besoin. Considérez ces messages comme des indices pour votre avenir sur ce qui pourrait se passer.

Bien que les journaux puissent être utilisés de multiples façons, ils sont généralement très utiles pour enregistrer des situations dans lesquelles l'ordre et/ou l'absence d'appels constituent une information d'une importance vitale.

  1. Dans Assets/Hamster/Scripts/States/DebugMenu.cs , remplacez LogStringsAndCrashNow() comme suit :
    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. Créez votre application.
  3. (Android uniquement) Téléchargez vos symboles en exécutant la commande Firebase CLI suivante :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Appuyez sur le bouton Log Strings and Crash Now , puis redémarrez votre application.
  5. Revenez au tableau de bord Crashlytics et cliquez sur le problème le plus récent répertorié dans le tableau Problèmes . Encore une fois, vous devriez voir quelque chose de similaire aux problèmes précédents.
    7aabe103b8589cc7.png
  6. Cependant, si vous cliquez sur l'onglet Journaux dans un résumé d'événement , vous obtenez une vue comme celle-ci :
    4e27aa407b7571cf.png

10. Écrivez et écrasez une clé personnalisée

Disons que vous souhaitez mieux comprendre un crash correspondant à des variables définies sur un petit nombre de valeurs ou de configurations. Il pourrait être intéressant de pouvoir filtrer, en fonction de la combinaison de variables et de valeurs possibles que vous examinez, à un moment donné.

En plus de journaliser les chaînes arbitraires, Crashlytics propose une autre forme de débogage lorsqu'il est avantageux de connaître l'état exact de votre programme au moment de son crash : les clés personnalisées.

Il s'agit de paires clé-valeur que vous pouvez définir pour une session. Contrairement aux journaux qui s'accumulent et sont purement additifs, les clés peuvent être écrasées pour refléter uniquement l'état le plus récent d'une variable ou d'une condition.

En plus d'être un registre du dernier état enregistré de votre programme, ces clés peuvent ensuite être utilisées comme de puissants filtres pour les problèmes Crashlytics.

  1. Dans Assets/Hamster/Scripts/States/DebugMenu.cs , remplacez SetAndOverwriteCustomKeyThenCrash() comme suit :
    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. Créez votre application.
  3. (Android uniquement) Téléchargez vos symboles en exécutant la commande Firebase CLI suivante :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Appuyez sur le bouton Définir une clé personnalisée et un crash , puis redémarrez votre application.
  5. Revenez au tableau de bord Crashlytics et cliquez sur le problème le plus récent répertorié dans le tableau Problèmes . Encore une fois, vous devriez voir quelque chose de similaire aux problèmes précédents.
  6. Cette fois, cependant, cliquez sur l'onglet Clés dans le résumé de l'événement afin de pouvoir afficher la valeur des clés, y compris Current Time :
    7dbe1eb00566af98.png

Pourquoi voudriez-vous utiliser des clés personnalisées au lieu de journaux personnalisés ?

  • Les journaux sont efficaces pour stocker des données séquentielles, mais les clés personnalisées sont préférables si vous souhaitez uniquement la valeur la plus récente .
  • Dans la console Firebase, vous pouvez facilement filtrer les problèmes en fonction des valeurs des clés dans la zone de recherche du tableau Problèmes .

Cependant, comme pour les journaux, les clés personnalisées ont une limite. Crashlytics prend en charge un maximum de 64 paires clé-valeur. Une fois ce seuil atteint, les valeurs supplémentaires ne sont pas enregistrées. Chaque paire clé-valeur peut atteindre 1 Ko.

11. (Android uniquement) Utilisez des clés et des journaux personnalisés pour comprendre et diagnostiquer un ANR

L’erreur ANR ( Application Not Responding ) est l’une des catégories de problèmes les plus difficiles à déboguer pour les développeurs Android. Les ANR se produisent lorsqu'une application ne répond pas à une entrée pendant plus de 5 secondes. Si cela se produit, cela signifie que l'application est gelée ou fonctionne très lentement. Une boîte de dialogue s'affiche pour les utilisateurs et ils peuvent choisir entre « Attendre » ou « Fermer l'application ».

Les ANR constituent une mauvaise expérience utilisateur et (comme mentionné dans le lien ANR ci-dessus) peuvent affecter la visibilité de votre application dans le Google Play Store. En raison de leur complexité et du fait qu'ils sont souvent provoqués par du code multithread ayant un comportement très différent sur différents modèles de téléphone, la reproduction des ANR pendant le débogage est souvent très difficile, voire presque impossible. En tant que tel, les aborder de manière analytique et déductive est généralement la meilleure approche.

Dans cette méthode, nous utiliserons une combinaison de Crashlytics.LogException , Crashlytics.Log et Crashlytics.SetCustomKey pour compléter la journalisation automatique des problèmes et pour nous donner plus d'informations.

  1. Dans Assets/Hamster/Scripts/States/DebugMenu.cs , remplacez SetLogsAndKeysBeforeANR() comme suit :
    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. Créez votre application.
  3. Téléchargez vos symboles en exécutant la commande Firebase CLI suivante :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Appuyez sur le bouton intitulé Définir les journaux et les clés → ANR , puis redémarrez votre application.
  5. Revenez au tableau de bord Crashlytics , puis cliquez sur le nouveau problème dans le tableau Problèmes pour afficher le résumé de l'événement . Si l'appel s'est bien déroulé, vous devriez voir quelque chose comme ceci :
    876c3cff7037bd07.png

    Comme vous pouvez le voir, Firebase a identifié l'attente occupée sur le fil de discussion comme la principale raison pour laquelle votre application a déclenché un ANR.
  6. Si vous regardez les journaux dans l'onglet Journaux du résumé des événements , vous verrez que la dernière méthode enregistrée comme terminée est DoSevereWork .
    5a4bec1cf06f6984.png

    En revanche, la dernière méthode répertoriée comme démarrante est DoExtremeWork , ce qui indique que l'ANR s'est produite au cours de cette méthode et que le jeu s'est fermé avant de pouvoir enregistrer DoExtremeWork .

    89d86d5f598ecf3a.png

Pourquoi faire ceci?

  • La reproduction des ANR est incroyablement difficile, il est donc extrêmement important de pouvoir obtenir des informations riches sur la zone de code et les métriques pour les découvrir de manière déductive.
  • Grâce aux informations stockées dans les clés personnalisées, vous savez désormais quel thread asynchrone a mis le plus de temps à s'exécuter et lesquels risquaient de déclencher des ANR. Ce type de données logiques et numériques associées vous montrera où dans votre code il est le plus nécessaire d'optimiser.

12. Intercaler les événements Analytics pour enrichir davantage les rapports

Les méthodes suivantes peuvent également être appelées à partir du menu Debug, mais au lieu de générer elles-mêmes des problèmes, elles utilisent Google Analytics comme autre source d'informations pour mieux comprendre le fonctionnement de votre jeu.

Contrairement aux autres méthodes que vous avez écrites dans cet atelier de programmation, vous devez utiliser ces méthodes en combinaison avec les autres. Appelez ces méthodes (en appuyant sur le bouton correspondant dans le menu Debug) dans l'ordre arbitraire souhaité avant d'exécuter l'une des autres. Ensuite, lorsque vous examinez les informations du problème Crashlytics spécifique, vous verrez un journal ordonné des événements Analytics. Ces données peuvent être utilisées dans un jeu pour mieux comprendre une combinaison de flux de programme ou d'entrées utilisateur, en fonction de la manière dont vous avez instrumenté votre application.

  1. Dans Assets/Hamster/Scripts/States/DebugMenu.cs , remplacez les implémentations existantes des méthodes suivantes :
    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. Créez et déployez votre jeu, puis entrez dans le menu Debug .
  3. (Android uniquement) Téléchargez vos symboles en exécutant la commande Firebase CLI suivante :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Appuyez une ou plusieurs fois sur au moins un des boutons suivants pour appeler les fonctions ci-dessus :
    • Événement de chaîne de journal
    • Événement de connexion
  5. Appuyez sur le bouton Crash maintenant .
  6. Redémarrez votre jeu pour qu'il télécharge l'événement de crash sur Firebase.
  7. Lorsque vous enregistrez diverses séquences arbitraires d'événements Analytics et que votre jeu génère ensuite un événement à partir duquel Crashlytics crée un rapport (comme vous venez de le faire), ils sont ajoutés à l'onglet Journaux du résumé des événements Crashlytics comme ceci :
    d3b16d78f76bfb04.png

13. Aller de l'avant

Et avec cela, vous devriez disposer d’une meilleure base théorique sur laquelle compléter vos rapports d’accident générés automatiquement. Ces nouvelles informations vous permettent d'utiliser l'état actuel, les enregistrements d'événements passés et les événements Google Analytics existants pour mieux décomposer la séquence d'événements et la logique qui a conduit à son résultat.

Si votre application cible Android 11 (API niveau 30) ou supérieur, envisagez d'incorporer GWP-ASan , une fonctionnalité d'allocation de mémoire native utile pour le débogage des plantages causés par des erreurs de mémoire native telles que les bogues use-after-free et heap-buffer-overflow . Pour profiter de cette fonctionnalité de débogage, activez explicitement GWP-ASan .

Prochaines étapes

Passez à l'atelier de programmation Instrumenter votre jeu Unity avec Remote Config , où vous découvrirez l'utilisation de Remote Config et des tests A/B dans Unity.