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 les ont peut-être causés.

Vous allez ajouter une nouvelle fonctionnalité à 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 pouvez ainsi 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 utiliser et vous permet d'utiliser les différentes fonctionnalités de Crashlytics. Ces méthodes vous expliquent 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 le fonctionnement de votre jeu.

Points abordés

  • Types d'erreurs automatiquement détectées par Crashlytics.
  • Autres erreurs qui peuvent être enregistrées volontairement.
  • Ajouter des informations à ces erreurs pour les rendre plus faciles à comprendre

Prérequis

  • Unity (version minimale recommandée 2019 ou version ultérieure) avec l'un ou les deux des éléments suivants:
    • Compatibilité avec iOS Build
    • Compatibilité avec les builds Android
  • (Pour Android uniquement) La CLI Firebase (utilisée pour importer les symboles des rapports d'erreur)

2. Configurer l'environnement de développement

Les sections suivantes expliquent comment télécharger le code Passer à la vitesse supérieure avec 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 et Unity. Vous avez donc peut-être déjà effectué les tâches de cette section. Dans ce 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 git n'est pas installé, vous pouvez également télécharger le dépôt sous forme de fichier ZIP.

Ouvrez Level Up with Firebase dans l'éditeur Unity.

  1. Lancez Unity Hub et, dans l'onglet Projects (Projets), cliquez sur la flèche du menu déroulant à côté de Open (Ouvrir).
  2. Cliquez sur Ajouter un projet à partir d'un 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. Dans la console Firebase, cliquez sur Ajouter un projet.
  2. Pour créer un projet, saisissez le nom souhaité.
    L'ID du projet (affiché sous le nom du projet) sera également défini sur une valeur basée sur le nom du projet. Vous pouvez également cliquer sur l'icône Modifier à côté de l'ID de projet pour le personnaliser davantage.
  3. Si vous y êtes invité, lisez 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 Créer un compte pour en créer un.
  7. Cliquez sur Create Project (Créer un projet).
  8. Une fois le projet créé, 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 workflow 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 l'option permettant d'enregistrer les cibles de compilation Apple (iOS) et Android.
  3. Saisissez les ID propres à la plate-forme de votre projet Unity. Pour les besoins de cet atelier de programmation, saisissez les informations suivantes:
  4. (Facultatif) Saisissez le ou les pseudos 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 Enregistrer l'application, vous serez invité à télécharger deux fichiers de configuration (un fichier de configuration pour chaque cible de compilation). 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 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 Next (Suivant), puis accédez à "Add Firebase SDK for Unity" (Ajouter des SDK Firebase pour Unity).

Ajouter des SDK Firebase pour Unity

  1. Cliquez sur Download Firebase Unity SDK (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) > Package personnalisé :
  4. Dans la boîte de dialogue Import package (Importer un package), accédez au répertoire contenant le SDK décompressé, sélectionnez FirebaseAnalytics.unitypackage, puis cliquez sur Open (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 et, dans le workflow de configuration, cliquez sur Next (Suivant).

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

4. Configurer Crashlytics dans votre projet Unity

Pour utiliser Crashlytics dans des projets Unity, vous devez effectuer quelques étapes de configuration supplémentaires. Bien entendu, vous devez initialiser le SDK. Vous devez également importer vos symboles pour pouvoir afficher les traces de pile symbolisées dans la console Firebase. Vous devez également 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, et 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. De même, 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 toute interaction du joueur avant l'initialisation des dépendances Firebase.

Pour en savoir plus sur les avantages et les conséquences du signalement d'exceptions non gérées comme fatales, consultez les questions fréquentes sur Crashlytics.

Créer votre projet et importer des symboles

La procédure de création et d'importation de symboles est différente 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 pour chaque build. Ces informations de symboles sont requises pour afficher les traces de pile décodées dans le tableau de bord Crashlytics.

Android

  1. (uniquement lors de la configuration initiale, et non pour chaque build) Configurez votre build :
    1. Créez un dossier nommé Builds à la racine du répertoire de votre projet (c'est-à-dire en tant que frère de votre répertoire Assets), puis un sous-répertoire nommé Android.
    2. Dans File (Fichier) > Build Settings (Paramètres de compilation) > Player Settings (Paramètres du joueur) > Configuration (Configuration), définissez Scripting Backend (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. Le sélectionner ici permet de mieux harmoniser les deux plates-formes et de simplifier le débogage des différences entre les deux (si vous choisissez de compiler les deux).
  2. Créez votre application. Dans File > Build Settings (Fichier > Paramètres de compilation), procédez comme suit :
    1. Assurez-vous que l'option Créer des symboles.zip est cochée (ou sélectionnez Débogage si un menu déroulant s'affiche).
    2. Créez votre APK directement depuis l'éditeur Unity dans le sous-répertoire Builds/Android que vous venez de créer.
  3. Une fois la compilation terminée, vous devez générer un fichier de symboles compatible avec Crashlytics et l'importer sur les serveurs Firebase. Ces informations de symboles sont requises pour afficher les traces de pile décodées pour les plantages de la bibliothèque native 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: votre ID d'application Android Firebase (pas 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 de test pour terminer la configuration

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

  1. Dans MainGameScene, recherchez EmptyObject GameObject dans la hiérarchie de l'éditeur, ajoutez-y le script suivant, puis enregistrez la scène. Ce script provoque 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. Compilez votre application et importez les informations des 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, consultez 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 la trouverez dans le tableau Problèmes au bas du tableau de bord. Vous en apprendrez davantage sur l'exploration de ces rapports plus tard dans cet atelier de programmation.
  5. Une fois que vous avez confirmé que l'événement a été importé dans Crashlytics, sélectionnez l'GameObject EmptyObject auquel vous l'avez associé, supprimez uniquement le composant CrashlyticsTester, puis enregistrez la scène pour la restaurer à 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 importe des événements dans Firebase. Vous allez maintenant créer un menu dans votre projet Unity pour vous montrer comment utiliser des fonctionnalités Crashlytics plus avancées dans votre jeu. Le projet Unity Level Up with Firebase contient déjà un menu de débogage masqué que vous allez rendre visible et dont vous allez écrire la fonctionnalité.

Activer le menu de débogage

Le bouton d'accès 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 préfab MainMenu :

  1. Dans l'éditeur Unity, ouvrez le préfab nommé MainMenu.4148538cbe9f36c5.png.
  2. Dans la hiérarchie du préfabriqué, recherchez le sous-objet désactivé nommé DebugMenuButton, puis sélectionnez-le.816f8f9366280f6c.png
  3. Activez DebugMenuButton en cochant la case en haut à 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évisualiser et comprendre les corps de méthode du menu de débogage

Plus loin dans cet atelier de programmation, vous écrirez des corps de méthode pour certaines méthodes de débogage Crashlytics préconfigurées. Toutefois, dans le projet Unity Level Up with Firebase, 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 à partir de 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 pour générer et annoter les 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 prochaines étapes de cet atelier de programmation, vous implémenterez ces méthodes et découvrirez comment elles permettent de résoudre des situations spécifiques pouvant survenir dans le cadre 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 bien comprendre comment les événements sont signalés à Crashlytics.

Pour les projets Unity, les événements de plantage et d'exception de 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 de 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 à l'endroit où vous initialisez Crashlytics dans votre projet Unity. Ces événements sont transmis à Crashlytics en temps réel, sans qu'un utilisateur final ait besoin de redémarrer le jeu. Notez que les plantages natifs sont toujours signalés en tant qu'événements fatals et envoyés lorsqu'un utilisateur final redémarre le jeu.

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

Simulateur iOS:

  • Les informations Crashlytics ne sont transmises que si vous dissociez Xcode du simulateur. Si Xcode est associé, il détecte les erreurs en amont, ce qui empêche la diffusion d'informations.

Appareils mobiles physiques (Android et iOS):

  • Propre à Android: les erreurs ANR ne sont signalées que sur Android 11 ou version ultérieure. Les erreurs ANR et les événements non fatals seront signalés lors de la prochaine exécution.

Éditeur Unity :

Testez le plantage de votre jeu d'une simple pression 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, puis les importe dans Firebase pour analyse. Les rapports sont affichés dans le tableau de bord Crashlytics de la console Firebase.

  1. Pour dé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 Plantage maintenant, puis passez à l'étape suivante de cet atelier de programmation pour savoir comment afficher et interpréter le rapport d'erreur.

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

Lorsque vous souhaitez consulter vos rapports d'erreur, vous devez savoir comment en tirer le meilleur parti. Chacune des méthodes que vous écrivez vous montrera comment ajouter différents types d'informations aux rapports Crashlytics.

  1. Appuyez sur le bouton Planter maintenant, 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 regroupe les événements ayant tous la même cause sous "Problèmes".
  3. Cliquez sur le nouveau problème listé dans le tableau Problèmes. Le récapitulatif des événements s'affiche alors pour chaque événement envoyé à Firebase.

    Vous devriez voir une capture d'écran semblable à celle-ci. Notez que le résumé des événements met en évidence la trace de la pile de l'appel ayant entraîné le plantage.40c96abe7f90c3aa.png

Métadonnées supplémentaires

L'onglet Métadonnées Unity est également utile. Cette section fournit des informations sur les attributs de l'appareil sur lequel l'événement s'est produit, y compris les caractéristiques physiques, le modèle/les caractéristiques du processeur et toutes sortes de métriques de GPU.

Voici un exemple où les informations de cet onglet peuvent être utiles :
Imaginons 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 de l'afficher. Les informations de l'onglet Métadonnées Unity peuvent vous donner une meilleure idée du matériel que votre application doit tester lorsque vous décidez des fonctionnalités à rendre disponibles automatiquement ou à désactiver complètement.

Bien qu'aucun bug ou plantage ne se produise sur votre appareil, en raison de la grande diversité d'appareils Android dans le monde, il est utile de mieux comprendre les points d'accès spécifiques. des appareils de votre audience.

41d8d7feaa87454d.png

8. Générer, intercepter et enregistrer 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é à cette fin exacte : 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 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 obtenir un résultat semblable à ce que vous avez vu à la dernière étape de cet atelier de programmation.
  7. Cette fois, cependant, 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, des centaines, voire des milliers de fois par session, peut soudainement générer une exception ou un plantage ? 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 petit pourcentage de vos utilisateurs ? Pire encore, que feriez-vous si vous ne pouviez pas reproduire ce plantage, quoi que vous fassiez ?

Dans de telles situations, avoir un peu de contexte 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 destinés à votre futur moi sur ce qui pourrait se passer.

Bien que les journaux puissent être utilisés de différentes manières, ils sont généralement les plus utiles pour enregistrer des situations où l'ordre et/ou l'absence d'appels est 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) 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 Journaliser les chaînes 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 dans le tableau Problèmes. Vous devriez à nouveau voir quelque chose de semblable aux problèmes précédents.
    7aabe103b8589cc7.png
  6. Toutefois, si vous cliquez sur l'onglet Journaux d'un récapitulatif des événements, vous obtenez une vue semblable à celle-ci :
    4e27aa407b7571cf.png

10. Écrire et écraser 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 serait utile de pouvoir filtrer en fonction de la combinaison de variables et des valeurs possibles que vous examinez à un moment donné.

En plus de consigner des chaînes arbitraires, Crashlytics offre une autre forme de débogage lorsqu'il est utile de connaître l'état exact de votre programme lorsqu'il a planté: des 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 de consigner le dernier état enregistré de votre programme, ces clés peuvent servir de 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 CLI Firebase suivante :
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Appuyez sur le bouton Définir une clé et un plantage personnalisés, puis redémarrez votre application.
  5. Revenez au tableau de bord Crashlytics, puis cliquez sur le dernier problème répertorié dans le tableau Issues (Problèmes). Vous devriez à nouveau voir quelque chose de semblable aux problèmes précédents.
  6. Cette fois, cependant, cliquez sur l'onglet Clés dans le récapitulatif des événements 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 efficaces pour stocker des données séquentielles, mais les clés personnalisées sont plus adaptées si vous ne souhaitez conserver que 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 le champ de recherche de la table Problèmes.

Cependant, 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, aucune valeur supplémentaire n'est enregistrée. Chaque paire clé-valeur peut avoir une taille maximale de 1 Ko.

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

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

Les erreurs ANR nuisent à l'expérience utilisateur et (comme indiqué dans le lien 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 sur différents modèles de téléphones, la reproduction des erreurs ANR lors du débogage est souvent très difficile, voire presque impossible. Il est donc généralement préférable de les aborder de manière analytique et déductive.

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 nous fournir 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 (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écapitulatif des événements. Si l'appel a bien abouti, vous devriez voir quelque chose comme ceci :
    876c3cff7037bd07.png

    Comme vous pouvez le constater, Firebase a identifié l'attente active sur le thread comme la principale raison pour laquelle votre application a déclenché une erreur ANR.
  6. Si vous examinez les journaux dans l'onglet Journaux du récapitulatif des événements, vous constaterez 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'erreur ANR s'est produite pendant cette méthode et que le jeu s'est fermé avant de pouvoir consigner DoExtremeWork.

    89d86d5f598ecf3a.png

À quoi ça sert ?

  • Reproduire les erreurs ANR est incroyablement difficile. Il est donc extrêmement important de pouvoir obtenir des informations complètes 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 pris le plus de temps à s'exécuter et lesquels risquaient de déclencher des erreurs ANR. Ce type de données logiques et numériques associées vous indiquera les parties de votre code qui doivent être optimisées en priorité.

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

Les méthodes suivantes peuvent également être appelées à partir du menu "Debug" (Débogage), mais au lieu de générer elles-mêmes des problèmes, elles utilisent Google Analytics comme une 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 les combiner aux 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'exécuter l'une des autres. Lorsque vous examinez les informations du problème Crashlytics spécifique, un journal ordonné des événements Analytics s'affiche. Ces données peuvent être utilisées dans un jeu pour mieux comprendre une combinaison de flux de programme ou d'entrée utilisateur, en fonction de 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 une ou plusieurs fois sur au moins l'un des boutons suivants pour appeler les fonctions ci-dessus:
    • Événement de chaîne de journal
    • Événement Log Int
  5. Appuyez sur le bouton Crash Now (Plantage).
  6. Redémarrez votre jeu pour qu'il importe l'événement de plantage dans Firebase.
  7. Lorsque vous consignez 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), ceux-ci sont ajoutés à l'onglet Journaux du Résumé des événements de Crashlytics, comme suit:
    D3b16d78f76bfb04.png

13. Aller plus loin

Vous disposez ainsi d'une base théorique plus solide sur laquelle vous pouvez vous appuyer pour compléter vos rapports d'erreur 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 comprendre la séquence d'événements et la logique qui ont conduit à ce résultat.

Si votre application cible Android 11 (niveau d'API 30) ou une 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 bénéficier de cette fonctionnalité de débogage, activez explicitement GWP-ASan.

Étapes suivantes

Passez à l'atelier de programmation Instrumenter votre jeu Unity avec Remote Config. Vous y apprendrez comment utiliser Remote Config et A/B Testing dans Unity.