Informacje o logowaniu

W tym artykule opisujemy proces logowania, w tym standardy logowania, wytyczne dotyczące poziomów, klasy, cele i przybliżenia wielostosowe.

Standardy logów

Logowanie w Androidzie jest złożone ze względu na mieszankę używanych standardów, które są łączone w logcat. Główne stosowane standardy zostały opisane poniżej:

Źródło Przykłady Wskazówki dotyczące poziomu stosu
RFC 5424 (standard syslog) Jądro Linuksa, wiele aplikacji Unix Jądro, demony systemowe
android.util.Log Platforma Androida + logowanie aplikacji Platforma Androida i aplikacja systemowa
java.util.logging.Level Ogólne rejestrowanie w Javie aplikacja niesystemowa,

Rysunek 1. Standardy poziomu rejestrowania.

Chociaż każdy z tych standardów ma podobną strukturę poziomów, różnią się one szczegółowością. Przybliżone odpowiedniki w poszczególnych standardach są następujące:

Poziom RFC 5424 Poziom ważności RFC 5424 Opis RFC 5424 android.util.Log java.util.logging.Level
0 Połączenie alarmowe System jest bezużyteczny Log.e / Log.wtf SEVERE
1 Alert Działanie musi zostać podjęte natychmiast Log.e / Log.wtf SEVERE
2 Krytyczny Krytyczne warunki Log.e / Log.wtf SEVERE
3 Błąd Warunki błędu Log.e SEVERE
4 Ostrzeżenie Warunki ostrzeżeń Log.w WARNING
5 Uwaga Normalne, ale znaczące Log.w WARNING
6 Informacje Wiadomości informacyjne Log.i INFO
7 Debuguj Wiadomości na poziomie debugowania Log.d CONFIG, FINE
- - Szczegółowe wiadomości Log.v FINER/FINEST

Ilustracja 2. Poziomy rejestrowania w syslog, Androidzie i Javie.

Wytyczne dotyczące poziomu logowania

W przypadku każdego standardu dziennika istnieją wytyczne. Wybrany poziom logowania jest zgodny z odpowiednim standardem, np. w przypadku tworzenia jądra systemu operacyjnego używany jest standard syslog.

Poziomy logowania w kolejności od najniższego do najwyższego przedstawiają 3 rysunki poniżej:

ERROR Te dzienniki są zawsze przechowywane.
WARN Te dzienniki są zawsze przechowywane.
INFO Te dzienniki są zawsze przechowywane.
DEBUG Te logi są kompilowane, ale usuwane w czasie działania programu.
VERBOSE Te logi nigdy nie są kompilowane w aplikacji, z wyjątkiem okresu jej tworzenia.

Rysunek 3: android.util.Log

CONFIG Poziom wiadomości w przypadku statycznych wiadomości konfiguracyjnych
FINE Poziom wiadomości zawierający informacje o śledzeniu
FINER Wskazuje dość szczegółową wiadomość śledzenia
FINEST Wskazuje bardzo szczegółową wiadomość śledzenia
INFO Poziom wiadomości w przypadku wiadomości informacyjnych
SEVERE Poziom wiadomości wskazujący poważną awarię
WARNING Poziom wiadomości wskazujący potencjalny problem

Rysunek 4: java.util.Logging.Level

0 Połączenie alarmowe System jest bezużyteczny
1 Alert Działanie musi zostać podjęte natychmiast
2 Krytyczny Krytyczne warunki
3 Błąd Warunki błędu
4 Ostrzeżenie Warunki ostrzeżeń
5 Uwaga Normalny, ale istotny stan
6 Informacyjne Wiadomości informacyjne
7 Debuguj Wiadomości na poziomie debugowania

Rysunek 5: RFC 5424 – sekcja 6.2.1.

Logowanie aplikacji

Selektywne rejestrowanie jest wykonywane za pomocą TAG przez klasę android.util.Log przy użyciu Log#isLoggable, jak pokazano poniżej:

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

Logi można dostosowywać w czasie działania programu, aby zapewnić wybrany poziom rejestrowania, jak pokazano poniżej:

adb shell setprop log.tag.FOO_TAG VERBOSE

Właściwości log.tag.* są resetowane po ponownym uruchomieniu. Istnieją też trwałe warianty, które pozostają aktywne po ponownym uruchomieniu. Zobacz poniżej:

adb shell setprop persist.log.tag.FOO_TAG VERBOSE

Sprawdzanie Log#isLoggable pozostawia ślady w kodzie aplikacji. Boolean DEBUG oznacza ślady dziennika pomijania za pomocą optymalizacji kompilatora ustawionych na false, jak pokazano poniżej:

private final static boolean DEBUG = false;

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

Rejestrowanie można usunąć w przypadku poszczególnych plików APK za pomocą zestawów reguł ProGuard R8 w momencie kompilacji. W tym przykładzie usuwamy wszystkie logi poniżej poziomu INFO dla 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

Jest to przydatne w przypadku obsługi wielu typów kompilacji aplikacji (np. kompilacji deweloperskich i wersji), w których kod źródłowy powinien być taki sam, ale dopuszczalne poziomy logowania są różne. W przypadku aplikacji (zwłaszcza systemowych) musi być ustawiona i przestrzegana wyraźna zasada, która określa, jak typy kompilacji i oczekiwania dotyczące wersji wpływają na dane wyjściowe dziennika.

Logowanie systemowe w środowisku wykonawczym Androida (ART)

Dostępnych jest kilka klas, które są dostępne dla aplikacji i usług systemowych:

Zajęcia Cel
android.telephony.Rlog Rejestrowanie radiowe
android.util.Log Ogólne logowanie aplikacji
android.util.EventLog Rejestrowanie zdarzeń diagnostycznych integratora systemów
android.util.Slog Logowanie platformy

Rysunek 6. Dostępne klasy logów systemowych i ich zastosowania.

Chociaż android.util.Logandroid.util.Slog korzystają z tych samych standardów poziomu logowania, Slog to klasa @hide, której może używać tylko platforma. Poziomy EventLog są mapowane na wpisy w pliku event.logtags w /system/etc/event-log-tags.

Logowanie natywne

Logowanie w C/C++ jest zgodne ze standardem syslog, przy czym syslog(2) odpowiada syslog jądru systemu Linux, które kontroluje bufor printk, a syslog(3) odpowiada ogólnemu rejestratorowi systemu. Android korzysta z biblioteki liblog do ogólnego rejestrowania zdarzeń systemowych.

liblog udostępnia otoczki dla grup podlogów w tym formacie makra:

[Sublog Buffer ID] LOG [Log Level ID]

RLOGD odpowiada na przykład [Radio log buffer ID] LOG [Debug Level]. Główne elementy opakowujące liblog to:

Klasa opakowująca Przykładowe funkcje
log_main.h ALOGV, ALOGW
log_radio.h RLOGD, RLOGE
log_system.h SLOGI, SLOGW

Rysunek 7. Otoczki liblog.

Android ma interfejsy wyższego poziomu do rejestrowania, które są preferowane w stosunku do bezpośredniego użycia, jak widać poniżej:liblog

Biblioteka Wykorzystanie
async_safe Biblioteka przeznaczona tylko do rejestrowania w środowiskach bezpiecznych pod względem sygnałów asynchronicznych
libbase Biblioteka rejestrowania, która udostępnia interfejs strumienia C++ do rejestrowania podobny do rejestrowania w stylu Google (glog). libbase można używać w projektach zewnętrznych i jest dostępny w aplikacjach korzystających z libbase_ndk.

Rysunek 8. Biblioteki dzienników wyższego poziomu.

Przybliżenia wielostosowe

Ze względu na różnice w poziomie szczegółowości i zamiaru nie ma jasnych ani dokładnych odpowiedników różnych standardów rejestrowania. Na przykład poziomy java.util.logging.Levelandroid.util.Log w przypadku logów błędów nie są odpowiednikami 1:1:

java.util.Logging.Level android.util.Log
POWAŻNE Log.wtf
POWAŻNE Log.e

Rysunek 9. Poziom błędu w standardowym logowaniu w Java w porównaniu z logowaniem w Androidzie.

W takich przypadkach użyj poszczególnych standardów, aby określić, który poziom zastosować.

Podczas tworzenia systemu z wieloma komponentami na poziomie stosu postępuj zgodnie z rysunkiem 1, aby określić, którego standardu użyć w przypadku poszczególnych komponentów. Przybliżone wskazówki dotyczące wiadomości na poszczególnych poziomach znajdziesz na rysunku 2.

Prywatność i bezpieczeństwo

Nie rejestruj informacji umożliwiających identyfikację. Obejmuje to takie informacje jak:

  • Adresy e-mail
  • numery telefonów,
  • imiona i nazwiska,

Podobnie niektóre szczegóły są uważane za poufne, nawet jeśli nie umożliwiają bezpośredniej identyfikacji.

Na przykład informacje o strefie czasowej nie są uznawane za informacje umożliwiające identyfikację, ale wskazują przybliżoną lokalizację użytkownika.

Zasady logowania i dopuszczalne szczegóły muszą zostać uwzględnione w ramach kontroli bezpieczeństwa i prywatności przed udostępnieniem.

dziennikami urządzenia.

Dostęp do wszystkich dzienników urządzenia, w tym do korzystania z android.permission.READ_LOGS, jest ograniczony:

  • Jeśli aplikacja działająca w tle poprosi o dostęp do wszystkich dzienników urządzenia, prośba zostanie automatycznie odrzucona, chyba że aplikacja:
    • Udostępnia identyfikator UID systemu.
    • Używa natywnego procesu systemowego (UID < APP_UID).
    • Używana strefa czasowa: DropBoxManager.
    • Dostęp tylko do bufora dziennika zdarzeń.
    • Korzysta z interfejsu API EventLog.
    • Korzysta z testów z instrumentacją.
  • Jeśli aplikacja na pierwszym planie z READ_LOGS poprosi o dostęp do dzienników urządzenia, system wyświetli prośbę o zgodę na dostęp lub odmowę dostępu.