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; |
|---|
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.Log i android.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.Level i android.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_LOGSpoprosi o dostęp do dzienników urządzenia, system wyświetli prośbę o zgodę na dostęp lub odmowę dostępu.