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

1. Introduction

Dans cet atelier de programmation, vous allez apprendre à utiliser les fonctionnalités avancées de Crashlytics, qui vous permettront de mieux comprendre les plantages et les circonstances qui ont pu les provoquer.

Vous allez ajouter de nouvelles fonctionnalités à un exemple de jeu, MechaHamster: Level Up with Firebase Edition. Ce jeu exemple est une nouvelle version du jeu Firebase classique MechaHamster. La plupart de ses fonctionnalités Firebase intégrées ont été supprimées pour vous permettre d'implémenter de nouvelles utilisations de Firebase à la place.

Vous allez ajouter 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 expliquent comment annoter vos rapports d'erreur automatiques avec des clés personnalisées, des journaux personnalisés, des erreurs non fatales et plus encore.

Après avoir développé le jeu, vous utiliserez le menu de débogage et inspecterez les résultats pour comprendre la vue unique qu'ils fournissent sur le fonctionnement de votre jeu en conditions réelles.

Points abordés

  • Types d'erreurs détectées automatiquement par Crashlytics.
  • Erreurs supplémentaires pouvant être enregistrées volontairement.
  • Ajouter des informations à ces erreurs pour les rendre plus faciles à comprendre

Prérequis

  • Unity (version minimale recommandée 2019+) avec l'un des éléments suivants (ou les deux) :
    • Assistance pour la compilation iOS
    • Assistance pour la compilation Android
  • (Android uniquement) La CLI Firebase (utilisée pour importer des symboles pour les rapports d'erreur)

2. Configurer l'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. Il est donc possible que vous ayez déjà effectué les tâches de cette section. Si c'est le cas, vous pouvez passer directement à la dernière étape de cette page : "Ajouter les SDK Firebase pour Unity".

Télécharger 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

Si vous n'avez pas installé git, vous pouvez également télécharger le dépôt sous forme de fichier ZIP.

Ouvrez Passez au niveau supérieur avec Firebase dans l'éditeur Unity.

  1. Lancez Unity Hub, puis dans l'onglet Projets, cliquez sur la flèche du menu déroulant à côté 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, pour l'ouvrir dans l'éditeur Unity.
  6. Si votre éditeur ne l'ouvre pas automatiquement, ouvrez MainGameScene dans Assets > Hamster dans l'onglet Project (Projet) de l'éditeur Unity.
    ff4ea3f3c0d29379.png

Pour en savoir plus sur l'installation et l'utilisation d'Unity, consultez Travailler dans Unity.

3. Ajouter Firebase à votre projet Unity

Créer un projet Firebase

  1. Connectez-vous à la console Firebase à l'aide de votre compte Google.
  2. Cliquez sur le bouton pour créer un projet, puis saisissez un nom de projet (par exemple, Mechahamster Codelab).
  3. Cliquez sur Continuer.
  4. Si vous y êtes invité, lisez et acceptez les Conditions d'utilisation de Firebase, puis cliquez sur Continuer.
  5. (Facultatif) Activez l'assistance IA dans la console Firebase (appelée "Gemini dans Firebase").
  6. Pour cet atelier de programmation, vous avez besoin de Google Analytics pour utiliser de manière optimale les produits Firebase. Par conséquent, laissez l'option Google Analytics activée. Suivez les instructions à l'écran pour configurer Google Analytics.
  7. Cliquez sur Créer un projet, attendez que votre projet soit provisionné, puis cliquez sur Continuer.

Enregistrer votre application auprès de Firebase

  1. Toujours dans la console Firebase, au centre de la page de présentation du projet, cliquez sur l'icône Unity pour lancer le processus de configuration. Si vous avez déjà ajouté une application à votre projet Firebase, cliquez sur Ajouter une application pour afficher les options de plate-forme.
  2. Sélectionnez cette option pour enregistrer les cibles de build Apple (iOS) et Android.
  3. Saisissez le ou les ID spécifiques à la plate-forme de votre projet Unity. Pour cet atelier de programmation, saisissez ce qui suit :
  4. (Facultatif) Saisissez le ou les pseudonymes spécifiques à la plate-forme de votre projet Unity.
  5. Cliquez sur Enregistrer l'application, puis accédez à la section Télécharger le fichier de configuration.

Ajouter des fichiers de configuration Firebase

Après avoir cliqué sur Register app (Enregistrer l'application), vous serez invité à télécharger deux fichiers de configuration (un pour chaque cible de compilation). Votre projet Unity a besoin des métadonnées Firebase 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 Project (Projet) de votre projet Unity, puis déplacez les deux fichiers de configuration dans le dossier Assets (Éléments).
  3. De retour dans la console Firebase, dans le workflow de configuration, cliquez sur Suivant et passez à l'ajout des SDK Firebase pour Unity.

Ajouter les SDK Firebase pour Unity

  1. Cliquez sur Télécharger le SDK Unity Firebase dans la console Firebase.
  2. Décompressez le SDK à l'emplacement de votre choix.
  3. Dans votre projet Unity ouvert, accédez à Assets (Éléments) > Import Package (Importer un package) > Custom Package (Package personnalisé).
  4. Dans la boîte de dialogue Importer un 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 Import Unity Package (Importer un package Unity) qui s'affiche, cliquez sur Import (Importer).
  6. Répétez les étapes précédentes pour importer FirebaseCrashlytics.unitypackage.
  7. Revenez à la console Firebase, puis cliquez sur Suivant dans le workflow de configuration.

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

4. Configurer Crashlytics dans votre projet Unity

Pour utiliser Crashlytics dans les projets Unity, vous devez effectuer quelques étapes de configuration supplémentaires. Bien sûr, vous devrez initialiser le SDK. Vous devrez également importer vos symboles pour pouvoir afficher les traces de pile symbolisées dans la console Firebase et forcer un plantage de test pour vous assurer que Firebase reçoit vos événements de plantage.

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, tandis que le second contient des extensions de l'API Tasks C#. Sans les deux instructions using, le code suivant ne fonctionnera pas.
  2. Toujours dans MainGame.cs, ajoutez l'initialisation de Firebase à la méthode Start() existante en appelant InitializeFirebaseAndStartGame() :
    void Start()
    {
      Screen.SetResolution(Screen.width / 2, Screen.height / 2, true);
      InitializeFirebaseAndStartGame();
    }
    
  3. Ensuite, dans MainGame.cs, recherchez InitializeFirebaseAndStartGame(), déclarez une variable d'application, puis remplacez l'implémentation de la méthode comme suit :
    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 lecteur avant l'initialisation des dépendances Firebase.

Les avantages et les effets de la signalisation des exceptions non gérées en tant qu'erreurs fatales sont abordés dans les questions fréquentes Crashlytics.

Créer votre projet et importer des symboles

La procédure de création et d'importation des symboles diffère pour les applications iOS et Android.

iOS+ (plate-forme Apple)

  1. Dans la boîte de dialogue Build Settings (Paramètres de compilation), exportez votre projet vers un espace de travail Xcode.
  2. Créez votre application.
    Pour les plates-formes Apple, le plug-in Firebase Unity Editor configure automatiquement votre projet Xcode pour générer et importer un fichier de symboles compatible avec Crashlytics sur les serveurs Firebase pour chaque build. Ces informations sur les symboles sont nécessaires pour afficher 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 dossier nommé Builds à la racine du répertoire de votre projet (c'est-à-dire au même niveau que votre répertoire Assets), puis créez un sous-dossier nommé Android.
    2. Dans File (Fichier) > Build Settings (Paramètres de compilation) > Player Settings (Paramètres du lecteur) > Configuration, définissez le backend de script sur IL2CPP.
      • IL2CPP permet généralement de réduire la taille des builds et d'améliorer leurs performances.
      • IL2CPP est également la SEULE option disponible sur iOS. La sélectionner ici permet aux deux plates-formes d'être plus équivalentes et de simplifier le débogage des différences entre les deux (si vous choisissez de créer les deux).
  2. Compilez votre application. Dans File (Fichier) > Build Settings (Paramètres de compilation), procédez comme suit :
    1. Assurez-vous que l'option Create symbols.zip est cochée (ou sélectionnez Debugging dans le menu déroulant).
    2. Créez votre APK directement à partir de l'éditeur Unity dans le sous-dossier Builds/Android que vous venez de créer.
  3. Une fois votre compilation terminée, vous devez générer un fichier de symboles compatible avec Crashlytics et l'importer sur les serveurs Firebase. Ces informations sur les symboles sont nécessaires pour afficher les traces de pile symbolisées pour les plantages de bibliothèques natives dans le tableau de bord Crashlytics.

     Générez et importez ce fichier de symboles en exécutant la commande CLI Firebase suivante :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
    • FIREBASE_APP_ID : ID de votre application Firebase pour Android (et non le nom de votre package). Vous trouverez cette valeur dans le fichier google-services.json que vous avez téléchargé précédemment. Il s'agit de la valeur mobilesdk_app_id.
      Exemple d'ID d'application Android Firebase : 1:567383003300:android:17104a2ced0c9b9b
    • PATH/TO/SYMBOLS : chemin d'accès au fichier de symboles compressé généré dans le répertoire Builds/Android à la fin de la compilation (par exemple, Builds/Android/myapp-1.0-v100.symbols.zip).

Forcer un plantage test pour terminer la configuration

Pour terminer la configuration de Crashlytics et afficher les premières données dans le tableau de bord Crashlytics de la console Firebase, vous devez forcer un plantage de test.

  1. Dans MainGameScene, recherchez l'EmptyObjectGameObject dans la hiérarchie de l'éditeur, ajoutez-y le script suivant, puis enregistrez la scène. Ce script provoquera un plantage 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 importez les informations sur les symboles une fois la compilation terminée.
    • iOS : le plug-in Firebase Unity Editor configure automatiquement votre projet Xcode pour importer votre fichier de symboles.
    • Android : exécutez la commande crashlytics:symbols:upload de la CLI Firebase pour importer 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. Accédez au tableau de bord Crashlytics pour afficher l'exception. Vous le trouverez dans le tableau Problèmes en bas du tableau de bord. Vous découvrirez comment explorer ces rapports plus loin dans cet atelier de programmation.
  5. Une fois que vous avez confirmé que l'événement a été importé dans Crashlytics, sélectionnez l'EmptyObject GameObject auquel vous l'avez associé, 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 des événements sur Firebase. Vous allez maintenant créer un menu dans votre projet Unity qui montrera comment utiliser des fonctionnalités Crashlytics plus avancées dans votre jeu. Le projet Unity Passez au niveau supérieur avec Firebase comporte déjà un menu de débogage masqué que vous allez rendre visible et pour lequel vous allez écrire la fonctionnalité.

Activer le menu de débogage

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

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

Prévisualiser et comprendre les corps de méthode pour le menu de débogage

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. Toutefois, dans le projet Unity Level Up with Firebase, les méthodes sont définies dans DebugMenu.cs et appelées à partir de ce fichier.

Bien que certaines de ces méthodes appellent 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 de ces méthodes en premier. Les rapports d'erreur générés à partir des erreurs détectées automatiquement 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 pour enregistrer des événements Analytics afin de faciliter le débogage :

  • LogProgressEventWithStringLiterals
  • LogIntScoreWithBuiltInEventAndParams

Dans les étapes suivantes de cet atelier de programmation, vous allez implémenter ces méthodes et découvrir comment elles permettent de résoudre des situations spécifiques pouvant survenir lors du développement de jeux.

6. Assurer l'envoi des rapports d'erreur en cours de développement

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

Pour les projets Unity, les événements de plantage et d'exception dans votre jeu sont immédiatement écrits sur le disque. Pour les exceptions non détectées qui ne plantent pas votre jeu (par exemple, les exceptions C# non détectées dans la logique du jeu), vous pouvez demander au SDK Crashlytics de les signaler en tant qu'événements fatals en définissant la propriété Crashlytics.ReportUncaughtExceptionsAsFatal sur true lorsque vous initialisez Crashlytics dans votre projet Unity. Ces événements sont signalés à Crashlytics en temps réel, sans que l'utilisateur final ait besoin de redémarrer le jeu. Notez que les plantages natifs sont toujours signalés comme des événements fatals et envoyés lorsqu'un utilisateur final redémarre le jeu.

De plus, tenez compte des petites, mais importantes, différences suivantes entre la façon dont les différents environnements d'exécution envoient les informations Crashlytics à Firebase :

Simulateur iOS :

  • Les informations Crashlytics ne sont signalées que si vous détachez Xcode du simulateur. Si Xcode est associé, il détecte les erreurs en amont, ce qui empêche la transmission des informations.

Appareils mobiles physiques (Android et iOS) :

  • Spécifique à Android : les ANR ne sont signalées que sur Android 11 et versions ultérieures. Les ANR et les événements non fatals sont signalés lors de la prochaine exécution.

Éditeur Unity :

Testez le plantage de votre jeu en appuyant sur un bouton dans CrashNow().

Une fois Crashlytics configuré dans votre jeu, le SDK Crashlytics enregistre automatiquement les plantages et les exceptions non interceptées, puis les importe dans Firebase pour analyse. Les rapports s'affichent dans le tableau de bord Crashlytics de la console Firebase.

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

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

Pour consulter vos rapports d'erreur et en tirer le meilleur parti, vous devez en savoir un peu plus. Chacune des méthodes que vous écrivez montre comment ajouter différents types d'informations aux rapports Crashlytics.

  1. Appuyez sur le bouton Plantage immédiat, puis redémarrez votre application.
  2. Accédez au tableau de bord Crashlytics. Faites défiler la page jusqu'au tableau Problèmes en bas du tableau de bord. Crashlytics y regroupe les événements ayant la même cause première dans des "problèmes".
  3. Cliquez sur le nouveau problème listé dans le tableau Problèmes. Vous verrez alors le récapitulatif des événements pour chaque événement envoyé à Firebase.

    Vous devriez voir quelque chose comme la capture d'écran suivante. Notez que le Résumé des événements met en évidence la trace de pile de l'appel qui a entraîné le plantage.40c96abe7f90c3aa.png

Métadonnées supplémentaires

L'onglet Métadonnées Unity est également utile. 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 nuanceurs pour obtenir un certain rendu, mais que tous les téléphones ne disposent pas de GPU capables d'afficher cette fonctionnalité. Les informations de l'onglet Métadonnées Unity peuvent vous donner une meilleure idée du matériel pour lequel votre application doit être testée lorsque vous décidez des fonctionnalités à rendre automatiquement disponibles ou à désactiver complètement.

Même si un bug ou un plantage ne se produit jamais sur votre appareil, en raison de la grande diversité des appareils Android, il est utile de mieux comprendre les "points chauds" spécifiques des appareils de votre audience.

41d8d7feaa87454d.png

8. Générer, intercepter et consigner une exception

En tant que développeur, même si votre code intercepte et gère correctement une exception d'exécution, il est souvent utile de noter qu'elle s'est produite et dans quelles circonstances. Crashlytics.LogException peut être utilisé à cette fin : envoyer un événement d'exception à Firebase pour que vous puissiez déboguer le problème plus en détail dans la console Firebase.

  1. Dans Assets/Hamster/Scripts/States/DebugMenu.cs, ajoutez les éléments suivants aux instructions using :
    // Import Firebase
    using Firebase.Crashlytics;
    
  2. Toujours dans DebugMenu.cs, remplacez 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) Importez vos symboles en exécutant la commande suivante de la CLI Firebase :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  5. Appuyez sur le bouton Consigner l'erreur non fatale, puis redémarrez votre application.
  6. Accédez au tableau de bord Crashlytics. Vous devriez voir quelque chose de similaire à ce que vous avez vu à la dernière étape de cet atelier de programmation.
  7. Cette fois, toutefois, limitez le filtre Type d'événement à Non fatales afin de n'afficher que les erreurs non fatales, comme celle que vous venez de consigner.
    a39ea8d9944cbbd9.png

9. Consigner des 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 à partir de plusieurs chemins d'accès, des centaines, voire des milliers de fois par session, peut soudainement générer une exception ou un plantage ? Bien qu'il puisse être agréable 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 pour un pourcentage infime de vos utilisateurs ? Pire encore, que feriez-vous si vous ne parveniez pas à reproduire ce plantage, quoi que vous fassiez ?

Dans ce type de situation, disposer de quelques informations contextuelles peut faire toute la différence. Avec Crashlytics.Log, vous pouvez écrire le contexte dont vous avez besoin. Considérez ces messages comme des indices pour vous aider à comprendre ce qui se passe.

Bien que les journaux puissent être utilisés de nombreuses façons, ils sont généralement plus utiles pour enregistrer les situations où l'ordre et/ou l'absence d'appels sont des informations essentielles.

  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) Importez vos symboles en exécutant la commande suivante de la CLI Firebase :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Appuyez sur le bouton Log Strings and Crash Now (Enregistrer les chaînes de journaux et planter maintenant), puis redémarrez votre application.
  5. Revenez au tableau de bord Crashlytics, puis cliquez sur le problème le plus récent listé dans le tableau Problèmes. Là encore, vous devriez voir quelque chose de semblable aux problèmes précédents.
    7aabe103b8589cc7.png
  6. Toutefois, si vous cliquez sur l'onglet Journaux dans un récapitulatif des événements, vous obtenez une vue comme celle-ci :
    4e27aa407b7571cf.png

10. Écrire et remplacer une clé personnalisée

Imaginons que vous souhaitiez mieux comprendre un plantage correspondant à des variables définies sur un petit nombre de valeurs ou de configurations. Il peut être utile de pouvoir filtrer les données en fonction de la combinaison de variables et des valeurs possibles que vous examinez à un moment donné.

En plus de l'enregistrement de chaînes arbitraires, Crashlytics propose une autre forme de débogage lorsqu'il est utile de connaître l'état exact de votre programme au moment du plantage : 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 ne refléter que 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 filtres puissants 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) Importez vos symboles en exécutant la commande suivante de la CLI Firebase :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Appuyez sur le bouton Set Custom Key and Crash (Définir une clé personnalisée et un plantage), puis redémarrez votre application.
  5. Revenez au tableau de bord Crashlytics, puis cliquez sur le problème le plus récent listé dans le tableau Problèmes. Là encore, vous devriez voir quelque chose de semblable aux problèmes précédents.
  6. Cette fois, cliquez sur l'onglet Clés dans Récapitulatif de l'événement pour afficher la valeur des clés, y compris Current Time :
    7dbe1eb00566af98.png

Pourquoi utiliser des clés personnalisées plutôt que des journaux personnalisés ?

  • Les journaux sont utiles pour stocker des données séquentielles, mais les clés personnalisées sont plus adaptées si vous ne souhaitez obtenir que la valeur la plus récente.
  • Dans la console Firebase, vous pouvez facilement filtrer les problèmes par valeurs de clés dans le champ de recherche du tableau Problèmes.

Toutefois, comme pour les journaux, les clés personnalisées sont limitées. Crashlytics accepte 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) Utiliser des clés et des journaux personnalisés pour comprendre et diagnostiquer une ANR

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

Les erreurs ANR sont une mauvaise expérience utilisateur et (comme indiqué dans le lien ANR ci-dessus) peuvent affecter la visibilité de votre application sur le Google Play Store. En raison de leur complexité et du fait qu'elles sont souvent causées par du code multithread dont le comportement est très différent selon les modèles de téléphones, il est souvent très difficile, voire impossible, de reproduire les erreurs ANR lors du débogage. Il est donc généralement préférable de les aborder de manière analytique et déductive.

Dans cette méthode, nous allons utiliser une combinaison de Crashlytics.LogException, Crashlytics.Log et Crashlytics.SetCustomKey pour compléter la journalisation automatique des problèmes et obtenir 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. Importez vos symboles en exécutant la commande CLI Firebase suivante :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Appuyez sur le bouton Set Logs And Keys → 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écapitulatif des événements. Si l'appel s'est déroulé correctement, vous devriez voir quelque chose comme ceci :
    876c3cff7037bd07.png

    Comme vous pouvez le voir, Firebase a identifié l'attente active sur le thread comme principale raison pour laquelle votre application a déclenché une ANR.
  6. Si vous consultez les journaux dans l'onglet Journaux de Récapitulatif 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 listée comme démarrée est DoExtremeWork, ce qui indique que l'ANR s'est produite pendant cette méthode et que le jeu s'est fermé avant de pouvoir enregistrer DoExtremeWork.

    89d86d5f598ecf3a.png

À quoi ça sert ?

  • Il est extrêmement difficile de reproduire les ANR. Il est donc très important de pouvoir obtenir des informations détaillées sur la zone de code et les métriques pour les identifier 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 indiquera où il est le plus nécessaire d'optimiser votre code.

12. Insérer des événements Analytics pour enrichir davantage les rapports

Les méthodes suivantes peuvent également être appelées depuis le menu de débogage. Toutefois, au lieu de générer 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 de débogage) dans l'ordre arbitraire de votre choix avant d'en exécuter une autre. Ensuite, lorsque vous examinez les informations d'un problème Crashlytics spécifique, vous voyez 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, selon la façon 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 accédez au menu de débogage.
  3. (Android uniquement) Importez vos symboles en exécutant la commande suivante de la CLI Firebase :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Appuyez sur au moins l'un des boutons suivants une ou plusieurs fois pour appeler les fonctions ci-dessus :
    • Événement de chaîne de journal
    • Événement Log Int
  5. Appuyez sur le bouton Plantage maintenant.
  6. Redémarrez votre jeu pour qu'il importe l'événement de plantage dans Firebase.
  7. Lorsque vous enregistrez différentes séquences arbitraires d'événements Analytics, puis que votre jeu génère un événement à partir duquel Crashlytics crée un rapport (comme vous venez de le faire), ces événements sont ajoutés à l'onglet Journaux du récapitulatif des événements Crashlytics, comme ceci :
    d3b16d78f76bfb04.png

13. Aller plus loin

Vous devriez ainsi disposer d'une base théorique plus solide pour compléter vos rapports d'erreur générés automatiquement. Ces nouvelles informations vous permettent d'utiliser l'état actuel, les enregistrements des é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 ont conduit au résultat.

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

Étapes suivantes

Passez à l'atelier de programmation Instrumenter votre jeu Unity avec Remote Config, où vous apprendrez à utiliser Remote Config et les tests A/B dans Unity.