Este artigo aborda o processo de registro em log, incluindo padrões de registro, diretrizes de nível, classes, finalidades e aproximações multistack.
Padrões de registro
O login no Android é complexo devido à combinação de padrões usados que são combinados no logcat
. Os principais padrões utilizados são detalhados abaixo:
Fonte | Exemplos | Orientação em nível de pilha |
---|---|---|
RFC 5424 (padrão syslog ) | Kernel Linux, muitos aplicativos Unix | Kernel, daemons do sistema |
android.util.Log | Estrutura Android + registro de aplicativos | Estrutura Android e aplicativo de sistema |
java.util.logging.Level | Log geral em Java | aplicativo que não é do sistema |
Figura 1: Padrões de nível de log.
Embora cada um desses padrões tenha um nível de construção semelhante, eles variam em granularidade. Os equivalentes aproximados entre os padrões são os seguintes:
Nível RFC 5424 | Gravidade RFC 5424 | 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ções devem ser tomadas 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 informativas | Log.i | INFO |
7 | Depurar | Mensagens em nível de depuração | Log.d | CONFIG , FINE |
- | - | Mensagens detalhadas | Log.v | FINER / FINEST |
Figura 2: níveis de log syslog
, Android e Java.
Diretrizes em nível de registro
Existem diretrizes fornecidas para cada padrão de registro. O nível de log escolhido segue o padrão apropriado usado, como usar o padrão syslog
para desenvolvimento do kernel.
Os pedidos em nível de log, do menor para o maior, são mostrados nas três figuras abaixo:
ERROR | Esses registros são sempre mantidos. |
WARN | Esses registros são sempre mantidos. |
INFO | Esses registros 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ções devem ser tomadas 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 em nível de depuração |
Figura 5: RFC 5424
- Seção 6.2.1 .
Registro de aplicativos
O registro 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 registro, 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 também permanecem durante as reinicializações. 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 no 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 sejam diferentes. Uma política explícita deve ser definida e seguida para aplicativos (particularmente aplicativos de sistema) para decidir como os tipos de construção e as expectativas de lançamento impactam 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:
Aula | Propósito |
---|---|
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 sistema |
android.util.Slog | Log da estrutura da plataforma |
Figura 6: Classes e finalidades 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 EventLog
são mapeados para as entradas no arquivo event.logtags
em /system/etc/event-log-tags
.
Registro nativo
O log 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 criador de logs geral do sistema. O Android usa a biblioteca liblog
para registro geral do sistema.
liblog
fornece wrappers para os grupos de sublogs usando o seguinte formato de macro:
[Sublog Buffer ID] LOG [Log Level ID] |
RLOGD
, por exemplo, corresponde a [Radio log buffer ID] LOG [Debug Level]
. Os principais wrappers 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 liblog
.
O Android tem interfaces de nível superior para registro que são preferidas ao uso direto liblog
, conforme visto abaixo:
Biblioteca | Uso |
---|---|
async_safe | Biblioteca apenas para registro em ambientes seguros com sinal assíncrono |
libbase | Biblioteca de registro em log que fornece uma interface de fluxo C++ para registro em log, semelhante ao registro em log no estilo Google (glog). libbase pode ser usado em projetos externos e está disponível em aplicativos que usam libbase_ndk . |
Figura 8: Bibliotecas de log de nível superior.
Aproximações Multistack
Devido às diferenças na granularidade e na intenção de nível, não há correspondências claras ou exatas entre os 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 1:1:
java.util.Logging.Level | android.util.Log |
---|---|
FORTE | Log.wtf |
FORTE | Log.e |
Figura 9: Nível de erro no log Java padrão vs. log do Android.
Em casos como este, use o padrão individual para determinar qual nível aplicar.
Durante o desenvolvimento do sistema com vários componentes no nível da pilha, siga a Figura 1 para determinar qual padrão usar por componente. Para obter um guia aproximado de mensagens em camadas, 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 log e os detalhes aceitáveis devem ser tratados como parte da revisão de segurança e privacidade antes do lançamento.
Registros de dispositivos
O acesso a todos os registros do dispositivo, inclusive o uso de android.permission.READ_LOGS
, é restrito:
- Se um aplicativo em segundo plano solicitar acesso a todos os registros do dispositivo, a solicitação será automaticamente negada, a menos que o aplicativo:
- compartilha o UID do sistema.
- usa um processo nativo do sistema (
UID
<APP_UID
). - usa
DropBoxManager
. - acessa apenas o buffer do log de eventos.
- usa a API
EventLog
. - usa testes instrumentados.
- Se um aplicativo em primeiro plano com
READ_LOGS
solicitar acesso aos logs do dispositivo, o sistema solicitará que o usuário aprove ou negue a solicitação de acesso.