Informacje o logowaniu

W tym artykule omawiamy proces rejestrowania danych, w tym standardy logowania, wytyczne dotyczące poziomu, klasy, celów i przybliżeń wielowarstwowych.

Standardy logowania

Logowanie na Androidzie jest skomplikowane ze względu na różne standardy używane w komponencie logcat. Oto główne standardy, których używamy:

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

Rysunek 1. Standardy poziomu rejestrowania.

Chociaż wszystkie te standardy mają podobną strukturę poziomów, różnią się poziomem szczegółowości. Przybliżone odpowiedniki w różnych standardach:

Poziom RFC 5424 Poziom ważności RFC 5424 Opis RFC 5424 android.util.Log java.util.logging.Level
0 Alarmowe System jest nieużyteczny Log.e / Log.wtf SEVERE
1 Alert Natychmiastowe podjęcie działań 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 ostrzegania Log.w WARNING
5 Uwaga Normalne, ale istotne Log.w WARNING
6 Informacje Komunikaty informacyjne Log.i INFO
7 Debuguj Komunikaty na poziomie debugowania Log.d CONFIG, FINE
- - Szczegółowe informacje Log.v FINER/FINEST

Ilustracja 2. Poziomy rejestrowania syslog, Androida i Java.

Wskazówki dotyczące poziomu logowania

W przypadku każdego standardu logowania istnieją już wytyczne. Wybrany poziom logowania jest zgodny z odpowiednim używanym standardem, np. syslog w przypadku tworzenia jądra.

Poziomy logowania, od najmniejszego do największego, są pokazane na 3 rysunkach 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 pozbawione treści w czasie wykonywania.
VERBOSE Te logi nigdy nie są kompilowane do aplikacji, z wyjątkiem okresu rozwoju.

Rysunek 3: android.util.Log

CONFIG Poziom wiadomości dla statycznych komunikatów konfiguracyjnych
FINE Poziom wiadomości z informacjami dotyczącymi śledzenia
FINER Wskazuje dość szczegółowy komunikat dotyczący śledzenia
FINEST Wskazuje bardzo szczegółowy komunikat dotyczący śledzenia
INFO Poziom wiadomości w przypadku wiadomości informacyjnych
SEVERE Poziom komunikatu wskazujący poważną awarię
WARNING Poziom komunikatu wskazujący na potencjalny problem

Rysunek 4: java.util.Logging.Level.

0 Alarmowe System jest nieużyteczny
1 Alert Natychmiastowe podjęcie działań
2 Krytyczny Krytyczne warunki
3 Błąd Warunki błędu
4 Ostrzeżenie Warunki ostrzegania
5 Uwaga Normalny, ale istotny stan
6 Informacyjne Komunikaty informacyjne
7 Debuguj Komunikaty na poziomie debugowania

Rysunek 5. RFC 5424 – sekcja 6.2.1.

Logowanie aplikacji

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

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

W czasie działania możesz dostosować logi, aby uzyskać 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ą po ponownym uruchomieniu. Poniżej znajdziesz więcej informacji:

adb shell setprop persist.log.tag.FOO_TAG VERBOSE

Log#isLoggable sprawdza, czy w kodzie aplikacji są ślady logowania. Flagi logiczne DEBUG pomijają ścieżki logowania, korzystając z optymalizacji kompilatora ustawionych na false, jak pokazano poniżej:

private final static boolean DEBUG = false;

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

W regułach ProGuard można usunąć rejestrowanie na poziomie pliku APK za pomocą R8 w czasie kompilacji. W tym przykładzie usuwamy wszystko poniżej poziomu INFO w przypadku logowania 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 w celu testowania i kompilacji wersji), w których kod źródłowy jest taki sam, ale dozwolone poziomy logowania są różne. W przypadku aplikacji (zwłaszcza systemowych) musisz ustawić i stosować wyraźną zasadę, która określa, jak typy kompilacji i oczekiwania dotyczące wersji wpływają na dane w wyjściowym pliku dziennika.

Logowanie systemowe w Android Runtime (ART)

Dostępnych jest kilka klas dostępnych dla aplikacji i usług systemowych:

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

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

Chociaż android.util.Logandroid.util.Slog używają tych samych standardów poziomu logowania, Slog należy do klasy @hide i może być używana tylko przez platformę. Poziomy EventLog są mapowane na wpisy w pliku event.logtags w katalogu /system/etc/event-log-tags.

Logowanie natywne

Logowanie w C/C++ jest zgodne ze standardem syslog, w którym syslog(2) odpowiada jądrowi Linuksa syslog, które kontroluje bufor printk, a syslog(3) odpowiada ogólnemu rejestratorowi systemu. Android używa biblioteki liblog do ogólnego rejestrowania działań systemu.

liblog udostępnia obudowy dla grup subblogów za pomocą tego formatu makr:

[Sublog Buffer ID] LOG [Log Level ID]

Na przykład RLOGD odpowiada [Radio log buffer ID] LOG [Debug Level]. Najważniejsze obudowy liblog:

Klasa kodu towarzyszącego Przykładowe funkcje
log_main.h ALOGV, ALOGW
log_radio.h RLOGD, RLOGE
log_system.h SLOGI, SLOGW

Rysunek 7. Opakowania liblog.

Android ma interfejsy logowania na wyższym poziomie, które są preferowane w stosunku do bezpośredniego korzystania z liblog, jak widać poniżej:

Biblioteka Wykorzystanie
async_safe Biblioteka tylko do rejestrowania danych z bezpiecznych środowisk asynchronicznych
libbase Biblioteka do rejestrowania, która udostępnia interfejs strumieniowania w C++, podobny do rejestrowania w stylu Google (glog). libbase można używać w projektach zewnętrznych, a także w aplikacjach korzystających z libbase_ndk.

Rysunek 8.: biblioteki dziennika wyższego poziomu.

Aproksymacje wielowarstwowe

Ze względu na różnice w szczególności i intencjach na różnych poziomach nie ma dokładnego dopasowania różnych standardów rejestrowania. Na przykład poziomy java.util.logging.Level i android.util.Log w logach błędów nie są zgodne w stosunku 1:1:

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

Rysunek 9: poziom błędu w standardowym logowaniu w Javie i w Androidzie.

W takich przypadkach należy użyć standardu indywidualnego, 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ć dla poszczególnych komponentów. Aby uzyskać przybliżony przewodnik po poziomach wiadomości, zapoznaj się z Rysunkiem 2.

Prywatność i bezpieczeństwo

Nie rejestruj informacji umożliwiających identyfikację osoby. Dotyczy to takich informacji 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ą jednoznacznej identyfikacji osoby.

Na przykład informacje o strefach czasowych nie są uważane za informacje umożliwiające identyfikację, ale wskazują przybliżoną lokalizację użytkownika.

Zasady dotyczące logowania i dopuszczalne szczegóły muszą być rozpatrywane w ramach kontroli bezpieczeństwa i prywatności przed wydaniem.

dziennikami urządzenia.

Dostęp do wszystkich dzienników urządzenia, w tym do korzystania z aplikacji 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ń.
    • Używa interfejsu EventLog API.
    • Używa testów z instrumentacją.
  • Jeśli aplikacja na pierwszym planie z READ_LOGS poprosi o dostęp do dzienników urządzenia, system poprosi użytkownika o zatwierdzenie lub odrzucenie prośby o dostęp.