Écrire et visualiser les journaux avec Logcat

La fenêtre Logcat d’Android Studio affiche les messages du système, comme lorsqu’une collecte de déchets se produit, et les messages que vous avez ajoutés à votre application avec la classe Log. Elle affiche les messages en temps réel et conserve un historique afin que vous puissiez consulter les messages plus anciens.

Pour afficher uniquement les informations qui vous intéressent, vous pouvez créer des filtres, modifier la quantité d’informations affichées dans les messages, définir des niveaux de priorité, afficher uniquement les messages produits par le code de l’app et effectuer des recherches dans le journal. Par défaut, logcatsaffiche uniquement la sortie du journal liée à l’app la plus récemment exécutée.

Lorsqu’une app lève une exception, logcat affiche un message suivi de la trace de pile associée contenant des liens vers la ligne de code.

A partir d’Android Studio 2.2, la fenêtre Run affiche également les messages de journal pour l’app en cours d’exécution. Notez que vous pouvez configurer l’affichage de la sortie logcat, mais pas la fenêtre Runwindow.

Voir les journaux de votre app

Pour afficher les messages de journal d’une app :

  1. Construisez et exécutez votre app sur un appareil.
  2. Cliquez sur Afficher > Fenêtres d’outils > Logcat (ou cliquez sur Logcat dans la barre des fenêtres d’outils).

La fenêtre Logcat affiche les messages de journal pour l’app sélectionnée, tels que sélectionnés dans les listes déroulantes en haut de la fenêtre, comme indiqué dans la figure 1.

Figure 1. Fenêtre Logcat

Par défaut, logcat affiche uniquement les messages de journal de votre application en cours d’exécution sur l’appareil. Pour changer ce défaut, voir comment filtrer les messages de logcat.

La barre d’outils de logcat fournit les boutons suivants :

  1. Effacer logcat : Cliquez pour effacer le journal visible.
  2. Faire défiler jusqu’à la fin : Cliquez pour passer au bas du journal et voir les derniers messages du journal. Si vous cliquez ensuite sur une ligne du journal, la vue interrompt le défilement à ce point.
  3. Haut de la trace de pile et Bas de la trace de pile : Cliquez pour naviguer vers le haut et le bas des traces de pile dans le journal, en sélectionnant les noms de fichier suivants (et en visualisant les numéros de ligne correspondants dans l’éditeur) qui apparaissent dans les exceptions imprimées. C’est le même comportement que lorsque vous cliquez sur un nom de fichier dans le journal.
  4. Utiliser les enveloppes souples : Cliquez pour activer l’enveloppement des lignes et empêcher le défilement horizontal (bien que toute chaîne insécable nécessitera toujours un défilement horizontal).
  5. Imprimer : Cliquez pour imprimer les messages logcat. Après avoir sélectionné vos préférences d’impression dans la boîte de dialogue qui apparaît, vous pouvez également choisir d’enregistrer dans un PDF.
  6. Redémarrer : Cliquez pour effacer le journal et redémarrer logcat. Contrairement au bouton Effacer logcat, ceci récupère et affiche les messages de journal précédents, donc est plus utile si Logcat ne répond plus et que vous ne voulez pas perdre vos messages de journal.
  7. En-tête Logcat : Cliquez pour ouvrir la boîte de dialogue Configurer l’en-tête de Logcat, où vous pouvez personnaliser l’apparence de chaque message de Logcat, comme l’affichage ou non de la date et de l’heure.
  8. Capture d’écran : Cliquez pour capturer une capture d’écran.
  9. Enregistrement d’écran : Cliquez pour enregistrer une vidéo du périphérique (pour un maximum de 3 minutes).

Écrire des messages de journal

La classe Log vous permet de créer des messages de journal qui apparaissent dans logcat. En général, vous devriez utiliser les méthodes de journalisation suivantes, énumérées dans l’ordre de la plus haute à la plus basse priorité (ou, du moins au plus verbeux) :

  • Log.e(String, String) (erreur)
  • Log.w(String, String) (avertissement)
  • Log.i(String, String) (information)
  • Log.d(String, String) (débogage)
  • Log.v(String, String) (verbeux)

Voir la description de la classe Log pour une liste plus complète des options.

Vous ne devriez jamais compiler les journaux verbeux dans votre application, sauf pendant le développement. Les journaux de débogage sont compilés mais supprimés au moment de l’exécution, tandis que les journaux d’erreur, d’avertissement et d’information sont toujours conservés.

Pour chaque méthode de journal, le premier paramètre doit être une étiquette unique et le second paramètre est le message. La balise d’un message de journal système est une courte chaîne indiquant le composant système d’où provient le message (par exemple, ActivityManager). Votre étiquette peut être n’importe quelle chaîne de caractères que vous trouvez utile, comme le nom de la classe actuelle.

Une bonne convention est de déclarer une constante TAG dans votre classe à utiliser dans le premier paramètre. Par exemple, vous pourriez créer un message de journal d’information comme suit :

Kotlin

private const val TAG = "MyActivity"...Log.i(TAG, "MyClass.getView() — get item number $position")

Java

private static final String TAG = "MyActivity";...Log.i(TAG, "MyClass.getView() — get item number " + position);

Note : les noms de balises supérieurs à 23 caractères sont tronqués dans la sortie logcat.

Format du message logcat

Chaque message de journal Android est associé à une balise et à une priorité. La balise d’un message de journal système est une courte chaîne indiquant le composant système d’où provient le message (par exemple, ActivityManager). Une balise définie par l’utilisateur peut être n’importe quelle chaîne que vous trouvez utile, comme le nom de la classe actuelle (la balise recommandée). Vous la définissez dans un appel de méthode Log, par exemple :

Kotlin

Log.d(tag, message)

Java

Log.d(tag, message);

La priorité est l’une des valeurs suivantes :

  • V : Verbose (priorité la plus faible)
  • D : Débogage
  • I : Info
  • W : Warning
  • E : Error
  • A : Assert

Le format du message de journal est:

date time PID-TID/package priority/tag: message

Par exemple, le message de journal suivant a une priorité de V et une balise de AuthZen:

12-10 13:02:50.071 1901-4229/com.google.android.gms V/AuthZen: Handling delegate intent.

PID signifie identificateur de processus et TID est identificateur de thread ; ils peuvent être identiques s’il n’y a qu’un seul thread.

Définir le niveau du journal

Vous pouvez contrôler combien de messages apparaissent dans logcat en définissant le niveau du journal. Vous pouvez afficher tous les messages, ou seulement les messages indiquant les conditions les plus sévères.

N’oubliez pas que logcat continue à collecter tous les messages quel que soit le paramètre du niveau de journal. Le paramètre détermine simplement ce que logcat affiche.

Dans le menu Niveau de journal, sélectionnez l’une des valeurs suivantes :

  • Verbeux : Afficher tous les messages du journal (la valeur par défaut).
  • Débogage : Afficher les messages de journal de débogage qui ne sont utiles que pendant le développement, ainsi que les niveaux de message inférieurs dans cette liste.
  • Info : Afficher les messages de journal attendus pour une utilisation régulière, ainsi que les niveaux de message inférieurs dans cette liste.
  • Avertissement : Afficher les problèmes possibles qui ne sont pas encore des erreurs, ainsi que les niveaux de message inférieurs dans cette liste.
  • Erreur : Afficher les problèmes qui ont causé des erreurs, ainsi que le niveau de message inférieur dans cette liste.
  • Assert : Montrer les problèmes qui, selon le développeur, ne devraient jamais se produire.

Recherche de messages logcat

Pour rechercher les messages actuellement affichés dans logcat :

  1. Sélectionnez éventuellement Regex si vous voulez utiliser un modèle de recherche par expression régulière.
  2. Tapez une séquence de caractères dans le champ de recherche .

    L’affichage de la sortie logcat change en conséquence.

  3. Passez la touche Entrée pour stocker la chaîne de recherche dans le menu pendant cette session.
  4. Pour répéter une recherche, choisissez-la dans le menu de recherche. Sélectionnez ou désélectionnez Regex au besoin (le paramètre n’est pas mémorisé).

Filtrer les messages logcat

Une façon de réduire la sortie du journal à un niveau gérable est de la restreindre en utilisant un filtre.

Note : Le filtre s’applique à votre historique logcat complet, pas seulement aux messages actuellement affichés dans logcat. Assurez-vous que vos autres options d’affichage sont définies de manière appropriée afin que vous puissiez voir la sortie du filtre que vous voulez examiner.

Pour définir et appliquer un filtre :

  1. Dans le menu de filtre, sélectionnez une option de filtre :
    • Afficher uniquement l’application sélectionnée : Afficher les messages produits par le code de l’app uniquement (la valeur par défaut). Logcat filtre les messages du journal en utilisant le PID de l’app active.
    • Aucun filtre : N’appliquer aucun filtre. Logcat affiche tous les messages de journal de l’appareil, quel que soit le processus que vous avez sélectionné.
    • Modifier la configuration du filtre : Créez ou modifiez un filtre personnalisé. Par exemple, vous pouvez créer un filtre pour afficher les messages de journal de deux apps en même temps.

    Après avoir défini les filtres, vous pouvez également les sélectionner dans le menu. Pour les retirer du menu, supprimez-les.

  2. Si vous avez sélectionné Modifier la configuration du filtre, créez ou modifiez un filtre :
    1. Spécifiez les paramètres du filtre dans la boîte de dialogue Créer un nouveau filtre Logcat :
      • Nom du filtre : Tapez le nom d’un filtre que vous voulez définir, ou sélectionnez-le dans le volet de gauche pour modifier un filtre existant. Le nom peut contenir uniquement des caractères minuscules, des traits de soulignement et des chiffres.
      • Balise de journal : Spécifiez facultativement une balise. Pour plus d’informations, voir le format de message logcat.
      • Message de journal : Spécifier facultativement le texte du message du journal. Pour plus d’informations, voir le format de message logcat.
      • Nom de paquet : Spécifier facultativement un nom de paquet. Pour plus d’informations, voir le format de message logcat.
      • PID : spécifie de manière facultative un identifiant de processus. Pour plus d’informations, voir le format de message logcat.
      • Niveau de journal : Sélectionnez de manière facultative un niveau de journal. Pour plus d’informations, voir Définir le niveau du journal.
      • Regex : Sélectionnez cette option pour utiliser la syntaxe d’expression régulière pour ce paramètre.
    2. Cliquez sur + pour ajouter la définition du filtre au volet de gauche.

      Pour supprimer un filtre, sélectionnez-le dans le volet de gauche et cliquez sur -.

    3. Lorsque vous avez terminé, cliquez sur OK.

Si vous ne pensez pas voir les messages de journal que vous voulez, essayez de sélectionnerAucun filtre et de rechercher des messages de journal particuliers.

Lire les messages de collecte de déchets

Parfois, lorsqu’un événement de collecte de déchets se produit, ils sont imprimés dans logcat.

Pour plus de détails sur la mémoire de votre application, utilisez leMemory Profiler.

Messages de journal Dalvik

Dans Dalvik (mais pas ART), chaque GC imprime les informations suivantes dans logcat:

D/dalvikvm(PID): GC_Reason Amount_freed, Heap_stats, External_memory_stats, Pause_time

Exemple:

D/dalvikvm( 9050): GC_CONCURRENT freed 2049K, 65% free 3571K/9991K, external 4703K/5261K, paused 2ms+2ms

Raison du GC Ce qui a déclenché le GC et de quel type de collecte il s’agit. Les raisons qui peuvent apparaître comprennent :GC_CONCURRENTUne GC concurrente qui libère de la mémoire alors que votre tas commence à se remplir.GC_FOR_MALLOCUn GC a été provoqué parce que votre app a tenté d’allouer de la mémoire alors que votre tas étaitdéjà plein, le système a donc dû arrêter votre app et récupérer de la mémoire.GC_HPROF_DUMP_HEAPUn GC qui se produit lorsque vous demandez la création d’un fichier HPROF pour analyser votre tas.GC_EXPLICITUne GC explicite, comme lorsque vous appelezgc()(que vous devriez éviter d’appeler et plutôt faire confiance à la GC pour s’exécuter lorsque cela est nécessaire).GC_EXTERNAL_ALLOCCela ne se produit que sur l’API de niveau 10 et inférieur (les versions plus récentes allouent tout dans le Dalvikheap). Une GC pour la mémoire allouée en externe (comme les données de pixels stockées en mémoire innative ou les tampons d’octets NIO). Amount freed La quantité de mémoire récupérée de ce GC. Statistiques du tas Pourcentage libre du tas et (nombre d’objets vivants)/(taille totale du tas). Statistiques de la mémoire externe Mémoire allouée en externe au niveau 10 de l’API et inférieur (quantité de mémoire allouée) / (limite à laquelle la collecte aura lieu). Temps de pause Les temps de pause sont plus longs pour les grands tas. Les temps de pause simultanés montrent deux pauses : une au début de la collecte et une autre vers la fin.

Pendant que ces messages de journal s’accumulent, surveillez les augmentations des statistiques du tas (la valeur3571K/9991K dans l’exemple ci-dessus). Si cette valeur continue d’augmenter, vous avez peut-être une fuite de mémoire.

Messages de journal d’ART

Contrairement à Dalvik, ART ne consigne pas les messages pour les GC qui n’ont pas été explicitement demandés. Les GC ne sont mis en pause que lorsqu’ils sont jugés lents. Plus précisément, si la pause GC dépasse 5ms ou si la durée de la GC dépasse 100ms. Si l’application n’est pas dans un état de pause perceptible (comme lorsque l’application est en arrière-plan, où l’utilisateur ne peut pas percevoir une pause GC), alors aucun de ses GC n’est considéré comme lent. Les GC explicites sont toujours journalisées.

ART inclut les informations suivantes dans ses messages de journal de garbage collection:

I/art: GC_Reason GC_Name Objects_freed(Size_freed) AllocSpace Objects, Large_objects_freed(Large_object_size_freed) Heap_stats LOS objects, Pause_time(s)

Exemple:

I/art : Explicit concurrent mark sweep GC freed 104710(7MB) AllocSpace objects, 21(416KB) LOS objects, 33% free, 25MB/38MB, paused 1.230ms total 67.216ms

GC Reason Ce qui a déclenché la GC et de quel type de collecte il s’agit. Les raisons qui peuvent apparaître comprennent :ConcurrentUn GC concurrent qui ne suspend pas les threads de l’appli. Ce GC s’exécute dans un thread d’arrière-planet n’empêche pas les allocations.AllocLa GC a été lancée parce que votre app a tenté d’allouer de la mémoire alors que votre tas était déjà plein. Dans ce cas, le garbage collection a eu lieu dans le thread d’allocation.ExplicitLa collecte des déchets a été explicitement demandée par un utilisateur, par exemple en appelantgc()ougc(). Comme Dalvik, dans ART, la meilleure pratique est de faire confiance au GC et d’éviter de demander des GC explicites, si possible.Les GC explicites sont déconseillés car ils bloquent le thread d’allocation et gaspillent inutilement des cycles de CPU. Les GC explicites peuvent également provoquer un jank (bégaiement, saccades ou arrêt de l’application) s’ils provoquent la préemption d’autres threads.NativeAllocLa collecte a été causée par une pression mémoire provenant d’allocations natives telles que les Bitmaps ou les objets d’allocationRenderScript.CollectorTransitionLa collecte a été causée par une transition de tas ; celle-ci est causée par le changement de la stratégie GC au moment de l’exécution (comme lorsque l’app change entre des états perceptibles en pause). Les transitions du collecteur consistent à copier tous les objets d’un espace soutenu par une liste libre vers un espace de pointeur de bosse (ou vice versa).

Cela ne se produit que sur un appareil à faible mémoire vive avant Android 8.0quand une app change d’état de processus d’un état perceptible de pause (comme lorsque l’app est au premier plan, où l’utilisateur peutprecevoir une pause GC) à un état non perceptible de pause (ou vice versa).

HomogeneousSpaceCompactLe compactage d’espace homogène est un compactage d’espace de liste libre à liste libre qui se produit généralement quand une app est déplacée vers un état de processus imperceptible de pause. Les principales raisons de faire cela sont de réduire l’utilisation de la RAM et de défragmenter le tas.

DisableMovingGcCe n’est pas une vraie raison GC, mais une note que la collecte a été bloquée en raison de l’utilisation deGetPrimitiveArrayCritical. alors que la compaction simultanée du tas se produit. En général, l’utilisation deGetPrimitiveArrayCritical est fortement déconseillée en raison de ses restrictions sur le déplacement des collecteurs.HeapTrimIl ne s’agit pas d’une raison GC, mais d’une note indiquant que la collecte a été bloquée jusqu’à ce qu’une découpe du tas se termine. Nom du GC ART a plusieurs GC différents qui peuvent être exécutés.Concurrent mark sweep (CMS)Un collecteur de tas entier qui libère collecte tous les espaces autres que l’espace image.Concurrent partial mark sweepUn collecteur de tas presque entier qui collecte tous les espaces autres que les espaces image et zygote.Concurrent sticky mark sweepUn collecteur générationnel qui ne peut libérer que les objets alloués depuis la dernière GC. Ce collecteur de déchets est exécuté plus souvent qu’un balayage de marque complet ou partiel car il est plus rapide et comporte moins de pauses.Marksweep + semispaceUn GC non concurrent et copiant utilisé pour les transitions de tas ainsi que le spacecompaction homogène (pour défragmenter le tas). Objets libérés Le nombre d’objets qui ont été récupérés par cette GC dans l’espace des non-gros objets. Taille libérée Le nombre d’octets qui ont été récupérés par ce GC dans l’espace des objets non volumineux. Grands objets libérés Le nombre d’objets dans l’espace des grands objets qui ont été récupérés de cette collection d’ordures. Taille des grands objets libérés Le nombre d’octets dans l’espace des grands objets qui ont été récupérés de cette collection d’ordures. Statistiques du tas Pourcentage libre et (nombre d’objets vivants)/(taille totale du tas). Temps de pause En général, les temps de pause sont proportionnels au nombre de références d’objets qui ont été modifiés pendant l’exécution du GC. Actuellement, les GC de l’ART CMS n’ont qu’une seule pause, vers la fin de la GC.Les GC mobiles ont une longue pause qui dure pendant la majorité de la durée de la GC.

Si vous voyez une grande quantité de GC dans logcat, recherchez des augmentations dans les statistiques du tas (la valeur25MB/38MB dans l’exemple ci-dessus). Si cette valeur continue à augmenter et ne semble jamais diminuer, vous pourriez avoir une fuite de mémoire. Alternativement, si vous voyez GC qui sont pour la raison « Alloc », alors vous opérez déjà près de votre capacité de tas et pouvez vous attendre à des exceptionsOOM dans un avenir proche.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.