Comprendere gli arresti anomali di un gioco Unity utilizzando le funzionalità avanzate di Crashlytics

1. Introduzione

In questo codelab, imparerai a utilizzare le funzionalità avanzate di Crashlytics che ti offrono una migliore visibilità sugli arresti anomali e sulle circostanze che potrebbero averli causati.

Aggiungerai nuove funzionalità a un gioco di esempio, MechaHamster: Level Up with Firebase Edition. Questo gioco di esempio è una nuova versione del classico gioco Firebase MechaHamster che rimuove la maggior parte delle funzionalità Firebase integrate, offrendoti la possibilità di implementare nuovi utilizzi di Firebase al loro posto.

Aggiungerai un menu di debug al gioco. Questo menu di debug chiama i metodi che creerai e ti consente di esercitarti con le diverse funzionalità di Crashlytics. Questi metodi ti mostreranno come annotare i report automatici sugli arresti anomali con chiavi personalizzate, log personalizzati, errori non irreversibili e altro ancora.

Dopo aver creato il gioco, utilizza il menu di debug ed esamina i risultati per comprendere la visione unica che forniscono sul funzionamento del gioco in produzione.

Obiettivi didattici

  • I tipi di errori rilevati automaticamente da Crashlytics.
  • Errori aggiuntivi che possono essere registrati intenzionalmente.
  • Come aggiungere ulteriori informazioni a questi errori per semplificarne la comprensione.

Che cosa ti serve

2. Configurazione dell'ambiente di sviluppo

Le seguenti sezioni descrivono come scaricare il codice Livello successivo con Firebase e aprirlo in Unity.

Tieni presente che questo gioco di esempio Sali di livello con Firebase è utilizzato da diversi altri codelab Firebase e Unity, quindi potresti aver già completato le attività di questa sezione. In questo caso, puoi andare direttamente all'ultimo passaggio di questa pagina: "Aggiungi gli SDK Firebase per Unity".

Scarica il codice

Clona il repository GitHub di questo codelab dalla riga di comando:

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

In alternativa, se non hai installato Git, puoi scaricare il repository come file ZIP.

Apri Sali di livello con Firebase nell'editor Unity

  1. Avvia l'hub Unity e, dalla scheda Progetti, fai clic sulla freccia del menu a discesa accanto ad Apri.
  2. Fai clic su Aggiungi progetto dal disco.
  3. Passa alla directory che contiene il codice e fai clic su OK.
  4. Se richiesto, seleziona una versione di Unity Editor da utilizzare e la piattaforma di destinazione (Android o iOS).
  5. Fai clic sul nome del progetto, level-up-with-firebase, per aprirlo nell'editor di Unity.
  6. Se l'editor non si apre automaticamente, apri MainGameScene in Asset > Hamster nella scheda Progetto di Unity Editor.
    2017-07-29.png

Per ulteriori informazioni sull'installazione e sull'utilizzo di Unity, vedi Utilizzo di Unity.

3. Aggiungi Firebase al tuo progetto Unity

Crea un progetto Firebase

  1. Nella Console Firebase, fai clic su Aggiungi progetto.
  2. Per creare un nuovo progetto, inserisci il nome del progetto che ti interessa.
    Verrà impostato anche l'ID progetto (visualizzato sotto il nome del progetto) su un valore basato sul nome del progetto. Se vuoi, puoi fare clic sull'icona di modifica sull'ID progetto per personalizzarlo ulteriormente.
  3. Se richiesto, leggi e accetta i Termini di Firebase.
  4. Fai clic su Continua.
  5. Seleziona l'opzione Abilita Google Analytics per questo progetto e poi fai clic su Continua.
  6. Seleziona un account Google Analytics esistente da utilizzare oppure Crea un nuovo account per crearne uno nuovo.
  7. Fai clic su Crea progetto.
  8. Una volta creato il progetto, fai clic su Continua.

Registra la tua app con Firebase

  1. Sempre nella console Firebase, fai clic sull'icona di Unity al centro della pagina di riepilogo del progetto per avviare il flusso di lavoro di configurazione oppure, se hai già aggiunto un'app al progetto Firebase, fai clic su Aggiungi app per visualizzare le opzioni della piattaforma.
  2. Seleziona la registrazione sia delle destinazioni di build Apple (iOS) che di quelle Android.
  3. Inserisci gli ID specifici della piattaforma del tuo progetto Unity. Per questo codelab, inserisci quanto segue:
  4. (Facoltativo) Inserisci i nickname specifici della piattaforma del progetto Unity.
  5. Fai clic su Registra app e poi vai alla sezione Scarica il file di configurazione.

Aggiungi file di configurazione Firebase

Dopo aver fatto clic su Registra app, ti verrà chiesto di scaricare due file di configurazione (un file per ogni destinazione di build). Il tuo progetto Unity richiede i metadati Firebase in questi file per connettersi a Firebase.

  1. Scarica entrambi i file di configurazione disponibili:
    • Per Apple (iOS): scarica GoogleService-Info.plist.
    • Per Android: scarica google-services.json.
  2. Apri la finestra Progetto del tuo progetto Unity, quindi sposta entrambi i file di configurazione nella cartella Asset.
  3. Torna nella Console Firebase, nel flusso di lavoro di configurazione, fai clic su Avanti e vai ad Aggiungere gli SDK Firebase per Unity.

Aggiungi gli SDK Firebase per Unity

  1. Fai clic su Scarica l'SDK Firebase Unity nella console Firebase.
  2. Decomprimi l'SDK in un percorso semplice da raggiungere.
  3. Nel progetto Unity aperto, vai a Asset > Importa pacchetto > Pacchetto personalizzato.
  4. Nella finestra di dialogo Importa pacchetto, vai alla directory che contiene l'SDK non compresso, seleziona FirebaseAnalytics.unitypackage e fai clic su Apri.
  5. Nella finestra di dialogo Importa il pacchetto Unity visualizzata, fai clic su Importa.
  6. Ripeti i passaggi precedenti per importare FirebaseCrashlytics.unitypackage.
  7. Torna alla Console Firebase e, nel flusso di lavoro di configurazione, fai clic su Avanti.

Per saperne di più sull'aggiunta degli SDK Firebase ai progetti Unity, consulta Ulteriori opzioni di installazione di Unity.

4. Configurare Crashlytics nel progetto Unity

Per utilizzare Crashlytics nei progetti Unity, devi eseguire alcuni altri passaggi di configurazione. Ovviamente dovrai inizializzare l'SDK. Inoltre, dovrai caricare i simboli per poter vedere gli stack trace simbolizzati nella Console Firebase e dovrai forzare un arresto anomalo di prova per assicurarti che Firebase riceva gli eventi di arresto anomalo.

Inizializza l'SDK Crashlytics

  1. In Assets/Hamster/Scripts/MainGame.cs, aggiungi le seguenti istruzioni using:
    using Firebase.Crashlytics;
    using Firebase.Extensions;
    
    Il primo modulo ti consente di utilizzare i metodi dell'SDK Crashlytics, mentre il secondo contiene alcune estensioni dell'API Tasks C#. Senza entrambe le istruzioni using il seguente codice non funzionerà.
  2. Sempre in MainGame.cs, aggiungi l'inizializzazione di Firebase al metodo Start() esistente chiamando InitializeFirebaseAndStartGame():
    void Start()
    {
      Screen.SetResolution(Screen.width / 2, Screen.height / 2, true);
      InitializeFirebaseAndStartGame();
    }
    
  3. Ancora una volta, in MainGame.cs, trova InitializeFirebaseAndStartGame(), dichiara una variabile di app e poi sovrascrivi l'implementazione del metodo nel seguente modo:
    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");
          }
        });
    }
    

L'inserimento qui della logica di inizializzazione impedisce l'interazione con il player prima dell'inizializzazione delle dipendenze Firebase.

I vantaggi e gli effetti della segnalazione di eccezioni non gestite come irreversibili sono descritti nelle Domande frequenti su Crashlytics.

Crea il tuo progetto e carica i simboli

I passaggi per creare e caricare i simboli sono diversi per le app per iOS e Android.

iOS e versioni successive (piattaforma Apple)

  1. Dalla finestra di dialogo Impostazioni di compilazione, esporta il progetto in un'area di lavoro Xcode.
  2. Crea l'app.
    Per le piattaforme Apple, il plug-in Firebase Unity Editor configura automaticamente il progetto Xcode in modo da generare e caricare un file di simboli compatibile con Crashlytics sui server Firebase per ogni build. Queste informazioni sui simboli sono necessarie per visualizzare le tracce dello stack simboliche nella dashboard di Crashlytics.

Android

  1. (solo durante la configurazione iniziale, non per ogni build) Configura la build:
    1. Crea una nuova cartella denominata Builds nella directory principale del progetto (ovvero come cartella correlata alla directory Assets) e poi una sottocartella denominata Android.
    2. In File > Impostazioni di compilazione > Impostazioni del player > Configurazione, imposta Scripting Backend su IL2CPP.
      • In genere, IL2CPP consente di ottenere build più piccole e con prestazioni migliori.
      • IL2CPP è anche l'UNICA opzione disponibile su iOS e la selezione qui consente alle due piattaforme di avere una migliore parità e di semplificare le differenze di debug tra le due (se scegli di crearle entrambe).
  2. Compila l'app. In File > Impostazioni di compilazione, completa quanto segue:
    1. Assicurati che l'opzione Crea simboli.zip sia selezionata oppure, se viene presentato un menu a discesa, seleziona Debug.
    2. Compila l'APK direttamente da Unity Editor nella sottocartella Builds/Android che hai appena creato.
  3. Al termine della compilazione, devi generare un file di simboli compatibile con Crashlytics e caricarlo sui server Firebase. Queste informazioni sui simboli sono necessarie per visualizzare le analisi dello stack simbolizzate per gli arresti anomali delle librerie native nella dashboard di Crashlytics.

    Genera e carica questo file di simboli eseguendo il seguente comando dell'interfaccia a riga di comando di Firebase:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
    • FIREBASE_APP_ID: l'ID dell'app Firebase per Android (non il nome del pacchetto). Trova questo valore nel file google-services.json scaricato in precedenza. È il valore mobilesdk_app_id.
      Esempio di ID app Firebase per Android: 1:567383003300:android:17104a2ced0c9b9b
    • PATH/TO/SYMBOLS: il percorso del file dei simboli compresso generato nella directory Builds/Android al termine della compilazione (ad esempio: Builds/Android/myapp-1.0-v100.symbols.zip).

Forzare un arresto anomalo del test per completare la configurazione

Per completare la configurazione di Crashlytics e visualizzare i dati iniziali nella dashboard di Crashlytics della Console Firebase, devi forzare un arresto anomalo di prova.

  1. In MainGameScene, trova EmptyObject GameObject nell'editor Hierarchy, aggiungi il seguente script e salva la scena. Questo script causerà un arresto anomalo del test pochi secondi dopo l'esecuzione dell'app.
    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. Compila l'app e carica le informazioni sui simboli al termine della compilazione.
    • iOS: il plug-in Firebase Unity Editor configura automaticamente il progetto Xcode per caricare il file dei simboli.
    • Android: esegui il comando crashlytics:symbols:upload dell'interfaccia a riga di comando di Firebase per caricare il file del simbolo.
  3. Esegui l'app. Una volta in esecuzione, controlla il log del dispositivo e attendi che l'eccezione venga attivata da CrashlyticsTester.
    • iOS: visualizza i log nel riquadro inferiore di Xcode.
    • Android: per visualizzare i log, esegui il seguente comando nel terminale: adb logcat.
  4. Visita la dashboard di Crashlytics per visualizzare l'eccezione. Lo vedrai nella tabella Problemi nella parte inferiore della dashboard. Più avanti nel codelab, scoprirai di più su come esplorare questi report.
  5. Dopo aver verificato che l'evento è stato caricato su Crashlytics, seleziona l'oggetto vuoto GameObject a cui lo hai allegato, rimuovi solo il componente CrashlyticsTester e salva la scena per ripristinare le condizioni originali.

5. Attivare e comprendere il menu di debug

Finora hai aggiunto Crashlytics al tuo progetto Unity, hai completato la configurazione e hai verificato che l'SDK Crashlytics carichi gli eventi su Firebase. Ora creerai un menu nel tuo progetto Unity che ti mostrerà come utilizzare le funzionalità più avanzate di Crashlytics nel tuo gioco. Il progetto Unity Sali di livello con Firebase ha già un menu di debug nascosto che renderai visibile e per cui scriverai la funzionalità.

Attiva il menu Debug

Il pulsante per accedere al menu di debug esiste nel tuo progetto Unity, ma al momento non è abilitato. Devi attivare il pulsante per accedervi dal prefab MainMenu:

  1. In Unity Editor, apri il prefab denominato MainMenu.4148538cbe9f36c5.png
  2. Nella gerarchia del prefab, individua l'oggetto secondario disattivato denominato DebugMenuButton e selezionalo.816f8f9366280f6c.png
  3. Attiva DebugMenuButton selezionando la casella nell'angolo in alto a sinistra a sinistra del campo di testo contenente DebugMenuButton.8a8089d2b4886da2.png
  4. Salva il prefab.
  5. Esegui il gioco nell'editor o sul tuo dispositivo. Ora il menu dovrebbe essere accessibile.

Visualizza l'anteprima e comprendi i corpi dei metodi per il menu di debug

Più avanti in questo codelab, scriverai i corpi dei metodi per alcuni metodi di debug Crashlytics preconfigurati. Tuttavia, nel progetto Unity Level Up with Firebase, i metodi vengono definiti e richiamati da DebugMenu.cs.

Sebbene alcuni di questi metodi chiamino i metodi Crashlytics e generino errori, la capacità di Crashlytics di rilevare questi errori non dipende dall'aver chiamato prima questi metodi. I report sugli arresti anomali generati dalla rilevazione automatica degli errori verranno migliorati dalle informazioni aggiunte da questi metodi.

Apri DebugMenu.cs, poi trova i seguenti metodi:

Metodi per generare e annotare i problemi di Crashlytics:

  • CrashNow
  • LogNonfatalError
  • LogStringsAndCrashNow
  • SetAndOverwriteCustomKeyThenCrash
  • SetLogsAndKeysBeforeANR

Metodi per registrare gli eventi di Analytics per facilitare il debug:

  • LogProgressEventWithStringLiterals
  • LogIntScoreWithBuiltInEventAndParams

Nelle fasi successive di questo codelab, imparerai a implementare questi metodi e imparerai ad affrontare situazioni specifiche che possono verificarsi nello sviluppo di giochi.

6. Garantire l'invio di report sugli arresti anomali durante lo sviluppo

Prima di iniziare a implementare questi metodi di debug e di vedere in che modo influiscono sui report sugli arresti anomali, assicurati di comprendere come vengono segnalati gli eventi a Crashlytics.

Per i progetti Unity, gli eventi di arresto anomalo ed eccezione nel gioco vengono scritti immediatamente sul disco. Per le eccezioni non rilevate che non causano arresti anomali del gioco (ad esempio le eccezioni C# non rilevate nella logica di gioco), puoi chiedere all'SDK Crashlytics di segnalarle come eventi irreversibili impostando la proprietà Crashlytics.ReportUncaughtExceptionsAsFatal su true dove inizializzi Crashlytics nel tuo progetto Unity. Questi eventi vengono segnalati a Crashlytics in tempo reale senza che l'utente finale debba riavviare il gioco. Tieni presente che gli arresti anomali nativi vengono sempre segnalati come eventi fatali e inviati quando un utente finale riavvia il gioco.

Inoltre, tieni presente le seguenti differenze, piccole ma significative, nel modo in cui i diversi ambienti di runtime inviano le informazioni di Crashlytics a Firebase:

Simulatore iOS:

  • Le informazioni di Crashlytics vengono registrate se e solo se scolleghi Xcode dal simulatore. Se Xcode è collegato, rileva gli errori a monte, impedendo l'invio delle informazioni.

Dispositivi fisici mobili (Android e iOS):

  • Specifici per Android: gli errori ANR vengono segnalati soltanto su Android 11 e versioni successive. Gli eventi ANR ed eventi non irreversibili vengono segnalati all'esecuzione successiva.

Editor Unity:

Testare l'arresto anomalo del gioco con un solo tocco in CrashNow()

Una volta configurato Crashlytics nel tuo gioco, l'SDK Crashlytics registra automaticamente gli arresti anomali e le eccezioni non rilevate e le carica su Firebase per l'analisi. I report vengono visualizzati nella dashboard di Crashlytics nella console Firebase.

  1. Per dimostrare che si tratta di un'operazione automatica, apri DebugMenu.cs e sovrascrivi il metodo CrashNow() come segue:
    void CrashNow()
    {
        TestCrash();
    }
    
  2. Crea la tua app.
  3. (Solo Android) Carica i simboli eseguendo il seguente comando dell'interfaccia a riga di comando di Firebase:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Tocca il pulsante Avvia arresto anomalo e vai al passaggio successivo di questo codelab per scoprire come visualizzare e interpretare il report sugli arresti anomali.

7. Informazioni sui report sui problemi nella Console Firebase

Per quanto riguarda la visualizzazione dei report sugli arresti anomali, c'è ancora qualcosa che devi sapere su come ottenere il massimo da questi report. Ciascuno dei metodi che scrivi mostrerà come aggiungere tipi diversi di informazioni ai report di Crashlytics.

  1. Tocca il pulsante Incidente ora e riavvia l'app.
  2. Vai alla dashboard di Crashlytics. Scorri verso il basso fino alla tabella Problemi nella parte inferiore della dashboard, in cui Crashlytics raggruppa in "problemi" gli eventi con la stessa causa principale.
  3. Fai clic sul nuovo problema elencato nella tabella Problemi. In questo modo viene visualizzato il riepilogo degli eventi relativo a ogni singolo evento inviato a Firebase.

    Dovresti visualizzare qualcosa di simile allo screenshot seguente. Osserva come il Riepilogo eventi mette in evidenza l'analisi dello stack della chiamata che ha generato l'arresto anomalo.40c96abe7f90c3aa.png

Metadati aggiuntivi

Un'altra scheda utile è la scheda Metadati Unity. Questa sezione contiene informazioni sugli attributi del dispositivo su cui si è verificato l'evento, tra cui le funzionalità fisiche, il modello/le specifiche della CPU e tutti i tipi di metriche GPU.

Ecco un esempio in cui le informazioni in questa scheda potrebbero essere utili:
immagina che il tuo gioco faccia un uso intensivo degli shader per ottenere un determinato aspetto, ma non tutti gli smartphone dispongono di GPU in grado di eseguire il rendering di questa funzionalità. Le informazioni nella scheda Metadati di Unity possono darti un'idea migliore dell'hardware per cui la tua app deve eseguire il test quando decidi quali funzionalità rendere disponibili automaticamente o disattivare del tutto.

Anche se un bug o un arresto anomalo potrebbe non verificarsi sul tuo dispositivo, a causa dell'enorme diversità di dispositivi Android in circolazione, aiuta a comprendere meglio gli "hotspot" specifici dei dispositivi del tuo pubblico.

41d8d7feaa87454d.png

8. Genera, gestisci e registra un'eccezione

Spesso, in qualità di sviluppatore, anche se il codice rileva e gestisce correttamente un'eccezione di runtime, è bene notare che si è verificata e in quali circostanze. Crashlytics.LogException può essere utilizzato proprio per questo scopo: inviare un evento di eccezione a Firebase in modo da poter eseguire ulteriormente il debug del problema nella console di Firebase.

  1. In Assets/Hamster/Scripts/States/DebugMenu.cs, aggiungi quanto segue alle istruzioni using:
    // Import Firebase
    using Firebase.Crashlytics;
    
  2. Sempre in DebugMenu.cs, sovrascrivi LogNonfatalError() come segue:
    void LogNonfatalError()
    {
        try
        {
            throw new System.Exception($"Test exception thrown in {nameof(LogNonfatalError)}");
        }
        catch(System.Exception exception)
        {
            Crashlytics.LogException(exception);
        }
    }
    
  3. Crea la tua app.
  4. (Solo Android) Carica i simboli eseguendo il seguente comando Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  5. Tocca il pulsante Registra errore non fatale, quindi riavvia l'app.
  6. Vai alla dashboard di Crashlytics, dovresti vedere qualcosa di simile a quello che hai visto nell'ultimo passaggio di questo codelab.
  7. Questa volta, però, limita il filtro Tipo di evento a Non irreversibili in modo da visualizzare solo gli errori non irreversibili, come quello appena registrato.
    a39ea8d9944cbbd9.png

9. Registra le stringhe in Crashlytics per comprendere meglio il flusso di esecuzione del programma

Avete mai provato a capire perché una riga di codice che viene chiamata da più percorsi, centinaia se non migliaia di volte per sessione, può improvvisamente generare un'eccezione o un arresto anomalo? Anche se potrebbe essere utile eseguire il codice in un IDE e esaminare più da vicino i valori, cosa succede se questo accade solo in una percentuale minima di utenti? Peggio ancora, cosa faresti se non riesci a replicare questo arresto anomalo indipendentemente da cosa fai?

In situazioni come questa, avere un contesto specifico può fare davvero la differenza. Con Crashlytics.Log, hai la possibilità di scrivere il contesto di cui hai bisogno. Considera questi messaggi come suggerimenti per il tuo io del futuro su cosa potrebbe succedere.

Sebbene i log possano essere utilizzati in svariati modi, in genere sono più utili per registrare situazioni in cui l'ordine e/o l'assenza di chiamate sono informazioni di fondamentale importanza.

  1. In Assets/Hamster/Scripts/States/DebugMenu.cs, sovrascrivi LogStringsAndCrashNow() come segue:
    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. Crea la tua app.
  3. (Solo Android) Carica i simboli eseguendo il seguente comando Firebase CLI:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Tocca il pulsante Log Strings and Crash Now (Registra stringhe e arresta anomalo ora), quindi riavvia l'app.
  5. Torna alla dashboard di Crashlytics e fai clic sul problema più recente elencato nella tabella Problemi. Dovresti visualizzare un messaggio simile a quello dei problemi precedenti.
    7aabe103b8589cc7.png
  6. Tuttavia, se fai clic sulla scheda Log in un Riepilogo eventi, ottieni una visualizzazione simile alla seguente:
    4e27aa407b7571cf.png.

10. Scrivere e sovrascrivere una chiave personalizzata

Supponiamo che tu voglia comprendere meglio un arresto anomalo corrispondente a variabili impostate su un numero ridotto di valori o configurazioni. Potrebbe essere utile poter filtrare in un determinato momento in base alla combinazione di variabili e valori possibili visualizzati.

Oltre al logging di stringhe arbitrarie, Crashlytics offre un'altra forma di debug quando è utile conoscere lo stato esatto del programma in cui si è verificato l'arresto anomalo: le chiavi personalizzate.

Si tratta di coppie chiave-valore che puoi impostare per una sessione. A differenza dei log, che si accumulano e sono puramente additivi, le chiavi possono essere sovrascritte per riflettere solo lo stato più recente di una variabile o condizione.

Oltre ad essere un registro dell'ultimo stato registrato del programma, queste chiavi possono essere utilizzate come filtri efficaci per i problemi di Crashlytics.

  1. In Assets/Hamster/Scripts/States/DebugMenu.cs, sovrascrivi SetAndOverwriteCustomKeyThenCrash() come segue:
    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. Crea la tua app.
  3. (Solo Android) Carica i simboli eseguendo il seguente comando dell'interfaccia a riga di comando di Firebase:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Tocca il pulsante Imposta chiave personalizzata e arresto anomalo, quindi riavvia l'app.
  5. Torna alla dashboard di Crashlytics e fai clic sul problema più recente elencato nella tabella Problemi. Dovresti vedere qualcosa di simile ai problemi precedenti.
  6. Questa volta, tuttavia, fai clic sulla scheda Chiavi nel Riepilogo evento per visualizzare il valore delle chiavi, tra cui Current Time:
    7dbe1eb00566af98.png

Perché dovresti utilizzare chiavi personalizzate invece dei log personalizzati?

  • I log sono utili per archiviare i dati sequenziali, ma le chiavi personalizzate sono migliori se vuoi solo il valore più recente.
  • Nella Console Firebase, puoi filtrare facilmente i problemi in base ai valori delle chiavi nella casella di ricerca della tabella Problemi.

Tuttavia, come per i log, le chiavi personalizzate hanno un limite. Crashlytics supporta un massimo di 64 coppie chiave-valore. Una volta raggiunta questa soglia, i valori aggiuntivi non vengono salvati. Ogni coppia chiave-valore può avere una dimensione massima di 1 kB.

11. (Solo Android) Usare chiavi e log personalizzati per comprendere e diagnosticare un errore ANR

Una delle classi di problemi più difficili di cui eseguire il debug per gli sviluppatori Android è l'errore L'applicazione non risponde (ANR). Gli errori ANR si verificano quando un'app non risponde all'input per più di 5 secondi. In questo caso, significa che l'app si è bloccata o è molto lenta. Viene mostrata una finestra di dialogo agli utenti che possono scegliere se impostare o meno l'opzione "Attendi" o "Chiudi app".

Gli errori ANR costituiscono un'esperienza utente negativa e (come menzionato nel link ANR sopra) possono influire sulla rilevabilità della tua app nel Google Play Store. A causa della loro complessità e perché sono spesso causati da codice multithread con comportamenti molto diversi su diversi modelli di smartphone, la riproduzione degli errori ANR durante il debug è spesso molto difficile, se non quasi impossibile. Di conseguenza, di solito è meglio affrontarli in modo analitico e deduttivo.

In questo metodo utilizzeremo una combinazione di Crashlytics.LogException, Crashlytics.Log e Crashlytics.SetCustomKey per integrare la registrazione automatica dei problemi e per fornirci ulteriori informazioni.

  1. In Assets/Hamster/Scripts/States/DebugMenu.cs, sovrascrivi SetLogsAndKeysBeforeANR() come segue:
    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. Crea la tua app.
  3. Carica i simboli eseguendo questo comando dell'interfaccia a riga di comando di Firebase:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Tocca il pulsante Imposta registri e chiavi → ANR, quindi riavvia l'app.
  5. Torna alla dashboard di Crashlytics e fai clic sul nuovo problema nella tabella Problemi per visualizzare il Riepilogo eventi. Se la chiamata è andata a buon fine, dovresti vedere qualcosa di simile a questo:
    876c3cff7037bd07.png

    Come puoi vedere, Firebase ha indicato l'attesa impegnativa nel thread come il motivo principale per cui la tua app ha attivato un errore ANR.
  6. Se esamini i log nella scheda Log del Riepilogo eventi, vedrai che l'ultimo metodo registrato come completato è DoSevereWork.
    5a4bec1cf06f6984.png

    Al contrario, l'ultimo metodo elencato come in esecuzione è DoExtremeWork, il che indica che l'ANR si è verificato durante questo metodo e che il gioco è stato chiuso prima che potesse registrare DoExtremeWork.

    89d86d5f598ecf3a.png

Perché dovresti farlo?

  • La riproduzione degli ANR è incredibilmente difficile, quindi è fondamentale poter ottenere informazioni dettagliate sull'area di codice e sulle metriche per rilevarli in modo deduttivo.
  • Con le informazioni memorizzate nelle chiavi personalizzate, ora sai quale thread asincrono ha richiesto più tempo per l'esecuzione e quali rischiano di attivare ANR. Questo tipo di dati logici e numerici correlati ti mostrerà dove è più necessario ottimizzare il codice.

12. Inserire gli eventi di Analytics per arricchire ulteriormente i report

I seguenti metodi sono richiamabili anche dal menu di debug, ma invece di generare problemi, utilizzano Google Analytics come un'altra fonte di informazioni per comprendere meglio il funzionamento del gioco.

A differenza degli altri metodi che hai scritto in questo codelab, devi utilizzare questi metodi in combinazione con gli altri. Chiama questi metodi (premendo il pulsante corrispondente nel menu di debug) nell'ordine che preferisci prima di eseguire uno degli altri. Quando esamini le informazioni relative al problema specifico di Crashlytics, viene visualizzato un log ordinato degli eventi di Analytics. Questi dati possono essere utilizzati in un gioco per comprendere meglio una combinazione di flusso del programma o input utente, a seconda di come hai strumentato la tua app.

  1. In Assets/Hamster/Scripts/States/DebugMenu.cs, sovrascrivi le implementazioni esistenti dei seguenti metodi:
    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. Compila e implementa il gioco, quindi accedi al menu di debug.
  3. (Solo Android) Carica i simboli eseguendo il seguente comando dell'interfaccia a riga di comando di Firebase:
    firebase crashlytics:symbols:upload --app=<FIREBASE_APP_ID> <PATH/TO/SYMBOLS>
    
  4. Premi uno o più volte almeno uno dei seguenti pulsanti per richiamare le funzioni precedenti:
    • Evento stringa di log
    • Log Int Event
  5. Premi il pulsante Induce un arresto anomalo ora.
  6. Riavvia il gioco per caricare l'evento di arresto anomalo su Firebase.
  7. Quando registri varie sequenze arbitrarie di eventi di Analytics e poi fai in modo che il tuo gioco generi un evento da cui Crashlytics crea un report (come hai appena fatto), questi vengono aggiunti alla scheda Log del Riepilogo eventi di Crashlytics come segue:
    d3b16d78f76bfb04.png

13. In futuro

Detto ciò, dovresti avere una base teorica migliore su cui integrare i report sugli arresti anomali generati automaticamente. Queste nuove informazioni ti consentono di utilizzare lo stato corrente, i record degli eventi passati e gli eventi Google Analytics esistenti per suddividere meglio la sequenza di eventi e la logica che hanno portato al risultato.

Se la tua app ha come target Android 11 (livello API 30) o versioni successive, ti consigliamo di incorporare GWP-ASan, una funzionalità di allocazione della memoria nativa utile per il debug degli arresti anomali causati da errori di memoria nativa come i bug use-after-free e heap-buffer-overflow. Per sfruttare questa funzionalità di debug, attiva esplicitamente GWP-ASan.

Passaggi successivi

Vai al codelab Esegui il test del tuo gioco Unity con Remote Config, dove scoprirai come utilizzare Remote Config e i test A/B in Unity.