Comprensione della registrazione

Questo articolo illustra il processo di registrazione, inclusi gli standard di registrazione, le linee guida sui livelli, le classi, gli scopi e le approssimazioni multistack.

Standard di registro

L'accesso ad Android è complesso a causa del mix di standard utilizzati che sono combinati in logcat . I principali standard utilizzati sono dettagliati di seguito:

Fonte Esempi Guida a livello di pila
RFC 5424 (standard syslog ) Kernel Linux, molte applicazioni Unix Kernel, demoni di sistema
android.util.Log Framework Android + registrazione dell'applicazione Framework Android e applicazione di sistema
java.util.logging.Level Registrazione generale in Java applicazione non di sistema

Figura 1: standard a livello di log.

Sebbene ciascuno di questi standard abbia una struttura di livello simile, varia in granularità. Gli equivalenti approssimativi tra gli standard sono i seguenti:

Livello RFC 5424 Gravità RFC 5424 RFC 5424 Descrizione android.util.Log java.util.logging.Level
0 Emergenza Il sistema è inutilizzabile Log.e / Log.wtf SEVERE
1 Mettere in guardia L'azione deve essere intrapresa immediatamente Log.e / Log.wtf SEVERE
2 Critico Condizioni critiche Log.e / Log.wtf SEVERE
3 Errore Condizioni di errore Log.e SEVERE
4 Avvertimento Condizioni di avviso Log.w WARNING
5 Avviso Normale ma significativo Log.w WARNING
6 Informazioni Messaggi informativi Log.i INFO
7 Debug Messaggi a livello di debug Log.d CONFIG , FINE
- - Messaggistica dettagliata Log.v FINER FINE / FINEST

Figura 2: livelli di registrazione syslog , Android e Java.

Linee guida a livello di registro

Esistono linee guida esistenti fornite per ogni standard di registro. Il livello di registro scelto segue lo standard appropriato utilizzato, come l'utilizzo dello standard syslog per lo sviluppo del kernel.

Gli ordini a livello di registro, dal meno al più, sono mostrati nelle tre figure seguenti:

ERROR Questi registri vengono sempre conservati.
WARN Questi registri vengono sempre conservati.
INFO Questi registri vengono sempre conservati.
DEBUG Questi log vengono compilati ma rimossi in fase di esecuzione.
VERBOSE Questi registri non vengono mai compilati in un'applicazione tranne che durante lo sviluppo.

Figura 3: android.util.Log

CONFIG Livello di messaggio per i messaggi di configurazione statici
FINE Livello di messaggio che fornisce informazioni di tracciamento
FINER Indica un messaggio di traccia abbastanza dettagliato
FINEST Indica un messaggio di traccia molto dettagliato
INFO Livello messaggio per messaggi informativi
SEVERE Livello di messaggio che indica un errore grave
WARNING Livello di messaggio che indica un potenziale problema

Figura 4: java.util.Logging.Level .

0 Emergenza Il sistema è inutilizzabile
1 Mettere in guardia L'azione deve essere intrapresa immediatamente
2 Critico Condizioni critiche
3 Errore Condizioni di errore
4 Avvertimento Condizioni di avviso
5 Avviso Condizioni normali ma significative
6 Informativo Messaggi informativi
7 Debug Messaggi a livello di debug

Figura 5: RFC 5424 - Sezione 6.2.1 .

Registrazione dell'applicazione

La registrazione selettiva viene eseguita con TAG dalla classe android.util.Log utilizzando Log#isLoggable , come mostrato di seguito:

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

I registri possono essere ottimizzati in fase di esecuzione per fornire un livello selezionato di registrazione come mostrato di seguito:

adb shell setprop log.tag.FOO_TAG VERBOSE

le proprietà log.tag.* vengono reimpostate al riavvio. Esistono varianti persistenti che rimangono anche dopo i riavvii. Vedi sotto:

adb shell setprop persist.log.tag.FOO_TAG VERBOSE

I controlli Log#isLoggable lasciano tracce di registro nel codice dell'applicazione. I flag booleani DEBUG ignorano le tracce di log utilizzando le ottimizzazioni del compilatore impostate su false , come mostrato di seguito:

private final static boolean DEBUG = false;

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

La registrazione può essere rimossa in base all'APK tramite i set di regole ProGuard di R8 in fase di compilazione. L'esempio seguente rimuove tutto ciò che è al di sotto della registrazione di livello INFO per 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

Ciò è utile per gestire più tipi di build dell'applicazione (ad esempio, build di sviluppo e build di rilascio) in cui il codice sottostante dovrebbe essere lo stesso, ma i livelli di log consentiti sono diversi. È necessario impostare e seguire un criterio esplicito per le applicazioni (in particolare le applicazioni di sistema) per decidere in che modo i tipi di compilazione e le aspettative di rilascio influiscono sull'output del registro.

Registrazione del sistema in Android Runtime (ART)

Esistono diverse classi disponibili per le applicazioni e i servizi di sistema:

Classe Scopo
android.telephony.Rlog Registrazione radiofonica
android.util.Log Registrazione generale dell'applicazione
android.util.EventLog Registrazione degli eventi diagnostici dell'integratore di sistema
android.util.Slog Registrazione del framework della piattaforma

Figura 6: Classi e scopi del registro di sistema disponibili.

Sebbene android.util.Log e android.util.Slog utilizzino gli stessi standard a livello di registro, Slog è una classe @hide utilizzabile solo dalla piattaforma. I livelli EventLog sono mappati alle voci nel file event.logtags in /system/etc/event-log-tags .

Registrazione nativa

L'accesso in C/C++ segue lo standard syslog con syslog (2) corrispondente al syslog del kernel Linux che controlla il buffer printk e syslog (3) corrispondente al logger di sistema generale. Android utilizza la libreria liblog per la registrazione generale del sistema.

liblog fornisce wrapper per i gruppi di subblog utilizzando il seguente modulo macro:

[Sublog Buffer ID] LOG [Log Level ID]

RLOGD , ad esempio, corrisponde a [Radio log buffer ID] LOG [Debug Level] . I principali wrapper di liblog sono i seguenti:

Classe wrapper Esempi di funzioni
log_main.h ALOGV , ALOGW
log_radio.h RLOGD , RLOGE
log_system.h SLOGI , SLOGW

Figura 7: wrapper liblog .

Android ha interfacce di livello superiore per la registrazione che sono preferite rispetto all'utilizzo diretto di liblog , come mostrato di seguito:

Biblioteca Utilizzo
async_safe Libreria solo per la registrazione da ambienti sicuri per il segnale asincrono
libbase Libreria di registrazione che fornisce un'interfaccia di flusso C++ per la registrazione, simile alla registrazione in stile Google (glog). libbase è utilizzabile in entrambi i progetti esterni ed è disponibile nelle applicazioni che utilizzano libbase_ndk .

Figura 8: librerie di log di livello superiore.

Approssimazioni multistack

A causa delle differenze di granularità e livello di intenti, non esistono corrispondenze chiare o esatte di diversi standard di registrazione. Ad esempio, i livelli java.util.logging.Level e android.util.Log per i log degli errori non corrispondono 1:1:

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

Figura 9: livello di errore nella registrazione Java standard rispetto alla registrazione Android.

In casi come questo, utilizzare lo standard individuale per determinare quale livello applicare.

Durante lo sviluppo del sistema con più componenti a livello di stack, seguire la Figura 1 per determinare quale standard utilizzare per componente. Per una guida approssimativa alla messaggistica di livello, seguire la Figura 2.

Sicurezza e privacy

Non registrare informazioni di identificazione personale (PII). Ciò include dettagli come:

  • Indirizzi email
  • Numeri di telefono
  • Nomi

Allo stesso modo, alcuni dati sono considerati sensibili anche se non esplicitamente identificabili personalmente.

Ad esempio, sebbene le informazioni sul fuso orario non siano considerate identificabili personalmente, forniscono un'indicazione della posizione approssimativa di un utente.

La politica di registro e i dettagli accettabili devono essere gestiti come parte della revisione della sicurezza e della privacy prima del rilascio.

Registri del dispositivo

L'accesso a tutti i log del dispositivo, incluso l'utilizzo di android.permission.READ_LOGS , è limitato:

  • Se un'app in background richiede l'accesso a tutti i log del dispositivo, la richiesta viene automaticamente rifiutata a meno che l'app:
    • condivide l'UID di sistema.
    • utilizza un processo di sistema nativo ( UID < APP_UID ).
    • utilizza DropBoxManager .
    • accede solo al buffer del registro eventi.
    • utilizza l'API EventLog .
    • utilizza test strumentali.
  • Se un'app in primo piano con READ_LOGS richiede l'accesso ai log del dispositivo, il sistema richiede all'utente di approvare o rifiutare la richiesta di accesso.