Informationen zum Logging

In diesem Artikel wird der Prozess der Protokollierung beschrieben, einschließlich Protokollstandards, Richtlinien für die Ebene, Klassen, Zwecke und Multistack-Näherungen.

Log-Standards

Das Logging in Android ist komplex, da verschiedene Standards verwendet werden, die in logcat kombiniert werden. Die wichtigsten verwendeten Standards sind unten aufgeführt:

Source Beispiele Anleitung für die Stack-Ebene
RFC 5424 (syslog Standard) Linux-Kernel, viele Unix-Apps Kernel, System-Daemons
android.util.Log Android-Framework + App-Logging Android-Framework und System-App
java.util.logging.Level Allgemeines Logging in Java Nicht-System-App

Abbildung 1:Logebenenstandards.

Die einzelnen Standards haben zwar eine ähnliche Ebenenstruktur, unterscheiden sich aber in der Granularität. Ungefähre Entsprechungen zwischen den Standards:

RFC 5424-Ebene RFC 5424 – Schweregrad RFC 5424-Beschreibung android.util.Log java.util.logging.Level
0 Notfall System ist nicht nutzbar Log.e / Log.wtf SEVERE
1 Benachrichtigung Es sind sofortige Maßnahmen erforderlich Log.e / Log.wtf SEVERE
2 Kritisch Kritische Bedingungen Log.e / Log.wtf SEVERE
3 Fehler Fehlerbedingungen Log.e SEVERE
4 Warnung Warnbedingungen Log.w WARNING
5 Hinweis Normal, aber signifikant Log.w WARNING
6 Info Informationsnachrichten Log.i INFO
7 Fehler beheben Nachrichten auf Debug-Ebene Log.d CONFIG, FINE
- - Ausführliche Benachrichtigungen Log.v FINER/FINEST

Abbildung 2:syslog-, Android- und Java-Logging-Stufen.

Richtlinien für Protokollebenen

Für jeden Logstandard gibt es bestehende Richtlinien. Die ausgewählte Logebene entspricht dem verwendeten Standard, z. B. dem syslog-Standard für die Kernelentwicklung.

Die Reihenfolge der Logebenen (von der niedrigsten zur höchsten) ist in den drei Abbildungen unten dargestellt:

ERROR Diese Protokolle werden immer aufbewahrt.
WARN Diese Protokolle werden immer aufbewahrt.
INFO Diese Protokolle werden immer aufbewahrt.
DEBUG Diese Logs werden kompiliert, aber zur Laufzeit entfernt.
VERBOSE Diese Logs werden nie in eine App kompiliert, außer während der Entwicklung.

Abbildung 3:android.util.Log

CONFIG Meldungsebene für statische Konfigurationsmeldungen
FINE Meldungsebene mit Informationen zur Ablaufverfolgung
FINER Gibt eine relativ detaillierte Tracing-Meldung an.
FINEST Gibt eine sehr detaillierte Tracing-Nachricht an.
INFO Nachrichtenebene für Informationsmeldungen
SEVERE Meldungsebene, die auf einen schwerwiegenden Fehler hinweist
WARNING Nachrichtenebene, die auf ein potenzielles Problem hinweist

Abbildung 4:java.util.Logging.Level.

0 Notfall System ist nicht nutzbar
1 Benachrichtigung Es sind sofortige Maßnahmen erforderlich
2 Kritisch Kritische Bedingungen
3 Fehler Fehlerbedingungen
4 Warnung Warnbedingungen
5 Hinweis Normaler, aber signifikanter Zustand
6 Information Mitteilungen
7 Fehler beheben Nachrichten auf Debug-Ebene

Abbildung 5:RFC 5424 – Abschnitt 6.2.1.

App-Logging

Das selektive Logging wird mit TAG von der Klasse android.util.Log mit Log#isLoggable durchgeführt, wie unten dargestellt:

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

Logs können zur Laufzeit so angepasst werden, dass ein bestimmtes Logging-Niveau erreicht wird, wie unten dargestellt:

adb shell setprop log.tag.FOO_TAG VERBOSE

log.tag.*-Eigenschaften werden beim Neustart zurückgesetzt. Es gibt auch persistente Varianten, die nach Neustarts bestehen bleiben. Sehen Sie:

adb shell setprop persist.log.tag.FOO_TAG VERBOSE

Log#isLoggable-Prüfungen hinterlassen Protokollspuren im App-Code. Boolesche DEBUG-Flags umgehen Log-Traces mithilfe von Compiler-Optimierungen, die auf false festgelegt sind, wie unten dargestellt:

private final static boolean DEBUG = false;

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

Die Protokollierung kann pro APK über ProGuard-Regelsätze durch R8 zur Kompilierungszeit entfernt werden. Im folgenden Beispiel wird alles unterhalb der Protokollierungsebene INFO für android.util.Log entfernt:

# 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

Dies ist nützlich, wenn Sie mehrere App-Build-Typen verarbeiten müssen (z. B. Entwicklungs-Builds im Vergleich zu Release-Builds), bei denen der zugrunde liegende Code identisch sein soll, die zulässigen Logebenen jedoch unterschiedlich sind. Für Apps (insbesondere System-Apps) muss eine explizite Richtlinie festgelegt und eingehalten werden, um zu entscheiden, wie sich Build-Typen und Release-Erwartungen auf die Protokollausgabe auswirken.

Systemprotokollierung in der Android Runtime (ART)

Für System-Apps und ‑Dienste sind mehrere Klassen verfügbar:

Kurs Zweck
android.telephony.Rlog Funkschnittstellen-Logging
android.util.Log Allgemeines App-Logging
android.util.EventLog Diagnoseereignis-Logging für Systemintegratoren
android.util.Slog Plattform-Framework-Logging

Abbildung 6:Verfügbare Systemprotokollklassen und ‑zwecke.

android.util.Log und android.util.Slog verwenden zwar dieselben Logebenenstandards, Slog ist jedoch eine @hide-Klasse, die nur von der Plattform verwendet werden kann. Die EventLog-Ebenen werden den Einträgen in der Datei event.logtags in /system/etc/event-log-tags zugeordnet.

Natives Logging

Das Logging in C/C++ folgt dem syslog-Standard. Dabei entspricht syslog(2) dem Linux-Kernel syslog, der den printk-Puffer steuert, und syslog(3) dem allgemeinen Systemlogger. Android verwendet die Bibliothek liblog für das allgemeine System-Logging.

liblog bietet Wrapper für die Unterloggruppen in der folgenden Makroform:

[Sublog Buffer ID] LOG [Log Level ID]

RLOGD entspricht beispielsweise [Radio log buffer ID] LOG [Debug Level]. Die wichtigsten liblog-Wrapper sind:

Wrapper-Klasse Beispielfunktionen
log_main.h ALOGV, ALOGW
log_radio.h RLOGD, RLOGE
log_system.h SLOGI, SLOGW

Abbildung 7:liblog-Wrapper.

Android bietet Schnittstellen auf höherer Ebene für die Protokollierung, die der direkten Verwendung von liblog vorgezogen werden, wie unten zu sehen ist:

Mediathek Nutzung
async_safe Bibliothek nur für die Protokollierung aus asynchronen signal-safe-Umgebungen
libbase Logging-Bibliothek, die eine C++-Stream-Schnittstelle für das Logging bietet, ähnlich dem Logging im Google-Stil (glog). libbase kann sowohl in externen Projekten verwendet werden als auch in Apps, die libbase_ndk nutzen.

Abbildung 8:Protokollbibliotheken auf höherer Ebene.

Multistack-Schätzungen

Aufgrund von Unterschieden in Bezug auf Granularität und Intention auf Ebene gibt es keine klaren oder genauen Übereinstimmungen zwischen verschiedenen Protokollierungsstandards. Die Ebenen java.util.logging.Level und android.util.Log für Fehlerlogs stimmen beispielsweise nicht 1:1 überein:

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

Abbildung 9:Fehlerstufe im Standard-Java-Logging im Vergleich zum Android-Logging.

In solchen Fällen müssen Sie anhand des jeweiligen Standards ermitteln, welche Stufe angewendet werden soll.

Bei der Systementwicklung mit mehreren Komponenten auf Stapelebene können Sie anhand von Abbildung 1 ermitteln, welcher Standard für die jeweilige Komponente verwendet werden soll. Abbildung 2 bietet eine ungefähre Anleitung für die Kommunikation mit den verschiedenen Stufen.

Sicherheit und Datenschutz

Protokollieren Sie keine personenidentifizierbaren Informationen. Dazu gehören Details wie:

  • E‑Mail-Adressen
  • Telefonnummern
  • Namen

Bestimmte Details gelten als vertraulich, auch wenn sie nicht explizit personenidentifizierbar sind.

Zeitzoneninformationen gelten beispielsweise nicht als personenidentifizierbar, geben aber einen Hinweis auf den ungefähren Standort eines Nutzers.

Die Protokollrichtlinie und akzeptable Details müssen vor der Veröffentlichung im Rahmen der Sicherheits- und Datenschutzüberprüfung behandelt werden.

Geräteprotokolle

Der Zugriff auf alle Geräteprotokolle, einschließlich der Verwendung von android.permission.READ_LOGS, ist eingeschränkt:

  • Wenn eine App im Hintergrund Zugriff auf alle Geräteprotokolle anfordert, wird die Anfrage automatisch abgelehnt, es sei denn, die App:
    • Gibt die System-UID weiter.
    • Es wird ein nativer Systemprozess verwendet (UID < APP_UID).
    • Verwendet DropBoxManager.
    • Greift nur auf den Ereignisprotokollpuffer zu.
    • Verwendet die EventLog API.
    • Verwendet instrumentierte Tests.
  • Wenn eine App im Vordergrund mit READ_LOGS Zugriff auf Geräteprotokolle anfordert, werden Nutzer vom System aufgefordert, die Zugriffsanfrage zu genehmigen oder abzulehnen.