Comprende el registro

En este artículo, se aborda el proceso de registro, incluidos los estándares, las pautas de nivel, las clases, los propósitos y las aproximaciones de múltiples pilas de registros.

Estándares de registro

El 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 sobre el 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 Registro del framework de Android y de la app 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

Si bien cada uno de estos estándares tiene una construcción de nivel similar, varían en granularidad. Las equivalencias aproximadas entre los estándares son las siguientes:

Nivel de RFC 5424 Gravedad según RFC 5424 Descripción de 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 debe tomar una medida 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 Mensajería informativa Log.i INFO
7 Depuración Mensajes de nivel de depuración Log.d CONFIG, FINE
- - Mensajería detallada Log.v FINER/FINEST

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

Lineamientos para los niveles de registro

Existen lineamientos 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 niveles de registro, ordenados de menor a mayor, se muestran en las tres figuras a continuación:

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 registro bastante detallado.
FINEST Indica un mensaje de registro muy detallado.
INFO Nivel de mensaje para los mensajes informativos
SEVERE Nivel de mensaje que indica una falla grave
WARNING Nivel del mensaje que indica un posible problema

Figura 4: java.util.Logging.Level.

0 Emergencia El sistema no se puede usar
1 Alerta Se debe tomar una medida 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 de 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 de log.tag.* se restablecen cuando se reinicia el dispositivo. También hay variantes persistentes que permanecen después de reiniciar el dispositivo. Consulta a continuación:

adb shell setprop persist.log.tag.FOO_TAG VERBOSE

Las verificaciones de Log#isLoggable dejan registros de seguimiento en el código de la app. Las marcas booleanas DEBUG omiten los registros de seguimiento con 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."); }

El registro se puede quitar por APK a través de conjuntos de reglas de ProGuard con R8 en el tiempo de compilación. En el siguiente ejemplo, se quita todo el registro por debajo del 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 frente a 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 que las apps (en especial, las apps del sistema) decidan cómo los tipos de compilación y las expectativas de lanzamiento afectan el resultado del registro.

Registro del sistema en Android Runtime (ART)

Hay 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 los registros del sistema disponibles

Si bien 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, en el que syslog(2) corresponde al kernel de Linux syslog que controla el búfer printk, y syslog(3) corresponde al registrador general del sistema. Android usa la biblioteca liblog para el registro general del sistema.

liblog proporciona wrappers para los grupos de registros secundarios 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 Ejemplos de funciones
log_main.h ALOGV, ALOGW
log_radio.h RLOGD, RLOGE
log_system.h SLOGI, SLOGW

Figura 7: Contenedores de liblog

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

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

Figura 8: Bibliotecas de registro de nivel superior.

Aproximaciones de múltiples pilas

Debido a las diferencias en la granularidad y la intención del nivel, no hay coincidencias claras o exactas de los diferentes estándares de registro. Por ejemplo, los niveles java.util.logging.Level y android.util.Log para los registros de errores no coinciden de forma exacta:

java.util.Logging.Level android.util.Log
GRAVE Log.wtf
GRAVE 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 sobre los mensajes de niveles, consulta 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 explícitamente de identificación personal.

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

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

Registros del dispositivo

El acceso a todos los registros del dispositivo, incluido el uso de android.permission.READ_LOGS, está restringido:

  • 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 las siguientes condiciones:
    • 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.