Questo articolo descrive il processo di logging, inclusi standard, linee guida per i livelli, classi, scopi e approssimazioni multistack.
Standard dei log
L'accesso in Android è complesso a causa del mix di standard utilizzati che vengono
combinati in logcat
. Di seguito sono descritti gli standard principali utilizzati:
Source | Esempi | Indicazioni sul livello dello stack |
---|---|---|
RFC 5424 (syslog standard) |
Kernel Linux, molte app Unix | Kernel, daemon di sistema |
android.util.Log |
Framework Android + logging app | Framework Android e app di sistema |
java.util.logging.Level |
Logging generale in Java | app non di sistema |
Figura 1: standard del livello di log.
Sebbene ciascuno di questi standard abbia una struttura di livello simile, variano in granularità. Gli equivalenti approssimativi tra gli standard sono i seguenti:
Livello RFC 5424 | Gravità RFC 5424 | Descrizione RFC 5424 | android.util.Log | java.util.logging.Level |
---|---|---|---|---|
0 | Emergenza | Il sistema è inutilizzabile | Log.e / Log.wtf |
SEVERE |
1 | Avviso | 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 | 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 meno al più importante, 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 vengono rimossi in fase di runtime. |
VERBOSE |
Questi log non vengono mai compilati in un'app, tranne durante lo sviluppo. |
Figura 3: android.util.Log
CONFIG |
Livello del messaggio per i messaggi di configurazione statica |
FINE |
Livello del messaggio che fornisce informazioni di tracciamento |
FINER |
Indica un messaggio di tracciamento abbastanza dettagliato |
FINEST |
Indica un messaggio di tracciamento molto dettagliato |
INFO |
Livello del 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 è inutilizzabile |
1 | Avviso | Azione deve essere intrapresa 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 app
Il logging selettivo viene eseguito 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 log possono essere ottimizzati in fase di runtime per fornire un livello di logging selezionato, come mostrato di seguito:
adb shell setprop log.tag.FOO_TAG VERBOSE |
---|
Le proprietà log.tag.*
vengono reimpostate al riavvio. Esistono anche
varianti persistenti che rimangono anche dopo i riavvii. Vedi di seguito:
adb shell setprop persist.log.tag.FOO_TAG VERBOSE |
---|
I controlli 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 in base al singolo APK tramite i set di regole ProGuard da R8
in fase di compilazione. L'esempio seguente rimuove tutti i log di livello inferiore a 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 di app (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. Per decidere in che modo i tipi di build e le aspettative di rilascio influiscono sull'output dei log, è necessario impostare e seguire una policy esplicita per le app (in particolare le app di sistema).
Registrazione di sistema in Android Runtime (ART)
Sono disponibili diverse classi per app e servizi di sistema:
Corso | Finalità |
---|---|
android.telephony.Rlog |
Registrazione della radio |
android.util.Log |
Logging generale delle app |
android.util.EventLog |
Registrazione eventi di diagnostica dell'integratore di sistemi |
android.util.Slog |
Logging del framework della piattaforma |
Figura 6: classi e scopi dei log di sistema disponibili.
Sebbene android.util.Log
e android.util.Slog
utilizzino gli stessi standard
per il livello di log, Slog
è una classe @hide
utilizzabile solo dalla piattaforma. I livelli EventLog
sono mappati alle voci del file event.logtags
in /system/etc/event-log-tags
.
Logging nativo
L'accesso in C/C++ segue lo standard syslog
con syslog
(2) corrispondente a
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 log secondari utilizzando la seguente macro
modulo:
[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 rispetto all'utilizzo diretto di liblog
, come mostrato di seguito:
Raccolta | Utilizzo |
---|---|
async_safe |
Libreria solo per la registrazione da ambienti asincroni sicuri per i segnali |
libbase |
Libreria di logging che fornisce un'interfaccia di flusso C++ per il logging, simile al logging in stile Google (glog). libbase è utilizzabile sia in progetti esterni
ed è disponibile nelle app che utilizzano libbase_ndk . |
Figura 8: librerie di log di livello superiore.
Approssimazioni multistack
A causa delle differenze di granularità e livello di intent, non esistono corrispondenze chiare o
esatte tra i diversi standard di logging. Ad esempio, i livelli
java.util.logging.Level
e android.util.Log
per i log degli errori non corrispondono
in modo univoco:
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 casi come questo, utilizza lo standard individuale per determinare il livello da
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 dei livelli, 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.
Allo stesso modo, alcuni dettagli sono considerati sensibili anche se non consentono esplicitamente l'identificazione personale.
Ad esempio, sebbene le informazioni sul fuso orario non siano considerate informazioni che consentono l'identificazione personale,
forniscono un'indicazione della posizione approssimativa di un utente.
Le norme sui 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 rifiutata automaticamente, 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 test strumentati.
- 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.