Este artigo aborda o processo de geração de registros, incluindo padrões, diretrizes de nível, classes, finalidades e aproximações de várias pilhas.
Padrões de registro
A geração de registros no Android é complexa devido à combinação de padrões usados no
logcat
. Os principais padrões usados estão detalhados abaixo:
Fonte | Exemplos | Orientação sobre o nível da pilha |
---|---|---|
RFC 5424 (padrão syslog ) |
Kernel do Linux, muitos apps Unix | Kernel, daemons do sistema |
android.util.Log |
Estrutura do Android + geração de registros de apps | Framework do Android e app do sistema |
java.util.logging.Level |
Registro geral em Java | app que não é do sistema |
Figura 1:padrões de nível de registro.
Embora cada um desses padrões tenha uma 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 | Gravidade da RFC 5424 | Descrição da RFC 5424 | android.util.Log | java.util.logging.Level |
---|---|---|---|---|
0 | Emergência | O sistema não pode ser usado | Log.e / Log.wtf |
SEVERE |
1 | Alerta | É necessário tomar uma ação 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 | Alerta | Condições de alerta | Log.w |
WARNING |
5 | Aviso | Normal, mas significativo | Log.w |
WARNING |
6 | Informações | Mensagens informativas | Log.i |
INFO |
7 | Depuração | Mensagens de nível de depuração | Log.d |
CONFIG , FINE |
- | - | Mensagens detalhadas | Log.v |
FINER / FINEST |
Figura 2:níveis de registro do syslog
, do Android e do Java.
Diretrizes de nível de registro
Há diretrizes para cada padrão de registro. O nível de registro escolhido segue o padrão apropriado em uso, como o syslog
para desenvolvimento de kernel.
As ordens de nível de registro, do menor para o maior, são mostradas 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 registros são compilados, mas removidos no tempo de execução. |
VERBOSE |
Esses registros nunca são compilados em um app, exceto durante o desenvolvimento. |
Figura 3: android.util.Log
CONFIG |
Nível de mensagem para mensagens de configuração estática |
FINE |
Nível da mensagem que fornece 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 que indica uma falha grave. |
WARNING |
Nível da mensagem que indica um possível problema |
Figura 4:java.util.Logging.Level
.
0 | Emergência | O sistema não pode ser usado |
1 | Alerta | É necessário tomar uma ação imediatamente |
2 | Crítico | Condições críticas |
3 | Erro | Condições de erro |
4 | Alerta | Condições de alerta |
5 | Aviso | Condição normal, mas significativa |
6 | Informativo | Mensagens informativas |
7 | Depuração | Mensagens de nível de depuração |
Figura 5:RFC 5424
- Seção 6.2.1.
Geração de registros de apps
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 registros podem ser ajustados no ambiente 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. Há
variantes persistentes que permanecem mesmo após reinicializações. Confira abaixo:
adb shell setprop persist.log.tag.FOO_TAG VERBOSE |
---|
As verificações do Log#isLoggable
deixam rastros de registros no código do app. Flags booleanas
DEBUG
ignoram rastreamentos de registros usando otimizações de compilador definidas como
false
, conforme mostrado abaixo:
private final static boolean DEBUG = false; |
---|
O registro em log pode ser removido por APK usando conjuntos de regras do ProGuard por R8
no tempo de compilação. O exemplo a seguir remove tudo abaixo do nível INFO
de geração de registros 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 processar vários tipos de build de app (por exemplo, builds de desenvolvimento x builds de lançamento), em que o código subjacente deve ser o mesmo, mas os níveis de registro permitidos são diferentes. Uma política explícita precisa ser definida e seguida para que os apps (principalmente os de sistema) decidam como os tipos de build e as expectativas de lançamento afetam a saída de registros.
Geração de registros do sistema no Android Runtime (ART)
Há várias classes disponíveis para apps e serviços do sistema:
Turma | Finalidade |
---|---|
android.telephony.Rlog |
Geração de registros de rádio |
android.util.Log |
Geração de registros gerais de apps |
android.util.EventLog |
Registro de eventos de diagnóstico do integrador de sistemas |
android.util.Slog |
Geração de registros do framework da plataforma |
Figura 6:classes e finalidades de registros do sistema disponíveis.
Embora android.util.Log
e android.util.Slog
usem os mesmos padrões de nível de registro, Slog
é uma classe @hide
que só pode ser usada pela plataforma. Os níveis de EventLog
são mapeados para as entradas no arquivo event.logtags
em /system/etc/event-log-tags
.
Geração de registros nativa
A geração de registros em C/C++ segue o padrão syslog
, com syslog
(2) correspondendo ao
kernel do Linux syslog
que controla o buffer printk
, e syslog
(3)
correspondendo ao registrador geral do sistema. O Android usa a biblioteca liblog
para geração de registros gerais do sistema.
O liblog
fornece wrappers para os grupos de subregistros usando a seguinte macro
forma:
[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 wrapper | Exemplos de funções |
---|---|
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 mais alto para registro em log que são preferíveis ao uso direto de
liblog
, como mostrado abaixo:
Biblioteca | Uso |
---|---|
async_safe |
Biblioteca apenas para geração de registros em ambientes assíncronos e seguros para sinais. |
libbase |
Biblioteca de geração de registros que fornece uma interface de stream C++ para geração de registros, semelhante à
geração de registros no estilo do Google (glog). A libbase pode ser usada em projetos externos
e está disponível em apps que usam libbase_ndk . |
Figura 8:bibliotecas de registro de nível mais alto.
Aproximações de várias pilhas
Devido a diferenças na granularidade e no nível de intenção, não há correspondências claras ou exatas de diferentes padrões de geração de registros. Por exemplo, os níveis
java.util.logging.Level
e android.util.Log
para registros de erros não são uma
correspondência 1:1:
java.util.Logging.Level | android.util.Log |
---|---|
SEVERA | Log.wtf |
SEVERA | Log.e |
Figura 9:nível de erro no registro padrão do Java x registro do Android.
Nesses casos, 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 um guia aproximado de mensagens por níveis, siga a Figura 2.
Segurança e privacidade
Não registre informações de identificação pessoal (PII). Isso inclui detalhes como:
- Endereços de e-mail
- Números de telefone
- Nomes
Da mesma forma, alguns detalhes são considerados sensíveis mesmo que não sejam explicitamente de identificação pessoal.
Por exemplo, embora as informações de fuso horário não sejam consideradas de identificação pessoal, elas indicam a localização aproximada de um usuário.
A política de registros e os detalhes aceitáveis precisam ser tratados como parte da revisão de segurança e privacidade antes do lançamento.
Registros do dispositivo
O acesso a todos os registros do dispositivo, incluindo o uso de
android.permission.READ_LOGS
é restrito:
- Se um app em segundo plano pedir acesso a todos os registros do dispositivo, a solicitação será negada automaticamente, a menos que o app:
- Compartilha o UID do sistema.
- Usa um processo nativo do sistema (
UID
<APP_UID
). - Usa
DropBoxManager
- Acessa apenas o buffer de registro de eventos.
- Usa a API
EventLog
. - Usa testes instrumentados.
- Se um app em primeiro plano com
READ_LOGS
solicitar acesso aos registros do dispositivo, o sistema vai pedir que o usuário aprove ou negue a solicitação.