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