Comprende el registro

En este artículo, se describe el proceso de registro, incluidos los estándares de registro, los lineamientos de nivel, las clases, los propósitos y las aproximaciones de varias pilas.

Estándares de registro

El proceso de registro en Android es complejo debido a la combinación de estándares que se combinan en logcat. A continuación, se detallan los principales estándares que se utilizan:

Source Ejemplos Orientación a nivel de la pila
RFC 5424 (estándar syslog) Kernel de Linux y muchas apps de Unix Kernel y daemons del sistema
android.util.Log Framework de Android y registro de apps Framework de Android y app del sistema
java.util.logging.Level Registro general en Java app que no es del sistema

Figura 1: Estándares de nivel de registro

Aunque cada uno de estos estándares tiene una construcción de nivel similar, varían en su nivel de detalle. Los equivalentes aproximados entre los estándares son los siguientes:

Nivel de RFC 5424 Gravedad de RFC 5424 Descripción de la RFC 5424 android.util.Log java.util.logging.Level
0 Emergencia El sistema no se puede usar Log.e / Log.wtf SEVERE
1 Alerta Se deben tomar medidas de inmediato Log.e / Log.wtf SEVERE
2 Crítico Condiciones críticas Log.e / Log.wtf SEVERE
3 Error Condiciones de error Log.e SEVERE
4 Advertencia Condiciones de advertencia Log.w WARNING
5 Aviso Normal, pero significativo Log.w WARNING
6 Información Mensajes de información Log.i INFO
7 Depuración Mensajes a nivel de depuración Log.d CONFIG, FINE
- - Mensajes detallados Log.v FINER/FINEST

Figura 2: Niveles de registro de syslog, Android y Java.

Lineamientos de nivel de registro

Existen lineamientos existentes para cada estándar de registro. El nivel de registro elegido sigue el estándar adecuado que se usa, como el estándar syslog para el desarrollo del kernel.

Los pedidos de nivel de registro, de menor a mayor, se muestran en las siguientes tres imágenes:

ERROR Estos registros siempre se conservan.
WARN Estos registros siempre se conservan.
INFO Estos registros siempre se conservan.
DEBUG Estos registros se compilan, pero se quitan durante el tiempo de ejecución.
VERBOSE Estos registros nunca se compilan en una app, excepto durante el desarrollo.

Figura 3: android.util.Log

CONFIG Nivel de mensaje para los mensajes de configuración estática
FINE Nivel de mensaje que proporciona información de seguimiento
FINER Indica un mensaje de seguimiento bastante detallado.
FINEST Indica un mensaje de seguimiento muy detallado.
INFO Nivel de mensaje para los mensajes informativos
SEVERE Nivel de mensaje que indica una falla grave
WARNING Nivel de mensaje que indica un posible problema

Figura 4: java.util.Logging.Level.

0 Emergencia El sistema no se puede usar
1 Alerta Se deben tomar medidas de inmediato
2 Crítico Condiciones críticas
3 Error Condiciones de error
4 Advertencia Condiciones de advertencia
5 Aviso Condición normal, pero significativa
6 Informativo Mensajes informativos
7 Depuración Mensajes a nivel de depuración

Figura 5: RFC 5424 - Sección 6.2.1.

Registro de apps

El registro selectivo se realiza con TAG por la clase android.util.Log con Log#isLoggable, como se muestra a continuación:

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

Los registros se pueden ajustar durante el tiempo de ejecución para proporcionar un nivel de registro seleccionado, como se muestra a continuación:

adb shell setprop log.tag.FOO_TAG VERBOSE

Las propiedades log.tag.* se restablecen durante el reinicio. También hay variantes persistentes que permanecen en los reinicios. Consulta a continuación:

adb shell setprop persist.log.tag.FOO_TAG VERBOSE

Las verificaciones de Log#isLoggable dejan registros en el código de la app. Las marcas DEBUG booleanas omiten los registros de seguimiento mediante optimizaciones del compilador que se establecen en false, como se muestra a continuación:

private final static boolean DEBUG = false;

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

R8 puede quitar el registro por APK a través de los conjuntos de reglas de ProGuard en el momento de la compilación. En el siguiente ejemplo, se quita todo debajo del registro de nivel INFO para 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

Esto es útil para controlar varios tipos de compilación de apps (por ejemplo, compilaciones de desarrollo en comparación con compilaciones de lanzamiento) en los que se espera que el código subyacente sea el mismo, pero los niveles de registro permitidos son diferentes. Se debe establecer y seguir una política explícita para las apps (en particular, las apps del sistema) para decidir cómo los tipos de compilación y las expectativas de lanzamiento afectan el resultado del registro.

Registro del sistema en Android Runtime (ART)

Existen varias clases disponibles para las apps y los servicios del sistema:

Clase Propósito
android.telephony.Rlog Registro de radio
android.util.Log Registro general de la app
android.util.EventLog Registro de eventos de diagnóstico del integrador del sistema
android.util.Slog Registro del framework de la plataforma

Figura 6: Clases y propósitos de registro del sistema disponibles.

Aunque android.util.Log y android.util.Slog usan los mismos estándares de nivel de registro, Slog es una clase @hide que solo puede usar la plataforma. Los niveles de EventLog se asignan a las entradas del archivo event.logtags en /system/etc/event-log-tags.

Registro nativo

El registro en C/C++ sigue el estándar syslog, con syslog(2) que corresponde al syslog del kernel de Linux que controla el búfer printk y syslog(3) que corresponde al registrador general del sistema. Android usa la biblioteca liblog para el registro general del sistema.

liblog proporciona wrappers para los grupos de subblogs con el siguiente formato de macro:

[Sublog Buffer ID] LOG [Log Level ID]

Por ejemplo, RLOGD corresponde a [Radio log buffer ID] LOG [Debug Level]. Los principales wrappers de liblog son los siguientes:

Clase de wrapper Funciones de ejemplo
log_main.h ALOGV, ALOGW
log_radio.h RLOGD, RLOGE
log_system.h SLOGI, SLOGW

Figura 7: Wrappers de liblog

Android tiene interfaces de nivel superior para el registro que se prefieren antes que el uso directo de liblog, como se ve a continuación:

Biblioteca Uso
async_safe Biblioteca solo para el registro desde entornos seguros para indicadores asíncronos
libbase Biblioteca de registro que proporciona una interfaz de transmisión C++ al registro, similar al registro al estilo de Google (glog). libbase se puede usar en proyectos externos y está disponible en apps que usan libbase_ndk.

Figura 8: Bibliotecas de registro de nivel superior.

Aproximaciones de varias pilas

Debido a las diferencias en el nivel de detalle y el nivel de intención, no hay coincidencias claras ni exactas de los diferentes estándares de registro. Por ejemplo, los niveles java.util.logging.Level y android.util.Log de los registros de errores no son una coincidencia de 1:1:

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

Figura 9: Nivel de error en el registro estándar de Java en comparación con el registro de Android.

En casos como este, usa el estándar individual para determinar qué nivel aplicar.

Durante el desarrollo del sistema con varios componentes a nivel de la pila, sigue la Figura 1 para determinar qué estándar usar por componente. Para obtener una guía aproximada de los mensajes por nivel, sigue la Figura 2.

Seguridad y privacidad

No registres información de identificación personal (PII). Esto incluye detalles como los siguientes:

  • Direcciones de correo electrónico
  • números de teléfono
  • Nombres

Del mismo modo, ciertos detalles se consideran sensibles, incluso si no son de identificación personal explícita.

Por ejemplo, aunque la información de zona horaria no se considera información de identificación personal, sí proporciona una indicación de la ubicación aproximada de un usuario.

La política de registro y los detalles aceptables deben tratarse como parte de la revisión de seguridad y privacidad antes del lanzamiento.

Registros del dispositivo

Se restringe el acceso a todos los registros del dispositivo, incluido el uso de android.permission.READ_LOGS:

  • Si una app en segundo plano solicita acceso a todos los registros del dispositivo, la solicitud se rechaza automáticamente, a menos que la app cumpla con los siguientes requisitos:
    • Comparte el UID del sistema.
    • Usa un proceso del sistema nativo (UID < APP_UID).
    • Usa DropBoxManager
    • Solo accede al búfer de registro de eventos.
    • Usa la API de EventLog.
    • Usa pruebas instrumentadas.
  • Si una app en primer plano con READ_LOGS solicita acceso a los registros del dispositivo, el sistema le solicita al usuario que apruebe o rechace la solicitud de acceso.