Desenvolver aplicativos robustos e eficientes envolve mais do que apenas escrever código; é essencial monitorar como um aplicativo se comporta em tempo real. A capacidade de criar e ler logs é crucial para entender e melhorar o desempenho e a estabilidade de um aplicativo, além é claro de facilitar a captura e correção de bugs no aplicativo.
A Importância dos Logs em Aplicativos
Logs são essenciais para qualquer aplicativo, pois oferecem uma visão clara do que está acontecendo “sob o capô”. Com logs adequados, desenvolvedores podem rastrear o fluxo de execução, monitorar o estado das variáveis, e identificar e corrigir bugs de maneira eficiente.
Claro que é totalmente possível incluir breakpoints no Delphi e executar step-by-step, ou seja, linha a linha. Mas nem sempre isso ajuda, pois sabemos que a uma lentidão no processo, já que precisamos estar conectados ao celular/tablet por meio de USB ou wi-fi, e isso pode demorar o processo de debug.
Uma parte crítica também é quando estamos trabalhando com Threads. Debugar um aplicativo Android que possui algum processo envolvido em Threads não é uma tarefa simples. Portanto, é muito importante a criação de logs que vão garantir uma melhor visão do que está acontecendo.
Logs auxiliam na depuração de erros
Logs são essenciais para o desenvolvimento de software, servindo como uma ferramenta fundamental para a depuração e análise de problemas em aplicativos. Quando um aplicativo falha ou se comporta de maneira inesperada, frequentemente, o primeiro recurso que os desenvolvedores consultam são os logs. Eles oferecem um registro cronológico das atividades do aplicativo, permitindo aos desenvolvedores rastrear o que o aplicativo estava fazendo no momento do problema.
Exemplos de Uso de Logs na Depuração
Suponha que um aplicativo móvel trava quando o usuário tenta carregar dados específicos. Sem logs, identificar a origem do problema pode ser como procurar uma agulha no palheiro. Com logs adequados, porém, os desenvolvedores podem ver exatamente quais funções estavam sendo executadas e quais dados estavam sendo processados no momento do travamento. Por exemplo:
- Antes do Crash
1 2 3 4 5 6 |
INFO: Solicitação de dados iniciada para o usuário ID1234 DEBUG: Dados recebidos: [dados parciais...] ERROR: Falha na conversão de dados tipo X CRITICAL: Aplicativo encerrado devido a exceção não tratada |
Este log mostra claramente que o problema ocorreu durante uma “falha na conversão de dados”, levando a uma “exceção não tratada” que causou o travamento do aplicativo. Com essa informação, os desenvolvedores podem ir diretamente ao código que lida com a conversão dos dados e investigar a causa do erro.
Vantagens de ter Logs em aplicações
- Detecção Rápida de Problemas
- Logs proporcionam uma maneira rápida de identificar onde e quando um problema ocorreu, o que pode economizar horas de depuração.
- Monitoramento de Saúde do Aplicativo
- Logs não são úteis apenas para depuração após falhas; eles também podem ser usados para monitorar a saúde do aplicativo em tempo real, identificando lentidão nas transações ou aumento inesperado no uso de recursos.
- Histórico Detalhado
- Manter um histórico de logs pode ajudar a identificar e analisar tendências ou recorrências de problemas, permitindo uma abordagem proativa na melhoria da aplicação.
- Facilitação de Auditorias
- Em ambientes regulados, os logs fornecem uma trilha de auditoria que pode ser usada para verificar a conformidade com regulamentos de segurança ou operacionais.
- Simplificação do Suporte ao Cliente
- Com logs detalhados, as equipes de suporte podem rapidamente entender e resolver problemas relatados pelos usuários, melhorando a satisfação do cliente.
O que é Logcat?
Logcat é uma ferramenta de linha de comando integrada ao Android que coleta e exibe logs do sistema e de aplicativos. Todos os aplicativos Android geram logs que podem ser acessados através do Logcat, tornando-o uma ferramenta indispensável para desenvolvedores.
Como funciona o Logcat?
Logcat funciona capturando mensagens de log baseadas em vários níveis de prioridade, como erro (E), aviso (W), informação (I), depuração (D) e detalhado (V). Essas mensagens ajudam desenvolvedores a entender o comportamento do aplicativo em diferentes condições e configurações.
Comandos do Logcat
Para usar o Logcat, uma ferramenta essencial na caixa de ferramentas de qualquer desenvolvedor Android, é necessário que o dispositivo Android (celular ou tablet) esteja conectado ao computador. Isso pode ser feito de duas maneiras principais:
- Conexão USB: Conecte seu dispositivo Android ao computador via cabo USB. Certifique-se de que a depuração USB esteja ativada nas opções de desenvolvedor do dispositivo.
- ADB via Wi-Fi: Para dispositivos que suportam conexões sem fio, você pode conectar o dispositivo ao ADB via Wi-Fi. Isso geralmente requer que o dispositivo esteja na mesma rede que o computador e que você inicie a sessão ADB via USB para configurar a conexão Wi-Fi inicialmente. Aqui estão os comandos para configurar o ADB via Wi-Fi:
1 2 3 4 |
adb tcpip 5555 adb connect <IP_DO_DISPOSITIVO>:5555 |
Caso tenha dúvidas, assista a esse vídeo no nosso canal:
- Substitua
<IP_DO_DISPOSITIVO>
pelo endereço IP real do seu dispositivo Android.
Capturando Logs com o Logcat
Uma vez que o dispositivo esteja conectado, você pode começar a capturar logs usando o Logcat através do seguinte comando no terminal ou prompt de comando:
1 2 3 |
adb logcat |
Este comando exibirá todos os logs do sistema e de aplicativos gerados no dispositivo.
Comandos e filtros do Logcat
- Limpar o Buffer de Logs: Antes de iniciar a captura de logs, você pode querer limpar logs antigos para facilitar a visualização dos novos eventos.
1 2 3 |
adb logcat -c |
Filtrar por Nível de Prioridade: Se você estiver interessado apenas em mensagens de erro, por exemplo, você pode filtrar os logs por nível de prioridade:
1 2 3 |
adb logcat MyAppTag:D *:E |
- Este comando mostra todas as mensagens de Debug (e mais críticas) para “MyAppTag” e silencia todos os outros logs.
- Exportar para um Arquivo: Para salvar os logs em um arquivo, você pode redirecionar a saída para um arquivo no seu sistema:
1 2 3 |
adb logcat -v time > myapp_logs.txt |
Você pode filtrar logs de um aplicativo específico usando tags. Por exemplo, para ver apenas os logs de um aplicativo com a tag “MyApp”, você usaria:
1 2 3 |
adb logcat MyApp:D *:S |
Isso mostra todas as mensagens de depuração (D) para “MyApp” e silencia os outros logs.
Como enviar logs de um app Delphi para o Logcat?
O logging é uma ferramenta crucial em qualquer plataforma de desenvolvimento, mas é particularmente essencial no desenvolvimento de aplicativos móveis com Delphi para Android. Implementar logs eficientes ajuda os desenvolvedores a entender o comportamento do aplicativo em condições reais de uso, facilita a identificação de erros e a análise de desempenho, e pode fornecer insights valiosos sobre como os usuários interagem com o aplicativo.
Vantagens do Logging via Delphi no Android
- Rastreamento de Erros e Exceções: Logs permitem que você capture informações detalhadas sobre exceções e erros de runtime, o que é crucial para diagnóstico rápido e eficaz.
- Monitoramento de Desempenho: Logs podem ser usados para monitorar o desempenho de partes críticas do seu aplicativo, ajudando a identificar pontos de lentidão ou potenciais vazamentos de memória.
- Auditoria e Segurança: Através dos logs, é possível manter um registro de atividades importantes, como transações ou modificações de dados sensíveis.
- Feedback em Tempo Real: Em um ambiente de desenvolvimento, ver os logs em tempo real enquanto o aplicativo está em execução pode fornecer feedback imediato sobre o impacto de recentes mudanças no código.
Como Enviar Logs do Delphi para o Logcat
Para enviar logs do seu aplicativo Delphi para o Logcat, você pode usar a unit Androidapi.Log
. Esta unit oferece uma interface direta para o sistema de log do Android, permitindo que você envie mensagens de log diretamente do seu código Delphi.
Passos para Implementar Logs:
- Incluir a Unidade Necessária: No seu projeto Delphi, inclua a unidade
Androidapi.Log
. Isso proporciona acesso às funções de log do Android.
1 2 3 |
uses Androidapi.Log; |
Enviar Mensagens de Log: Você pode enviar logs usando diferentes níveis de prioridade, dependendo da importância da mensagem. Por exemplo, para enviar uma mensagem de erro, você utilizaria:
1 2 3 4 |
Log.d('MyApp', 'Esta é uma mensagem de debug'); Log.e('MyApp', 'Erro encontrado: ' + MensagemDeErro); |
- Aqui,
Log.d
é usado para mensagens de debug eLog.e
para mensagens de erro. As funções disponíveis incluemLog.v
(Verbose),Log.d
(Debug),Log.i
(Info),Log.w
(Warning), eLog.e
(Error). - Visualizar os Logs: Depois de enviar logs do seu aplicativo, você pode visualizá-los utilizando o comando
adb logcat
no terminal ou em uma interface gráfica que suporte visualização de logs do Android.
Esse processo é fácil, basta abrir o terminal do Windows, qualquer um, digitar:
1 2 3 |
adb devices |
Isso vai trazer na tela o UUID do dispositivo conectado na porta USB. Em seguida digite:
1 2 3 |
adb -s <UUID> <TAG>:D *:S |
Substitua o <UUID> pelo UUID do seu dispositivo pego no comando anterior. Substitua <TAG> pela tag do seu aplicativo que você indicou na chamada para o log. No exemplo acima usamos ‘MyAPP’, no print de tela abaixo usei a tag ‘MeuAplicativo’.
Perceba que em cada botão do meu aplicativo exemplo, coloquei um tipo de log, Information, Warning, Error e Fatal Error. Os logs são printados na tela do terminal ao clicar no botão.
Então agora imagine uma janela de login por exemplo: Poderíamos fazer a chamada ao log antes e depois de clicar no botão Entrar, ou durante o processo de autenticação do servidor, sincronismo com o banco de dados, enfim, as possibilidades são infinitas.
Conheça a Biblioteca MultiLog4D: Simplificando Logs em Aplicativos Delphi
Se você leu este artigo até aqui e gostou do que viu, certamente irá apreciar ainda mais a solução que estou desenvolvendo para facilitar o dia a dia dos desenvolvedores de aplicativos Delphi. Apresento a você a biblioteca MultiLog4D.
O que é MultiLog4D?
MultiLog4D é uma biblioteca em desenvolvimento que tem como objetivo simplificar o processo de logging em diversas plataformas usando Delphi. Com apenas uma linha de código, você pode enviar logs para o Android, e isso é apenas o começo. A primeira versão suporta Android, e planejamos expandir rapidamente para outras plataformas, incluindo Windows Desktop (Log em arquivo), Windows Service (Event Viewer), Linux (syslog), macOS (NSLog) e iOS (NSLog). O nome “MultiLog4D” reflete essa capacidade multiplataforma.
Por que usar MultiLog4D?
- Simplicidade: Elimina a complexidade do manejo de diferentes sistemas de logs em várias plataformas.
- Eficiência: Acelera o desenvolvimento e a depuração ao permitir que você se concentre no código, não na configuração de logs.
- Unificação: Mantenha uma consistência de logs através de todas as plataformas suportadas.
- Open Source: Totalmente aberto para contribuições da comunidade, garantindo que evolui para atender às necessidades reais dos desenvolvedores.
Instalação e Uso
MultiLog4D está disponível para download e instalação via GitHub ou através do gerenciador de pacotes Boss.
- Instalação via GitHub:
- Visite nosso repositório no GitHub para clonar ou baixar diretamente.
- Instalação via Boss:
- Se você usa o Boss (Delphi Package Manager), pode instalar o MultiLog4D facilmente com o seguinte comando:
1 2 3 |
boss install github.com/adrianosantostreina/MultiLog4D |
Aproveite que entrou no GitHub e marque estrelinha pra nós, ajuda demais o projeto.
Exemplos de Uso
Uma vez instalado, usar o MultiLog4D é extremamente simples. Veja como você pode enviar logs de sua aplicação Delphi para o Android:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
program DefaultSample; uses System.StartUpCopy, MultiLog4D.Util, FMX.Forms, Unit1 in 'Unit1.pas' {Form1}; {$R *.res} begin TMultiLog4DUtil .Logger .Tag('MultiLog4D') .LogWriteInformation('Inicializando o sistema...'); Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end. |
Esse exemplo demonstra como enviar um log simples. Nesse exemplo abri o Source do projeto e antes da inicialização do aplicativo chamei o log pra informar que vamos passar pela inicialização do sistema. Pra facilitar a vida de todos nós, criei uma unit MultiLog4D.Util que possui uma classe Singleton TMultiLog4DUtil e nela a propriedade Logger que possui os métodos de log.
Note que chamo primeiro o TAG e depois o LogWriteInformation, a ordem é o de menos, o que quero que observe aqui é o TAG. A TAG é obrigatória apesar da biblioteca não forçar o uso. Ela é importante para que possamos filtrar as mensangens no terminal, como vimos anteriormente. Portanto um log gerado pela nossa aplicação com a TAG MultiLog4D, filtraríamos os logs no terminal da seguinte forma:
1 2 3 |
adb -s <UUID> MultiLog4D:D *:S |
Lembrando que o UUID é você consegue depois de rodar o comando adb devices
. Conforme novas plataformas forem adicionadas, o mesmo código poderá enviar logs para diferentes destinos sem nenhuma alteração adicional por parte do desenvolvedor.
Um outro exemplo de uso seria dentro de blocos try..except, por exemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
procedure TForm1.Button6Click(Sender: TObject); begin try TMultiLog4DUtil .Logger .LogWriteWarning('Converte um número'); StrToInt('MultiLog4D'); except on E:Exception do begin TMultiLog4DUtil .Logger .LogWriteError('Ocorreram erros:') .LogWriteFatalError(E.ClassName + ' | ' + E.Message); end; end; end; |
Perceba que a cada chamada para o log, uma mensagem é publicada no terminal, isso ajuda demais na depuração e descoberta de problemas. Aqui simulamos um erro fatal, conversão de texto em inteiro. Colocamos o log no Except do código e ele mostrará no terminal a mensagem “Ocorreram erros:” acrescidos dos erros original do Delphi em inglês retornados pelo Except. Legal né?
Outras formas de uso
Escrevemos uma classe Factory e você pode utilizar ela para fazer uso do Log do jeito como desejar. Aqui abaixo declaramos MultiLog4D.Factory no uses da Unit1 (Form1), declaramos uma variável global para o Form (FLogger) e então chamamos os métodos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
uses MultiLog4D.Types, MultiLog4D.Factory; ... type TForm1 = class private FLogger: IMultiLog4D; public end; ... procedure TForm1.Button1Click(Sender: TObject); begin FLogger := TLogFactory.GetLogger; // Correto, obtém a instância adequada FLogger.Tag('MultiLog4D'); FLogger.LogWrite('Teste de Log', ltInformation); // Chama método que deve estar implementado end; |
Claro que para um aplicativo com múltiplo forms teríamos que ter o FLogger como uma varável global para a aplicação inteira, talvez em uma Unit ou DataModule comum a toda a aplicação, dessa forma em qualquer lugar poderia informar o método LogWrite.
Um exemplo de Unit poderia ser assim:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
unit LoggingUtils; interface uses MultiLog4D.Interfaces, MultiLog4D.Factory; var GlobalLogger: IMultiLog4D; implementation initialization GlobalLogger := TLogFactory.GetLogger; finalization GlobalLogger := nil; end. |
E as chamadas nos forms ficariam:
1 2 3 4 5 6 7 8 9 10 |
uses LoggingUtils; procedure TForm1.Button1Click(Sender: TObject); begin GlobalLogger.Tag('MultiLog4D'); GlobalLogger.LogWrite('Log message here', ltInformation); end; |
Dessa forma, LoggingUitls seria adicionada ao uses de cada form que precisa utilizar o Log. Eu particularmente gosto dessa abordagem, mas não é a que mais uso em meus sistemas, varia bastante a forma de utilização.
Por fim, mais uma forma legal de usar é criando sua própria classe Singleton em seu projeto, assim você não precisa instanciar, veja:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
unit LoggingService; interface uses MultiLog4D.Interfaces, MultiLog4D.Factory; type TLoggingService = class private class var FLogger: IMultiLog4D; class function GetLogger: IMultiLog4D; static; public class property Logger: IMultiLog4D read GetLogger; end; implementation class function TLoggingService.GetLogger: IMultiLog4D; begin if FLogger = nil then FLogger := TLogFactory.GetLogger; Result := FLogger; end; end. |
Em outra palavras, criamos uma classe Singleton chamada TLoggingService e a partir dela podemos apenas incluir a unit no uses de cada form e fachar a chamada direto:
1 2 3 4 5 6 7 8 9 10 |
uses LoggingService; procedure TForm1.Button1Click(Sender: TObject); begin TLoggingService.Logger.Tag('MultiLog4D'); TLoggingService.Logger.LogWrite('Log message here', ltInformation); end; |
Como pudemos ver, há várias formas de utilização. A que mais gosto é a primeira delas, onde usamos a classe singleton que desenvolvemos, MultiLog4D.Util. Entretanto quis demonstrar que você pode usar de várias formas diferentes a biblioteca que desenvolvi. Muito legal né?
O Futuro do MultiLog4D
Estamos trabalhando ativamente para expandir a funcionalidade do MultiLog4D. Em breve, você poderá logar informações não apenas no Android, mas também em:
- Windows (Desktop e Service): Integrando com o Event Viewer.
- Linux: Enviando logs para o syslog.
- macOS e iOS: Utilizando as ferramentas nativas de log desses sistemas.
No Windows por exemplo vamos gravar os logs em arquivo que poderão ser consultados mais tarde tanto em aplicações VCL quanto FMX.
Conclusão
MultiLog4D visa ser a solução definitiva para logging em aplicações Delphi multiplataforma. Ao abstrair as complexidades de cada plataforma, permite que desenvolvedores se concentrem no que realmente importa: criar aplicativos incríveis. Convido todos a experimentar a biblioteca, contribuir e fazer parte desta excitante jornada de desenvolvimento.
Esperamos que a MultiLog4D torne seu desenvolvimento mais fácil e seus aplicativos mais robustos e fáceis de manter.
Comunidade no Telegram
🚀Comente no campo abaixo 👇👇👇 o que achou e qual sua dúvida.
Te vejo na próxima
Adriano Santos