Comprendre la journalisation

Cet article couvre le processus de journalisation, y compris les normes de journalisation, les directives de niveau, les classes, les objectifs et les approximations multipiles.

Normes de journal

La connexion à Android est complexe en raison du mélange de normes utilisées qui sont combinées dans logcat . Les principales normes utilisées sont détaillées ci-dessous :

Source Exemples Conseils au niveau de la pile
RFC 5424 (norme syslog ) Noyau Linux, nombreuses applications Unix Noyau, démons système
android.util.Log Framework Android + journalisation des applications Framework Android et application système
java.util.logging.Level Journalisation générale en Java application non système

Figure 1 : Normes de niveau de journalisation.

Bien que chacune de ces normes ait un niveau de construction similaire, leur granularité varie. Les équivalents approximatifs entre les normes sont les suivants :

Niveau RFC 5424 Gravité RFC 5424 RFC 5424 Description android.util.Log java.util.logging.Level
0 Urgence Le système est inutilisable Log.e / Log.wtf SEVERE
1 Alerte Il faut agir immédiatement Log.e / Log.wtf SEVERE
2 Critique Conditions critiques Log.e / Log.wtf SEVERE
3 Erreur Conditions d'erreur Log.e SEVERE
4 Avertissement Conditions d'avertissement Log.w WARNING
5 Avis Normal mais significatif Log.w WARNING
6 Info Messagerie d'information Log.i INFO
7 Déboguer Messages de niveau débogage Log.d CONFIG , FINE
- - Messagerie détaillée Log.v FINER / LE PLUS FINEST

Figure 2 : niveaux de journalisation syslog , Android et Java.

Consignes relatives au niveau de journalisation

Il existe des lignes directrices existantes données pour chaque norme de journal. Le niveau de journalisation choisi suit la norme appropriée utilisée, comme l'utilisation de la norme syslog pour le développement du noyau.

Les ordres de niveau de journal, du moins au plus, sont indiqués dans les trois figures ci-dessous :

ERROR Ces journaux sont toujours conservés.
WARN Ces journaux sont toujours conservés.
INFO Ces journaux sont toujours conservés.
DEBUG Ces journaux sont compilés mais supprimés lors de l'exécution.
VERBOSE Ces journaux ne sont jamais compilés dans une application, sauf pendant le développement.

Figure 3 : android.util.Log

CONFIG Niveau de message pour les messages de configuration statiques
FINE Niveau de message fournissant des informations de traçage
FINER Indique un message de traçage assez détaillé
FINEST Indique un message de traçage très détaillé
INFO Niveau de message pour les messages d'information
SEVERE Niveau de message indiquant une panne grave
WARNING Niveau de message indiquant un problème potentiel

Figure 4 : java.util.Logging.Level .

0 Urgence Le système est inutilisable
1 Alerte Il faut agir immédiatement
2 Critique Conditions critiques
3 Erreur Conditions d'erreur
4 Avertissement Conditions d'avertissement
5 Avis État normal mais significatif
6 Informationnel Messages d'information
7 Déboguer Messages de niveau débogage

Figure 5 : RFC 5424 - Section 6.2.1 .

Journalisation des applications

La journalisation sélective est effectuée avec TAG par la classe android.util.Log en utilisant Log#isLoggable , comme indiqué ci-dessous :

if (Log.isLoggable("FOO_TAG", Log.VERBOSE)) {
 Log.v("FOO_TAG", "Message for logging.");
}

Les journaux peuvent être réglés au moment de l'exécution pour fournir un niveau de journalisation sélectionné, comme indiqué ci-dessous :

adb shell setprop log.tag.FOO_TAG VERBOSE

Les propriétés log.tag.* sont réinitialisées au redémarrage. Il existe également des variantes persistantes qui subsistent lors des redémarrages. Voir ci-dessous:

adb shell setprop persist.log.tag.FOO_TAG VERBOSE

Les vérifications Log#isLoggable laissent des traces de journal dans le code de l'application. Les indicateurs booléens DEBUG contournent les traces de journal à l'aide d'optimisations du compilateur définies sur false , comme indiqué ci-dessous :

private final static boolean DEBUG = false;

… If (DEBUG) { Log.v("FOO_TAG", "Extra debug logging."); }

La journalisation peut être supprimée par APK via les ensembles de règles ProGuard par R8 au moment de la compilation. L'exemple suivant supprime tout ce qui se trouve sous la journalisation de niveau INFO pour android.util.Log :

# This allows proguard to strip isLoggable() blocks containing only <=INFO log
# code from release builds.
-assumenosideeffects class android.util.Log {
  static *** i(...);
  static *** d(...);
  static *** v(...);
  static *** isLoggable(...);
}
-maximumremovedandroidloglevel 4

Ceci est utile pour gérer plusieurs types de build d'application (par exemple, les builds de développement par rapport aux builds de version) où le code sous-jacent est censé être le même, mais les niveaux de journalisation autorisés sont différents. Une stratégie explicite doit être définie et suivie pour les applications (en particulier les applications système) afin de décider de l'impact des types de build et des attentes de publication sur la sortie du journal.

Journalisation du système dans Android Runtime (ART)

Plusieurs classes sont disponibles pour les applications système et les services :

Classe Objectif
android.telephony.Rlog Enregistrement radio
android.util.Log Journalisation générale des applications
android.util.EventLog Journalisation des événements de diagnostic de l'intégrateur système
android.util.Slog Journalisation du cadre de la plate-forme

Figure 6 : Classes et objectifs de journal système disponibles.

Bien que android.util.Log et android.util.Slog utilisent les mêmes normes de niveau de journalisation, Slog est une classe @hide utilisable uniquement par la plate-forme. Les niveaux EventLog sont mappés aux entrées du fichier event.logtags dans /system/etc/event-log-tags .

Journalisation native

La journalisation en C/C++ suit la norme syslog avec syslog (2) correspondant au syslog du noyau Linux qui contrôle le tampon printk , et syslog (3) correspondant au journal système général. Android utilise la bibliothèque liblog pour la journalisation générale du système.

liblog fournit des wrappers pour les groupes de sous-journaux en utilisant la forme de macro suivante :

[Sublog Buffer ID] LOG [Log Level ID]

RLOGD , par exemple, correspond à [Radio log buffer ID] LOG [Debug Level] . Les principaux wrappers de liblog sont les suivants :

Classe wrapper Exemples de fonctions
log_main.h ALOGV , ALOGW
log_radio.h RLOGD , RLOGE
log_system.h SLOGI , SLOGW

Figure 7 : enveloppes liblog .

Android a des interfaces de niveau supérieur pour la journalisation qui sont préférées à l'utilisation directe de liblog , comme indiqué ci-dessous :

Bibliothèque Usage
async_safe Bibliothèque uniquement pour la journalisation à partir d'environnements sécurisés pour les signaux asynchrones
libbase Bibliothèque de journalisation qui fournit une interface de flux C++ pour la journalisation, similaire à la journalisation de style Google (glog). libbase est utilisable dans les deux projets externes et est disponible dans les applications utilisant libbase_ndk .

Figure 8 : Bibliothèques de journaux de niveau supérieur.

Approximations multipiles

En raison des différences de granularité et d'intention de niveau, il n'y a pas de correspondance claire ou exacte des différentes normes de journalisation. Par exemple, les niveaux java.util.logging.Level et android.util.Log pour les journaux d'erreurs ne correspondent pas 1:1 :

java.util.Logging.Level android.util.Log
SÉVÈRE Log.wtf
SÉVÈRE Log.e

Figure 9 : Niveau d'erreur dans la journalisation Java standard par rapport à la journalisation Android.

Dans de tels cas, utilisez la norme individuelle pour déterminer le niveau à appliquer.

Lors du développement du système avec plusieurs composants au niveau de la pile, suivez la figure 1 pour déterminer la norme à utiliser par composant. Pour un guide approximatif de la messagerie de niveau, suivez la figure 2.

Sécurité et confidentialité

N'enregistrez pas d'informations personnelles identifiables (PII). Cela inclut des détails tels que :

  • Adresses mail
  • Numéros de téléphone
  • Des noms

De même, certains détails sont considérés comme sensibles même s'ils ne sont pas explicitement personnellement identifiables.

Par exemple, bien que les informations sur le fuseau horaire ne soient pas considérées comme personnellement identifiables, elles donnent une indication de l'emplacement approximatif d'un utilisateur.

La politique de journalisation et les détails acceptables doivent être traités dans le cadre de l'examen de la sécurité et de la confidentialité avant la publication.

Journaux de l'appareil

L'accès à tous les journaux de l'appareil, y compris l'utilisation d' android.permission.READ_LOGS , est limité :

  • Si une application en arrière-plan demande l'accès à tous les journaux de l'appareil, la demande est automatiquement refusée, sauf si l'application :
    • partage l'UID du système.
    • utilise un processus système natif ( UID < APP_UID ).
    • utilise DropBoxManager .
    • accède uniquement au tampon du journal des événements.
    • utilise l'API EventLog .
    • utilise des tests instrumentés.
  • Si une application au premier plan avec READ_LOGS demande l'accès aux journaux de l'appareil, le système invite l'utilisateur à approuver ou à refuser la demande d'accès.