Informationen zum Logging

In diesem Artikel werden Protokollierungsverfahren, einschließlich Protokollstandards, Richtlinien für Ebenen, Klassen, Zwecke und Multistack-Schätzungen behandelt.

Protokollstandards

Die Protokollierung unter Android ist aufgrund der verschiedenen Standards, die in logcat kombiniert werden, komplex. Die wichtigsten Standards werden unten beschrieben:

Source Beispiele Leitfäden auf Stack-Ebene
RFC 5424 (syslog Standard) Linux-Kernel, viele Unix-Anwendungen 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:Standards für die Protokollebene

Obwohl die Struktur der einzelnen Standards ähnlich ist, unterscheiden sie sich in der Detaillierung. Die ungefähren Entsprechungen zwischen den Standards sind:

RFC 5424-Ebene Schweregrad gemäß RFC 5424 RFC 5424 – Beschreibung android.util.Log java.util.logging.Level
0 Notfall System ist nicht benutzbar Log.e / Log.wtf SEVERE
1 Benachrichtigung 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 Benachrichtigungen über Informationen Log.i INFO
7 Fehler beheben Nachrichten auf Debug-Ebene Log.d CONFIG, FINE
- - Ausführliche Nachrichten Log.v FINER/FINEST

Abbildung 2:syslog-, Android- und Java-Protokollierungsebenen

Richtlinien für die Protokollebene

Für jeden Protokollstandard gibt es bereits vorhandene Richtlinien. Die ausgewählte Protokollebene entspricht dem entsprechenden Standard, z. B. dem syslog-Standard für die Kernelentwicklung.

Die Reihenfolge der Logebenen, von niedrigster zu höchster, 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 Protokolle werden kompiliert, aber zur Laufzeit entfernt.
VERBOSE Diese Protokolle werden nur während der Entwicklung in eine App kompiliert.

Abbildung 3:android.util.Log

CONFIG Nachrichtenebene für statische Konfigurationsnachrichten
FINE Nachrichtenebene mit Informationen zur Fehlerbehebung
FINER Gibt eine ziemlich detaillierte Tracing-Nachricht an.
FINEST Gibt eine sehr detaillierte Tracing-Nachricht an.
INFO Nachrichtenebene für öffentliche Sicherheitsinformationen
SEVERE Nachrichtenebene, 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 benutzbar
1 Benachrichtigung 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

Die selektive Protokollierung erfolgt mit der Klasse TAG nach android.util.Log mit Log#isLoggable, 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 eine bestimmte Logging-Ebene bereitgestellt wird, wie unten dargestellt:

adb shell setprop log.tag.FOO_TAG VERBOSE

log.tag.*-Properties werden beim Neustart zurückgesetzt. Es gibt auch persistente Varianten, die auch nach einem Neustart bestehen bleiben. Siehe unten:

adb shell setprop persist.log.tag.FOO_TAG VERBOSE

Log#isLoggable-Prüfungen hinterlassen Protokollspuren im App-Code. Boolesche DEBUG-Flags umgehen Protokoll-Traces mit Compileroptimierungen, die auf false gesetzt sind, wie unten dargestellt:

private final static boolean DEBUG = false;

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

Die Protokollierung kann bis zum R8 per APK über ProGuard-Regeln zur Kompilierungszeit entfernt werden. Im folgenden Beispiel wird alles unterhalb der INFO-Ebene 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 mehrere App-Build-Typen verarbeitet werden (z. B. Entwicklungs- und Release-Builds), bei denen der zugrunde liegende Code gleich sein soll, die zulässigen Protokollebenen jedoch unterschiedlich sind. Für Apps (insbesondere System-Apps) muss eine explizite Richtlinie festgelegt und befolgt werden, um zu entscheiden, wie sich Buildtypen und Release-Erwartungen auf die Protokollausgabe auswirken.

Systemprotokollierung in der Android Runtime (ART)

Es gibt mehrere Klassen, die für System-Apps und ‑Dienste verfügbar sind:

Kurs Zweck
android.telephony.Rlog Radio-Logging
android.util.Log Allgemeines App-Logging
android.util.EventLog Protokollierung von Diagnoseereignissen des Systemintegrators
android.util.Slog Logging des Plattform-Frameworks

Abbildung 6:Verfügbare Systemprotokollklassen und -zwecke

Obwohl android.util.Log und android.util.Slog dieselben Standards für die Logebene verwenden, ist Slog 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++ entspricht 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 allgemeine Systemprotokolle.

liblog bietet Wrapper für die Unter-Bloggruppen mit 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 höhere Schnittstellen für die Protokollierung, die gegenüber der direkten Verwendung von liblog bevorzugt werden, wie unten dargestellt:

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

Abbildung 8:Logbibliotheken höherer Ebene

Multistack-Schätzungen

Aufgrund von Unterschieden in der Detaillierung und der Ebenenintention gibt es keine eindeutige oder genaue Übereinstimmung zwischen den verschiedenen Protokollierungsstandards. Die Ebenen java.util.logging.Level und android.util.Log für Fehlerprotokolle stimmen beispielsweise nicht genau überein:

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

Abbildung 9:Fehlerebene im standardmäßigen 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 Stackebene können Sie anhand von Abbildung 1 ermitteln, welcher Standard pro Komponente verwendet werden soll. Eine ungefähre Anleitung zu Nachrichtenebenen findest du in Abbildung 2.

Sicherheit und Datenschutz

Personenidentifizierbare Informationen dürfen nicht protokolliert werden. Dazu gehören unter anderem folgende Details:

  • E‑Mail-Adressen
  • Telefonnummern
  • Namen

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

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

Die Protokollierungsrichtlinien und zulässigen 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 erfüllt folgende Voraussetzungen:
    • Die System-UID wird freigegeben.
    • Es wird ein nativer Systemprozess verwendet (UID < APP_UID).
    • Verwendet DropBoxManager.
    • Es wird nur auf den Ereignisprotokoll-Puffer zugegriffen.
    • Verwendet die EventLog API.
    • Es werden instrumentierte Tests verwendet.
  • Wenn eine App im Vordergrund mit READ_LOGS Zugriff auf Geräteprotokolle anfordert, wird der Nutzer vom System aufgefordert, die Zugriffsanfrage zu genehmigen oder abzulehnen.