Questo articolo illustra la procedura di registrazione, inclusi standard dei log, linee guida per i livelli, classi, finalità e approssimazioni multistack.
Standard di log
Il logging in Android è complesso a causa della combinazione di standard utilizzati in logcat
. Di seguito sono descritti i principali standard utilizzati:
Source | Esempi | Indicazioni a livello di stack |
---|---|---|
RFC 5424 (syslog standard) |
Kernel Linux, molte app Unix | Kernel, demoni di sistema |
android.util.Log |
Framework Android + logging delle app | Framework e app di sistema Android |
java.util.logging.Level |
Log generali in Java | app non di sistema |
Figura 1: standard dei livelli di log.
Sebbene ciascuno di questi standard abbia una struttura di livello simile, la granularità varia. Gli equivalenti approssimativi tra gli standard sono i seguenti:
Livello RFC 5424 | Gravità RFC 5424 | Descrizione di RFC 5424 | android.util.Log | java.util.logging.Level |
---|---|---|---|---|
0 | Emergenza | Il sistema non è utilizzabile | Log.e / Log.wtf |
SEVERE |
1 | Avviso | È necessario intervenire immediatamente | Log.e / Log.wtf |
SEVERE |
2 | Critico | Condizioni critiche | Log.e / Log.wtf |
SEVERE |
3 | Errore | Condizioni di errore | Log.e |
SEVERE |
4 | Avviso | Condizioni di avviso | Log.w |
WARNING |
5 | Avviso | Normale, ma significativo | Log.w |
WARNING |
6 | Informazioni | Messaggistica informativa | Log.i |
INFO |
7 | Debug | Messaggi a livello di debug | Log.d |
CONFIG , FINE |
- | - | Messaggistica dettagliata | Log.v |
FINER /FINEST |
Figura 2: livelli di logging di syslog
, Android e Java.
Linee guida per i livelli di log
Esistono linee guida per ogni standard di log. Il livello di log scelto segue lo standard appropriato in uso, ad esempio lo standard syslog
per lo sviluppo del kernel.
Gli ordini dei livelli di log, dal più basso al più alto, sono mostrati nelle tre figure seguenti:
ERROR |
Questi log vengono sempre conservati. |
WARN |
Questi log vengono sempre conservati. |
INFO |
Questi log vengono sempre conservati. |
DEBUG |
Questi log vengono compilati, ma rimossi in fase di esecuzione. |
VERBOSE |
Questi log non vengono mai compilati in un'app, tranne durante lo sviluppo. |
Figura 3: android.util.Log
CONFIG |
Livello di messaggio per i messaggi di configurazione statica |
FINE |
A livello di messaggio fornisce informazioni di tracciamento |
FINER |
Indica un messaggio di tracciamento abbastanza dettagliato |
FINEST |
Indica un messaggio di monitoraggio molto dettagliato |
INFO |
Livello di messaggio per i messaggi informativi |
SEVERE |
Livello del messaggio che indica un errore grave |
WARNING |
Livello del messaggio che indica un potenziale problema |
Figura 4: java.util.Logging.Level
.
0 | Emergenza | Il sistema non è utilizzabile |
1 | Avviso | È necessario intervenire immediatamente |
2 | Critico | Condizioni critiche |
3 | Errore | Condizioni di errore |
4 | Avviso | Condizioni di avviso |
5 | Avviso | Condizione normale, ma significativa |
6 | Informative | Messaggi informativi |
7 | Debug | Messaggi a livello di debug |
Figura 5: RFC 5424
- Sezione
6.2.1.
Logging delle app
Il logging selettivo viene eseguito con la classe TAG
per 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 log possono essere ottimizzati in fase di runtime per fornire un livello selezionato di logging, come mostrato di seguito:
adb shell setprop log.tag.FOO_TAG VERBOSE |
---|
Le proprietà log.tag.*
vengono reimpostate al riavvio. Esistono anche varianti permanenti che rimangono anche dopo i riavvii. Vedi di seguito:
adb shell setprop persist.log.tag.FOO_TAG VERBOSE |
---|
I controlli di Log#isLoggable
lasciano tracce di log nel codice dell'app. I flag booleani
DEBUG
ignorano le tracce dei log utilizzando le ottimizzazioni del compilatore impostate su
false
, come mostrato di seguito:
private final static boolean DEBUG = false; |
---|
La registrazione può essere rimossa su base APK tramite i set di regole di ProGuard da R8
al compilatore. L'esempio seguente rimuove tutto ciò che si trova al di sotto del livello INFO
del logging 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 |
---|
Questo è utile per gestire più tipi di build dell'app (ad esempio build di sviluppo e build di release) in cui il codice sottostante dovrebbe essere lo stesso, ma i livelli di log consentiti sono diversi. Per le app (in particolare quelle di sistema) deve essere impostato e rispettato un criterio esplicito per decidere in che modo i tipi di build e le aspettative di rilascio influiscono sull'output del log.
Registrazione di sistema in Android Runtime (ART)
Esistono diversi tipi di classi disponibili per le app e i servizi di sistema:
Corso | Finalità |
---|---|
android.telephony.Rlog |
Registrazione radio |
android.util.Log |
Logging generale dell'app |
android.util.EventLog |
Registrazione degli eventi diagnostici dell'integratore di sistema |
android.util.Slog |
Logging del framework della piattaforma |
Figura 6: classi e finalità dei log di sistema disponibili.
Sebbene android.util.Log
e android.util.Slog
utilizzino gli stessi standard di livello di log, Slog
è una classe @hide
utilizzabile solo dalla piattaforma. I livelli EventLog
vengono mappati alle voci del file event.logtags
in /system/etc/event-log-tags
.
Logging nativo
La registrazione in C/C++ segue lo standard syslog
, con syslog
(2) corrispondente al kernel Linux syslog
che controlla il buffer printk
e syslog
(3) corrispondente al logger di sistema generale. Android utilizza la libreria liblog
per il logging di sistema generale.
liblog
fornisce wrapper per i gruppi di blog secondari utilizzando il seguente formato della macro:
[Sublog Buffer ID] LOG [Log Level ID] |
RLOGD
, ad esempio, corrisponde a [Radio log buffer ID] LOG [Debug Level]
.
I principali wrapper liblog
sono i seguenti:
Classe wrapper | Funzioni di esempio |
---|---|
log_main.h |
ALOGV , ALOGW |
log_radio.h |
RLOGD , RLOGE |
log_system.h |
SLOGI , SLOGW |
Figura 7: wrapper liblog
.
Android dispone di interfacce di livello superiore per la registrazione che sono preferite all'uso direttoliblog
, come mostrato di seguito:
Raccolta | Utilizzo |
---|---|
async_safe |
Libreria solo per la registrazione da ambienti sicuri per gli indicatori asincroni |
libbase |
Libreria di logging che fornisce un'interfaccia di streaming C++ per la registrazione, simile alla registrazione in stile Google (glog). libbase è utilizzabile sia nei progetti esterni sia nelle app che utilizzano libbase_ndk . |
Figura 8: librerie di log di livello superiore.
Approssimazioni multistack
A causa delle differenze di granularità e intent di livello, non esistono corrispondenze chiare o precise tra i diversi standard di logging. Ad esempio, i livelli java.util.logging.Level
e android.util.Log
per i log di errore non corrispondono 1:1:
java.util.Logging.Level | android.util.Log |
---|---|
GRAVE | Log.wtf |
GRAVE | Log.e |
Figura 9: livello di errore nella registrazione Java standard rispetto alla registrazione Android.
In questi casi, utilizza il singolo standard per determinare quale livello applicare.
Durante lo sviluppo del sistema con più componenti a livello di stack, segui la Figura 1 per determinare quale standard utilizzare per componente. Per una guida approssimativa ai messaggi di livello, segui la Figura 2.
Sicurezza e privacy
Non registrare informazioni che consentono l'identificazione personale (PII). Sono inclusi dettagli quali:
- Indirizzi email
- Numeri di telefono
- Nomi.
Analogamente, alcuni dettagli sono considerati sensibili anche se non consentono esplicitamente l'identificazione personale.
Ad esempio, anche se le informazioni sul fuso orario non sono considerate informazioni che consentono l'identificazione personale, forniscono un'indicazione della posizione approssimativa di un utente.
Le norme relative ai log e i dettagli accettabili devono essere gestiti nell'ambito della revisione della sicurezza e della privacy prima del rilascio.
Log 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
). - Usa
DropBoxManager
. - Accede solo al buffer del log eventi.
- Utilizza l'API
EventLog
. - Utilizza i test con strumenti.
- Se un'app in primo piano con
READ_LOGS
richiede l'accesso ai log del dispositivo, il sistema chiede all'utente di approvare o rifiutare la richiesta di accesso.