Comprendre la journalisation

Cet article décrit le processus de journalisation, y compris les normes de journalisation, les consignes relatives aux niveaux, les classes, les objectifs et les approximations multipiles.

Normes de journalisation

La journalisation sur Android est complexe en raison du mélange de normes utilisées 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 (syslog standard) Noyau Linux, nombreuses applications Unix Noyau, daemons système
android.util.Log Framework Android + journalisation de l'application 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 la construction des niveaux de chacune de ces normes soit similaire, leur granularité varie. Les équivalences approximatives entre les normes sont les suivantes:

Niveau de la RFC 5424 Gravité de la RFC 5424 Description de la RFC 5424 android.util.Log java.util.logging.Level
0 Urgence Système inutilisable Log.e / Log.wtf SEVERE
1 Alerte Une action immédiate est requise Log.e / Log.wtf SEVERE
2 Critical (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 Infos Messages d'information Log.i INFO
7 Déboguer Messages de niveau "Débogage" Log.d CONFIG, FINE
- - Messages détaillés Log.v FINER/FINEST

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

Consignes concernant les niveaux de journalisation

Des consignes sont fournies pour chaque norme de journalisation. Le niveau de journalisation choisi suit la norme appropriée utilisée, comme la norme syslog pour le développement du noyau.

Les trois figures ci-dessous montrent l'ordre des niveaux de journalisation, du plus bas au plus élevé:

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 du 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 un échec grave
WARNING Niveau de message indiquant un problème potentiel

Figure 4:java.util.Logging.Level.

0 Urgence Système inutilisable
1 Alerte Une action immédiate est requise
2 Critical (Critique) Conditions critiques
3 Erreur Conditions d'erreur
4 Avertissement Conditions d'avertissement
5 Avis État normal, mais important
6 Informatif 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 à l'aide de Log#isLoggable, comme illustré ci-dessous:

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

Les journaux peuvent être configuré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 restent après les 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 de 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 des règles ProGuard par R8 au moment de la compilation. L'exemple suivant supprime tout ce qui se trouve en dessous du niveau de journalisation 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

Cela est utile pour gérer plusieurs types de compilations d'applications (par exemple, les compilations de développement par rapport aux compilations de version), où le code sous-jacent est censé être le même, mais où les niveaux de journalisation autorisés sont différents. Une règle explicite doit être définie et suivie pour les applications (en particulier les applications système) afin de déterminer comment les types de compilation et les attentes de publication affectent la sortie des journaux.

Journalisation système dans Android Runtime (ART)

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

Cours Objectif
android.telephony.Rlog Journalisation de la 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 framework de plate-forme

Figure 6:Classes et objectifs des journaux 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, syslog(2) correspondant au syslog du kernel Linux qui contrôle le tampon printk et syslog(3) correspondant au journal du système général. Android utilise la bibliothèque liblog pour la journalisation système générale.

liblog fournit des wrappers pour les groupes de sous-blogs à l'aide de 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 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:wrappers liblog.

Android dispose d'interfaces de journalisation de niveau supérieur qui sont privilégiées par rapport à l'utilisation directe de liblog, comme indiqué ci-dessous:

Bibliothèque Utilisation
async_safe Bibliothèque réservée à la journalisation à partir d'environnements sécurisés par signal asynchrone
libbase Bibliothèque de journalisation qui fournit une interface de flux C++ à la journalisation, semblable à la journalisation de style Google (glog). libbase est utilisable dans les 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 précision et d'intention de niveau, il n'existe pas de correspondances claires ni exactes entre les différentes normes de journalisation. Par exemple, les niveaux java.util.logging.Level et android.util.Log des journaux d'erreur ne correspondent pas de manière exacte :

java.util.Logging.Level android.util.Log
SEVERE Log.wtf
SEVERE Log.e

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

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

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

Sécurité et confidentialité

Ne conservez pas d'informations permettant d'identifier personnellement l'utilisateur. Cela inclut des informations telles que:

  • Adresses e-mail
  • Numéros de téléphone
  • Les noms

De même, certaines informations sont considérées comme sensibles, même si elles ne permettent pas explicitement d'identifier personnellement l'utilisateur.

Par exemple, bien que les informations sur le fuseau horaire ne soient pas considérées comme des informations permettant d'identifier personnellement l'utilisateur, elles donnent une indication sur la position approximative de l'utilisateur.

Le règlement sur les journaux et les informations 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'aide de android.permission.READ_LOGS, est limité:

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