Este artigo aborda o processo de log, incluindo padrões de log, diretrizes de nível, classes, propósitos e aproximações de várias pilhas.
Padrões de registro
O login no Android é complexo devido à mistura de padrões usados que são combinados no logcat
. Os principais padrões utilizados estão detalhados abaixo:
Fonte | Exemplos | Orientação de nível de pilha |
---|---|---|
RFC 5424 (padrão syslog ) | Kernel Linux, muitos aplicativos Unix | Kernel, daemons do sistema |
android.util.Log | Estrutura do Android + registro de aplicativos | Estrutura do Android e aplicativo do sistema |
java.util.logging.Level | Log geral em Java | aplicativo sem sistema |
Figura 1: Padrões de nível de log.
Embora cada um desses padrões tenha construção de nível semelhante, eles variam em granularidade. Os equivalentes aproximados entre os padrões são os seguintes:
Nível RFC 5424 | RFC 5424 Gravidade | Descrição da RFC 5424 | android.util.Log | java.util.logging.Level |
---|---|---|---|---|
0 | Emergência | O sistema está inutilizável | Log.e / Log.wtf | SEVERE |
1 | Alerta | Ação deve ser tomada imediatamente | Log.e / Log.wtf | SEVERE |
2 | Crítico | Condições críticas | Log.e / Log.wtf | SEVERE |
3 | Erro | Condições de erro | Log.e | SEVERE |
4 | Aviso | Condições de aviso | Log.w | WARNING |
5 | Perceber | Normal, mas significativo | Log.w | WARNING |
6 | Informações | Mensagens de informação | Log.i | INFO |
7 | Depurar | Mensagens no nível de depuração | Log.d | CONFIG , FINE |
- | - | Mensagens detalhadas | Log.v | FINER / FINEST |
Figura 2: níveis de log de syslog
, Android e Java.
Diretrizes de nível de registro
Existem diretrizes existentes para cada padrão de log. O nível de log escolhido segue o padrão apropriado sendo usado, como usar o padrão syslog
para desenvolvimento do kernel.
As ordens de nível de log, do menor para o maior, são mostradas nas três figuras abaixo:
ERROR | Esses logs são sempre mantidos. |
WARN | Esses logs são sempre mantidos. |
INFO | Esses logs são sempre mantidos. |
DEBUG | Esses logs são compilados, mas removidos em tempo de execução. |
VERBOSE | Esses logs nunca são compilados em um aplicativo, exceto durante o desenvolvimento. |
Figura 3: android.util.Log
CONFIG | Nível de mensagem para mensagens de configuração estática |
FINE | Nível de mensagem fornecendo informações de rastreamento |
FINER | Indica uma mensagem de rastreamento bastante detalhada |
FINEST | Indica uma mensagem de rastreamento altamente detalhada |
INFO | Nível de mensagem para mensagens informativas |
SEVERE | Nível de mensagem indicando uma falha grave |
WARNING | Nível de mensagem indicando um possível problema |
Figura 4: java.util.Logging.Level
.
0 | Emergência | O sistema está inutilizável |
1 | Alerta | Ação deve ser tomada imediatamente |
2 | Crítico | Condições críticas |
3 | Erro | Condições de erro |
4 | Aviso | Condições de aviso |
5 | Perceber | Condição normal, mas significativa |
6 | Informativo | Mensagens informativas |
7 | Depurar | Mensagens no nível de depuração |
Figura 5: RFC 5424
- Seção 6.2.1 .
Registro de aplicativos
O log seletivo é realizado com TAG
pela classe android.util.Log
usando Log#isLoggable
, conforme mostrado abaixo:
if (Log.isLoggable("FOO_TAG", Log.VERBOSE)) { Log.v("FOO_TAG", "Message for logging."); } |
---|
Os logs podem ser ajustados em tempo de execução para fornecer um nível selecionado de log, conforme mostrado abaixo:
adb shell setprop log.tag.FOO_TAG VERBOSE |
---|
As propriedades log.tag.*
são redefinidas na reinicialização. Existem variantes persistentes que permanecem nas reinicializações também. Veja abaixo:
adb shell setprop persist.log.tag.FOO_TAG VERBOSE |
---|
As verificações Log#isLoggable
deixam rastros de log no código do aplicativo. Os sinalizadores booleanos DEBUG
ignoram os rastreamentos de log usando otimizações do compilador definidas como false
, conforme mostrado abaixo:
private final static boolean DEBUG = false; |
---|
O registro pode ser removido por APK por meio dos conjuntos de regras do ProGuard pelo R8
em tempo de compilação. O exemplo a seguir remove tudo abaixo do registro de nível 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 |
---|
Isso é útil para lidar com vários tipos de compilação de aplicativos (por exemplo, compilações de desenvolvimento versus compilações de lançamento) em que se espera que o código subjacente seja o mesmo, mas os níveis de log permitidos são diferentes. Uma política explícita deve ser definida e seguida para aplicativos (especialmente aplicativos de sistema) para decidir como os tipos de compilação e as expectativas de versão afetam a saída do log.
Log do sistema no Android Runtime (ART)
Existem várias classes disponíveis para aplicativos e serviços do sistema:
Classe | Objetivo |
---|---|
android.telephony.Rlog | Registro de rádio |
android.util.Log | Registro geral de aplicativos |
android.util.EventLog | Log de eventos de diagnóstico do integrador de sistemas |
android.util.Slog | Registro da estrutura da plataforma |
Figura 6: Classes e propósitos de log do sistema disponíveis.
Embora android.util.Log
e android.util.Slog
usem os mesmos padrões de nível de log, Slog
é uma classe @hide
utilizável apenas pela plataforma. Os níveis de EventLog
são mapeados para as entradas no arquivo event.logtags
em /system/etc/event-log-tags
.
Log Nativo
O login em C/C++ segue o padrão syslog
com syslog
(2) correspondente ao syslog
do kernel Linux que controla o buffer printk
e syslog
(3) correspondente ao logger geral do sistema. O Android usa a biblioteca liblog
para log geral do sistema.
liblog
fornece wrappers para os grupos de sublogs usando a seguinte forma de macro:
[Sublog Buffer ID] LOG [Log Level ID] |
RLOGD
, por exemplo, corresponde a [Radio log buffer ID] LOG [Debug Level]
. Os principais wrappers de liblog
são os seguintes:
Classe de wrapper | Funções de exemplo |
---|---|
log_main.h | ALOGV , ALOGW |
log_radio.h | RLOGD , RLOGE |
log_system.h | SLOGI , SLOGW |
Figura 7: wrappers de liblog
.
O Android tem interfaces de nível superior para registro que são favorecidas em relação ao uso direto liblog
, como visto abaixo:
Biblioteca | Uso |
---|---|
async_safe | Biblioteca apenas para log de ambientes seguros para sinal assíncrono |
libbase | Biblioteca de registro que fornece uma interface de fluxo C++ para registro, semelhante ao registro no estilo do Google (glog). libbase é utilizável em projetos externos e está disponível em aplicativos usando libbase_ndk . |
Figura 8: Bibliotecas de log de nível superior.
Aproximações de várias pilhas
Devido às diferenças de granularidade e intenção de nível, não há correspondências claras ou exatas de diferentes padrões de registro. Por exemplo, os níveis java.util.logging.Level
e android.util.Log
para logs de erros não são uma correspondência de 1:1:
java.util.Logging.Level | android.util.Log |
---|---|
FORTE | Log.wtf |
FORTE | Log.e |
Figura 9: Nível de erro no registro Java padrão versus registro no Android.
Em casos como esse, use o padrão individual para determinar qual nível aplicar.
Durante o desenvolvimento do sistema com vários componentes de nível de pilha, siga a Figura 1 para determinar qual padrão usar por componente. Para obter um guia aproximado para mensagens de camada, siga a Figura 2.
Segurança e privacidade
Não registre informações de identificação pessoal (PII). Isso inclui detalhes como:
- Endereço de e-mail
- Números de telefone
- Nomes
Da mesma forma, certos detalhes são considerados confidenciais, mesmo que não sejam explicitamente identificáveis pessoalmente.
Por exemplo, embora as informações de fuso horário não sejam consideradas pessoalmente identificáveis, elas fornecem uma indicação da localização aproximada de um usuário.
A política de registro e os detalhes aceitáveis devem ser tratados como parte da análise de segurança e privacidade antes do lançamento.