Zrozumienie logowania

W tym artykule omówiono proces rejestrowania, w tym standardy dziennika, wytyczne dotyczące poziomów, klasy, cele i przybliżenia wielopoziomowe.

Standardy dziennika

Logowanie w systemie Android jest złożone ze względu na mieszankę stosowanych standardów połączonych w logcat . Poniżej szczegółowo opisano główne stosowane standardy:

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

Rysunek 1: Standardy poziomu kłody.

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

Poziom RFC 5424 RFC 5424 Ważność Opis RFC 5424 android.util.Log java.util.logging.Level
0 Nagły wypadek System jest bezużyteczny Log.e / Log.wtf SEVERE
1 Alarm Należy natychmiast podjąć działania Log.e / Log.wtf SEVERE
2 Krytyczny Warunki krytyczne Log.e / Log.wtf SEVERE
3 Błąd Warunki błędu Log.e SEVERE
4 Ostrzeżenie Warunki ostrzegawcze Log.w WARNING
5 Ogłoszenie Normalne, ale znaczące Log.w WARNING
6 Informacje Przesyłanie informacji Log.i INFO
7 Odpluskwić Komunikaty na poziomie debugowania Log.d CONFIG ., FINE
- - Szczegółowe wiadomości Log.v FINER / FINEST

Rysunek 2: Poziomy rejestrowania syslog , Android i Java.

Wytyczne dotyczące poziomu dziennika

Istnieją istniejące wytyczne dotyczące każdego standardu bali. Wybrany poziom dziennika jest zgodny z używanym odpowiednim standardem, np. standardem syslog do programowania jądra.

Kolejność poziomów kłód, od najmniejszego do największego, pokazano na trzech poniższych rysunkach:

ERROR Dzienniki te są zawsze przechowywane.
WARN Dzienniki te są zawsze przechowywane.
INFO Dzienniki te są zawsze przechowywane.
DEBUG Te dzienniki są kompilowane, ale usuwane w czasie wykonywania.
VERBOSE Dzienniki te nigdy nie są kompilowane w aplikacji, chyba że podczas jej programowania.

Rysunek 3: android.util.Log

CONFIG Poziom komunikatów dla statycznych komunikatów konfiguracyjnych
FINE Poziom komunikatu dostarczający informacji o śledzeniu
FINER Wskazuje dość szczegółowy komunikat śledzenia
FINEST Wskazuje bardzo szczegółowy komunikat śledzenia
INFO Poziom wiadomości dla wiadomości informacyjnych
SEVERE Poziom komunikatu wskazujący poważną awarię
WARNING Poziom komunikatu wskazujący potencjalny problem

Rysunek 4: java.util.Logging.Level .

0 Nagły wypadek System jest bezużyteczny
1 Alarm Należy natychmiast podjąć działania
2 Krytyczny Warunki krytyczne
3 Błąd Warunki błędu
4 Ostrzeżenie Warunki ostrzegawcze
5 Ogłoszenie Normalny, ale znaczący stan
6 Informacyjne Komunikaty informacyjne
7 Odpluskwić Komunikaty na poziomie debugowania

Rysunek 5: RFC 5424 – sekcja 6.2.1 .

Rejestrowanie aplikacji

Rejestrowanie selektywne 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.");
}

Dzienniki można dostrajać w czasie wykonywania, 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ą trwałe warianty, które pozostają również po ponownym uruchomieniu. Zobacz poniżej:

adb shell setprop persist.log.tag.FOO_TAG VERBOSE

Kontrole Log#isLoggable pozostawiają ślady dziennika w kodzie aplikacji. Wartość logiczna DEBUG oznacza pominięcie śladów dziennika przy użyciu 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ąć dla poszczególnych plików APK za pośrednictwem zestawów reguł ProGuard w R8 w czasie kompilacji. Poniższy przykład usuwa wszystko poniżej poziomu rejestrowania 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 (na przykład kompilacji programistycznych i wersji wydawczych), gdzie oczekuje się, że kod źródłowy będzie taki sam, ale dozwolone poziomy dziennika będą różne. Aby aplikacje (zwłaszcza aplikacje systemowe) mogły decydować, w jaki sposób typy kompilacji i oczekiwania dotyczące wersji wpływają na dane wyjściowe dziennika, należy ustawić jawną politykę, której należy przestrzegać.

Rejestrowanie systemu w środowisku wykonawczym Androida (ART)

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

Klasa Zamiar
android.telephony.Rlog Logowanie radiowe
android.util.Log Ogólne rejestrowanie aplikacji
android.util.EventLog Rejestrowanie zdarzeń diagnostycznych integratora systemu
android.util.Slog Rejestrowanie struktury platformy

Rysunek 6: Dostępne klasy i cele dzienników systemowych.

Chociaż android.util.Log i android.util.Slog korzystają z tych samych standardów poziomu logów, Slog jest klasą @hide , z której można korzystać tylko na platformie. Poziomy EventLog są mapowane na wpisy w pliku event.logtags w katalogu /system/etc/event-log-tags .

Rejestrowanie natywne

Logowanie w C/C++ odbywa się zgodnie ze standardem syslog z syslog (2) odpowiadającym syslog jądra Linuksa, który kontroluje bufor printk , i syslog (3) odpowiadającym ogólnemu rejestratorowi systemowemu. Android używa biblioteki liblog do ogólnego rejestrowania systemu.

liblog zapewnia opakowania dla grup podlogów przy użyciu następującej formy makra:

[Sublog Buffer ID] LOG [Log Level ID]

RLOGD odpowiada na przykład [Radio log buffer ID] LOG [Debug Level] . Główne opakowania liblog są następujące:

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

Rysunek 7: opakowania bibliotek liblog .

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

Biblioteka Stosowanie
async_safe Biblioteka przeznaczona wyłącznie do rejestrowania w środowiskach bezpiecznych dla sygnału asynchronicznego
libbase Biblioteka rejestrowania zapewniająca interfejs strumienia C++ do rejestrowania, podobny do rejestrowania w stylu Google (glog). libbase można używać w obu projektach zewnętrznych i jest ona dostępna w aplikacjach korzystających z libbase_ndk .

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

Aproksymacje wielopoziomowe

Ze względu na różnice w szczegółowości i zamierzeniu poziomu nie ma jasnego ani dokładnego dopasowania różnych standardów rejestrowania. Na przykład poziomy java.util.logging.Level i android.util.Log dla dzienników błędów nie są zgodne w stosunku 1:1:

java.util.Logging.Level android.util.Log
CIĘŻKI : SILNY Log.wtf
CIĘŻKI : SILNY Log.e

Rysunek 9: Poziom błędu w standardowym rejestrowaniu w języku Java w porównaniu z rejestrowaniem w systemie Android.

W takich przypadkach należy skorzystać z indywidualnego standardu, aby określić, który poziom zastosować.

Podczas opracowywania systemu z wieloma komponentami na poziomie stosu postępuj zgodnie z rysunkiem 1, aby określić, który standard zastosować dla każdego komponentu. Aby zapoznać się z przybliżonym przewodnikiem po komunikatach na poziomie, postępuj zgodnie z rysunkiem 2.

Bezpieczeństwo i prywatność

Nie rejestruj informacji umożliwiających identyfikację użytkownika (PII). Obejmuje to takie szczegóły, jak:

  • Adresy e-mail
  • Numer telefonu
  • Nazwy

Podobnie niektóre dane są uważane za wrażliwe, nawet jeśli nie pozwalają na identyfikację osoby.

Na przykład, mimo że informacje o strefie czasowej nie są uznawane za dane osobowe, wskazują przybliżoną lokalizację użytkownika.

Zasady dotyczące dzienników i akceptowalne szczegóły muszą zostać uwzględnione w ramach przeglądu bezpieczeństwa i prywatności przed publikacją.

Dzienniki urządzenia

Dostęp do wszystkich logów urządzenia, w tym za pomocą android.permission.READ_LOGS , jest ograniczony:

  • Jeśli aplikacja działająca w tle zażąda dostępu do wszystkich dzienników urządzenia, żądanie zostanie automatycznie odrzucone, chyba że aplikacja:
    • udostępnia systemowy identyfikator UID.
    • wykorzystuje natywny proces systemowy ( UID < APP_UID ).
    • używa DropBoxManager .
    • uzyskuje dostęp tylko do bufora dziennika zdarzeń.
    • korzysta z interfejsu API EventLog .
    • wykorzystuje testy instrumentalne.
  • Jeśli aplikacja na pierwszym planie z READ_LOGS zażąda dostępu do dzienników urządzenia, system poprosi użytkownika o zatwierdzenie lub odrzucenie żądania dostępu.