Mudanças entre as edições de "RFWLogger"

De Wiki do Leitão
Ir para: navegação, pesquisa
 
(7 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 4: Linha 4:


=== Visão Geral ===
=== Visão Geral ===
O `RFWLogger` é um componente centralizado de logging para o sistema, projetado para gerenciar e registrar eventos, erros, e informações relevantes durante a execução do software. Ele abstrai os detalhes de implementação do processo de log, permitindo que diferentes partes do sistema registrem mensagens de maneira consistente e eficiente. Essa centralização facilita a manutenção, monitoramento e depuração, garantindo que todas as informações críticas sejam capturadas e armazenadas de forma estruturada.
O '''RFWLogger''' é um componente centralizado de logging para o sistema, projetado para gerenciar e registrar eventos, erros, e informações relevantes durante a execução do software. Ele abstrai os detalhes de implementação do processo de log, permitindo que diferentes partes do sistema registrem mensagens de maneira consistente e eficiente. Essa centralização facilita a manutenção, monitoramento e depuração, garantindo que todas as informações críticas sejam capturadas e armazenadas de forma estruturada.


=== Contexto de Uso ===
=== Contexto de Uso ===
Em qualquer sistema complexo, o registro adequado de eventos é essencial para identificar problemas, entender o comportamento do software e realizar melhorias contínuas. O `RFWLogger` atende a essa necessidade, oferecendo uma interface uniforme para o registro de logs em diferentes níveis de severidade, como DEBUG, INFO, WARN, ERROR, e EXCEPTION. Ele é amplamente utilizado em todo o sistema para capturar desde mensagens de depuração até exceções críticas, possibilitando uma análise detalhada e rápida resolução de problemas. Além disso, o `RFWLogger` permite a customização da implementação de logging, adaptando-se às necessidades específicas de cada ambiente ou projeto.
Em qualquer sistema complexo, o registro adequado de eventos é essencial para identificar problemas, entender o comportamento do software e realizar melhorias contínuas. O '''RFWLogger''' atende a essa necessidade, oferecendo uma interface uniforme para o registro de logs em diferentes níveis de severidade, como DEBUG, INFO, WARN, ERROR, e EXCEPTION. Ele é amplamente utilizado em todo o sistema para capturar desde mensagens de depuração até exceções críticas, possibilitando uma análise detalhada e rápida resolução de problemas. Além disso, o '''RFWLogger''' permite a customização da implementação de logging, adaptando-se às necessidades específicas de cada ambiente ou projeto.




Linha 13: Linha 13:


=== Classes e Interfaces Envolvidas ===
=== Classes e Interfaces Envolvidas ===
O `RFWLogger` e a interface `RFWLoggerImplementation` são os componentes centrais do sistema de logging. A seguir, detalhamos o papel de cada um desses elementos:
O '''RFWLogger''' e a interface '''RFWLoggerImplementation''' são os componentes centrais do sistema de logging. A seguir, detalhamos o papel de cada um desses elementos:


==== Classe RFWLogger ====
==== Classe RFWLogger ====
A classe `RFWLogger` é responsável por centralizar todas as operações de log no sistema. Ela oferece métodos estáticos que permitem o registro de diferentes tipos de eventos, como erros, avisos, mensagens de depuração, e exceções. Essa classe utiliza uma implementação de `RFWLoggerImplementation` para realizar o log propriamente dito, o que significa que a lógica de logging pode ser customizada conforme necessário, sem alterar as chamadas de log em outras partes do sistema.
A classe '''RFWLogger''' é responsável por centralizar todas as operações de log no sistema. Ela oferece métodos estáticos que permitem o registro de diferentes tipos de eventos, como erros, avisos, mensagens de depuração, e exceções. Essa classe utiliza uma implementação de '''RFWLoggerImplementation''' para realizar o log propriamente dito, o que significa que a lógica de logging pode ser customizada conforme necessário, sem alterar as chamadas de log em outras partes do sistema.


==== Interface RFWLoggerImplementation ====
==== Interface RFWLoggerImplementation ====
A interface `RFWLoggerImplementation` define os métodos que uma implementação de logging deve fornecer. Ela inclui métodos para registrar logs com várias severidades (`DEBUG`, `INFO`, `WARN`, `ERROR`, `EXCEPTION`, etc.), bem como para logar exceções e objetos. A interface permite que diferentes implementações sejam utilizadas, dependendo dos requisitos específicos, como logar em um arquivo, banco de dados, ou serviço externo.
A interface '''RFWLoggerImplementation''' define os métodos que uma implementação de logging deve fornecer. Ela inclui métodos para registrar logs com várias severidades (`DEBUG`, `INFO`, `WARN`, `ERROR`, `EXCEPTION`, etc.), bem como para logar exceções e objetos. A interface permite que diferentes implementações sejam utilizadas, dependendo dos requisitos específicos, como logar em um arquivo, banco de dados, ou serviço externo.


=== Relacionamento entre RFWLogger e RFWLoggerImplementation ===
=== Relacionamento entre RFWLogger e RFWLoggerImplementation ===
A classe `RFWLogger` utiliza uma implementação de `RFWLoggerImplementation` para realizar o registro de logs. Por padrão, `RFWLogger` usa uma implementação interna simples, que imprime os logs no console. No entanto, essa implementação pode ser substituída dinamicamente utilizando o método `setImpl`, permitindo que o sistema de logging seja adaptado a diferentes ambientes ou necessidades. Esse design flexível permite que o processo de logging seja facilmente customizado, sem exigir mudanças no código que gera os logs.
A classe '''RFWLogger''' utiliza uma implementação de '''RFWLoggerImplementation''' para realizar o registro de logs. Por padrão, '''RFWLogger''' usa uma implementação interna simples, que imprime os logs no console. No entanto, essa implementação pode ser substituída dinamicamente utilizando o método `setImpl`, permitindo que o sistema de logging seja adaptado a diferentes ambientes ou necessidades. Esse design flexível permite que o processo de logging seja facilmente customizado, sem exigir mudanças no código que gera os logs.




Linha 37: Linha 37:


=== Log de Exceções (logException) ===
=== Log de Exceções (logException) ===
O método `logException` permite registrar exceções que ocorrem no sistema. Ele converte a exceção em uma string detalhada, incluindo o stack trace, e a loga com a severidade apropriada. Se a exceção for do tipo `RFWValidationException` ou `RFWValidationGroupException`, ela é registrada com a severidade `VALIDATION`.
O método `logException` permite registrar exceções que ocorrem no sistema. Ele converte a exceção em uma string detalhada, incluindo o stack trace, e a loga com a severidade apropriada. Se a exceção for do tipo '''[[RFWValidationException]]''' ou '''[[RFWValidationGroupException]]''', ela é registrada com a severidade `VALIDATION`.


<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
Linha 95: Linha 95:


=== Severidades do Log (RFWLogSeverity) ===
=== Severidades do Log (RFWLogSeverity) ===
A interface `RFWLoggerImplementation` define uma enumeração interna chamada `RFWLogSeverity`, que especifica os diferentes níveis de severidade dos logs. Cada nível de severidade indica a importância ou o tipo de evento que está sendo registrado:
A interface '''RFWLoggerImplementation''' define uma enumeração interna chamada '''RFWLogSeverity''', que especifica os diferentes níveis de severidade dos logs. Cada nível de severidade indica a importância ou o tipo de evento que está sendo registrado:


* '''OBJECT''': Usado para registrar o estado de objetos. Ideal para logs detalhados que imprimem a estrutura e valores de um objeto específico.
* '''OBJECT''': Usado para registrar o estado de objetos. Ideal para logs detalhados que imprimem a estrutura e valores de um objeto específico.
Linha 107: Linha 107:


=== Implementação Padrão e Customização ===
=== Implementação Padrão e Customização ===
A interface `RFWLoggerImplementation` define os métodos que uma implementação de logger deve fornecer. A implementação padrão usada pelo `RFWLogger` simplesmente imprime logs no console. No entanto, é possível criar implementações personalizadas para, por exemplo, gravar logs em arquivos, enviar logs para um sistema de monitoramento, banco de dados ou conforme necessário.
A interface '''RFWLoggerImplementation''' define os métodos que uma implementação de logger deve fornecer. A implementação padrão usada pelo '''RFWLogger''' simplesmente imprime logs no console. No entanto, é possível criar implementações personalizadas para, por exemplo, gravar logs em arquivos, enviar logs para um sistema de monitoramento, banco de dados ou conforme necessário.


<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
Linha 118: Linha 118:
</syntaxhighlight>
</syntaxhighlight>


Para usar uma implementação personalizada, basta configurar o `RFWLogger` para utilizar a nova implementação:
Para usar uma implementação personalizada, basta configurar o '''RFWLogger''' para utilizar a nova implementação:


<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
Linha 125: Linha 125:


=== Exemplos de Implementações ===
=== Exemplos de Implementações ===
Aqui estão alguns exemplos de como você pode implementar a interface `RFWLoggerImplementation` para diferentes cenários:
Aqui estão alguns exemplos de como você pode implementar a interface '''RFWLoggerImplementation''' para diferentes cenários:


* '''Logger para Arquivo''': Uma implementação que grava os logs em arquivos locais, útil para auditoria ou diagnóstico offline.
* '''Logger para Arquivo''': Uma implementação que grava os logs em arquivos locais, útil para auditoria ou diagnóstico offline.
Linha 134: Linha 134:


=== Como Substituir a Implementação Padrão ===
=== Como Substituir a Implementação Padrão ===
O `RFWLogger` permite que você substitua a implementação padrão de logging por uma personalizada, oferecendo flexibilidade para adaptar o sistema às suas necessidades específicas. Para substituir a implementação, utilize o método `setImpl` e forneça uma instância da nova implementação que segue a interface `RFWLoggerImplementation`.
O '''RFWLogger''' permite que você substitua a implementação padrão de logging por uma personalizada, oferecendo flexibilidade para adaptar o sistema às suas necessidades específicas. Para substituir a implementação, utilize o método `setImpl` e forneça uma instância da nova implementação que segue a interface '''RFWLoggerImplementation'''.


'''Exemplo:'''
'''Exemplo:'''
Linha 161: Linha 161:


=== Personalização do Comportamento do Logger ===
=== Personalização do Comportamento do Logger ===
O `RFWLogger` é altamente configurável e pode ser adaptado para diferentes cenários:
O '''RFWLogger''' é altamente configurável e pode ser adaptado para diferentes cenários:


* '''Alteração Dinâmica da Implementação''': Você pode trocar a implementação de logging em tempo de execução conforme necessário, o que é útil em ambientes de desenvolvimento e produção com diferentes requisitos de logging.
* '''Alteração Dinâmica da Implementação''': Você pode trocar a implementação de logging em tempo de execução conforme necessário, o que é útil em ambientes de desenvolvimento e produção com diferentes requisitos de logging.
* '''Integração com Sistemas de Monitoramento''': Considerando a arquitetura modular do `RFWLogger`, é possível integrar o logger com sistemas de monitoramento externos, como Splunk, ELK Stack, ou outras ferramentas de observabilidade. Isso pode ser feito implementando uma nova versão da interface `RFWLoggerImplementation` que envia os logs para esses serviços.
* '''Integração com Sistemas de Monitoramento''': Considerando a arquitetura modular do '''RFWLogger''', é possível integrar o logger com sistemas de monitoramento externos, como Splunk, ELK Stack, ou outras ferramentas de observabilidade. Isso pode ser feito implementando uma nova versão da interface '''RFWLoggerImplementation''' que envia os logs para esses serviços.
* '''Customização de Formatos de Log''': Dependendo da implementação escolhida, você pode personalizar o formato das mensagens de log para incluir timestamps, IDs de correlação, ou outras metainformações relevantes para a análise e rastreamento de problemas.
* '''Customização de Formatos de Log''': Dependendo da implementação escolhida, você pode personalizar o formato das mensagens de log para incluir timestamps, IDs de correlação, ou outras metainformações relevantes para a análise e rastreamento de problemas.


Linha 170: Linha 170:


=== Cenários Comuns de Uso ===
=== Cenários Comuns de Uso ===
Nesta seção, apresentamos exemplos de como o `RFWLogger` pode ser utilizado em situações reais do sistema, ajudando a entender melhor a aplicação prática dos métodos de logging.
Nesta seção, apresentamos exemplos de como o '''RFWLogger''' pode ser utilizado em situações reais do sistema, ajudando a entender melhor a aplicação prática dos métodos de logging.


'''Exemplo 1: Registro de Erros Críticos'''
'''Exemplo 1: Registro de Erros Críticos'''
Linha 210: Linha 210:
</syntaxhighlight>
</syntaxhighlight>


Este exemplo mostra como o `RFWLogger` pode ser usado para registrar o estado de um objeto antes de uma operação crítica, facilitando a depuração se algo der errado.
Este exemplo mostra como o '''RFWLogger''' pode ser usado para registrar o estado de um objeto antes de uma operação crítica, facilitando a depuração se algo der errado.


=== Depuração e Análise ===
=== Depuração e Análise ===
A utilização eficaz do `RFWLogger` permite uma análise detalhada dos eventos registrados no sistema. Aqui estão algumas dicas para usar os logs na depuração e monitoramento:
A utilização eficaz do '''RFWLogger''' permite uma análise detalhada dos eventos registrados no sistema. Aqui estão algumas dicas para usar os logs na depuração e monitoramento:


* '''Identificação de Problemas Recorrentes''': Ao analisar os logs, preste atenção em mensagens de erro e exceção que se repetem, indicando problemas que precisam de correção.
* '''Identificação de Problemas Recorrentes''': Ao analisar os logs, preste atenção em mensagens de erro e exceção que se repetem, indicando problemas que precisam de correção.
Linha 220: Linha 220:
* '''Análise Pós-Morte''': Após uma falha, os logs são a principal ferramenta para entender o que ocorreu. Certifique-se de que as mensagens de log incluam todas as informações relevantes, como parâmetros de entrada e o estado do sistema.
* '''Análise Pós-Morte''': Após uma falha, os logs são a principal ferramenta para entender o que ocorreu. Certifique-se de que as mensagens de log incluam todas as informações relevantes, como parâmetros de entrada e o estado do sistema.


Esses exemplos e dicas mostram como o `RFWLogger` pode ser integrado no fluxo de trabalho diário para melhorar a monitorização, a depuração e a manutenção do sistema.
Esses exemplos e dicas mostram como o '''RFWLogger''' pode ser integrado no fluxo de trabalho diário para melhorar a monitorização, a depuração e a manutenção do sistema.


== Considerações Finais ==
== Limitações Conhecidas ==
=== Benefícios de Usar RFWLogger ===
=== Possíveis Melhorias e Futuras Implementações ===


== Referências e Links ==
=== Uso Cíclico do RFWLogger ===
=== Referência a Outros Componentes ===
=== Documentação Externa ===






O '''RFWLogger''' é um serviço de "log" do framework com o objetivo de realizar o registro de informações do sistema para os desenvolvedores. O desenvolvedor deve chamar o '''RFWLogger''' sempre que quiser registrar alguma informação similar a qualquer outro framework de Log. Além da possibilidade de imprimir no console, este serviço permite que o log seja organizado em banco de dados ou outros formatos desejado pelo desenvolvedor.
{{stop|Limitação de Uso Interno do RFWLogger|
Um dos problemas do modelo atual do '''RFWLogger''' é que ele não pode ser utilizado diretamente nas classes que ele próprio utiliza, como nos métodos do '''[[RFWInterceptor]]''' e do '''[[RFWDAO]]'''. Isso ocorre porque, quando o '''RFWLogger''' tenta persistir os logs no banco de dados, ele gera novos logs sobre essa operação, resultando em um ciclo recursivo de persistência de logs.


Por esse motivo, é recomendado que esses tipos de logs continuem sendo registrados pelo sistema de log em arquivo do servidor de aplicação, evitando o problema de recursão infinita.


= Funcionamento =
Uma solução potencial seria a criação de um DAO exclusivo para o '''RFWLogger''', o que eliminaria o problema ao utilizá-lo com o '''[[RFWDAO]]'''. No entanto, o problema relacionado ao `SessionManager#SMInterceptor` exigiria o desenvolvimento de uma fachada completa apenas para esse propósito. Embora essa solução seja viável, ela ainda não foi implementada. Para saber se o sistema está em modo de desenvolvimento, consulte a classe '''[[RFW]]'''.
}}


O '''RFWLogger''' é uma classe estática utilizada para realizar as chamadas de log. Ele disponibiliza vários métodos no formato '''log...(...)''', que podem ser utilizados em todo sistema para registrar as mensagens a serem logadas.




== Customização ==
=== Múltiplos ClassLoaders da Aplicação ===
O '''RFWLogger''' é uma classe estática que é carregada pelo ClassLoader do módulo onde está localizada. Em uma aplicação J2EE, onde diferentes módulos (como WARs e EJBs) podem ser gerenciados por diferentes ClassLoaders, essa característica pode gerar problemas se não for adequadamente configurada.


O RFWLogger em sua implementação padrão só repassa todas as chamadas de LOG para o console. Mas essa implementação pode, e deve, ser alterada através da através da implementação da interface '''RFWLoggerImplementation'''.
Cada módulo que levanta seu próprio ClassLoader requer uma configuração específica da implementação da interface '''RFWLoggerImplementation'''. Se a implementação personalizada do logger não for configurada em cada um desses ClassLoaders, poderão ocorrer os seguintes problemas:


Ao implementar a interface, ela deve ser repassada para o '''RFWLogger''' através do método '''setImpl(RFWLoggerImplementation)'''. A partir deste ponto todas as chamadas de log feitas no '''RFWLogger''' serão repassadas para implementação fornecida.
* '''Inconsistência nos Logs''': Diferentes módulos da aplicação podem acabar utilizando implementações de log diferentes, resultando em logs que não são centralizados ou que seguem padrões distintos, dificultando a análise e o monitoramento.
* '''Falha na Configuração Customizada''': Se a implementação correta não for configurada em todos os módulos, alguns módulos podem continuar usando a implementação padrão do '''RFWLogger''', o que pode não atender aos requisitos específicos da aplicação (como gravar logs em arquivos específicos ou sistemas de monitoramento).


Desta forma temos a chamada de log sempre centralizada, podendo ser alterada para qualquer ferramenta de log desejada.
Para evitar esses problemas, é crucial garantir que a implementação do '''RFWLogger''' seja corretamente configurada em cada módulo da aplicação J2EE, assegurando uma experiência de logging consistente em todo o sistema.


== Referências e Links ==


 
=== Referência a Outros Componentes ===
== Utilização ==
* '''[[RFWBundle]]''': Classe utilizada para obter mensagens de erro e outras informações internacionalizadas no sistema. É frequentemente usada em conjunto com o '''RFWLogger''' para registrar logs localizados.
 
* '''[[RFWValidationException]]''': Exceção específica para erros de validação, registrada com a severidade `VALIDATION` no '''RFWLogger'''.
Depois de definida a implementação dentro do '''RFWLogger''', utilize os métodos de '''log''' da classe RFWLogger para registrar o necessário.
* '''[[RFWValidationGroupException]]''': Exceção que agrupa múltiplos erros de validação, também registrada com a severidade `VALIDATION`.
 
* '''[[RUReflex]]''': Classe utilizada para refletir e imprimir o estado de objetos no log, particularmente útil para o método `logObject` do '''RFWLogger'''.
= Informações do RFWLogger antigo aguardando revisão =
 
 
 
 
{{stop|Log Recursivo Na Persistência|Um dos problemas do modelo do '''RFWLogger''' é que ele não permite que o '''RFWLogger''' seja utilizado nas classes que ele mesmo utiliza. Como no caso dos métodos do [[RFWInterceptor]] e do [[RFWDAO]]. Isso porque toda vez que o '''RFWLogger''' persistir os logs no banco, gerará novos Logs sobre a persistência, e assim por diante. Estes tipos de logs é recomendado continuar a utilizar o sistema de log em arquivo do servidor de aplicação.
 
É possível escrever um DAO exclusivo para o '''RFWLogger''', eliminando o problema no [[RFWDAO]], já o problema do [[SessionManager#SMInterceptor]] necessitaria uma fachada completa só para esse fim. Nada difícil ou impossível, mas não implementado por enquanto. Consulte a classe [[RFW]]para saber como obter se está ou não em modo desenvolvimento. }}
 
 
O '''RFWLogger''' se integra com a aplicação permitindo que tudo seja registrado de forma a facilitar o debug e relatórios para o desenvolvedor. Como por exemplo, podem ser inclusos no log informações de sessão - quando essas informações ocorrem dentro de uma sessão de usuário - permitindo um filtro dos logs da sessão e obtendo o passo a passo somente daquele usuário.
 
 
= Estrutura do Objeto de Log =
 
Cada evento de Log é um objeto diferente, um '''RFWLogEntry'''. Esse objeto tem dois campos diferentes para salvar mensagens: '''''message''''' e '''''content'''''. A diferença entre eles é que '''''message''''' sempre carrega a informação que o usuário passou no método de .log*(), enquanto que '''''content''''' são informações maiores, como o print de um objeto, um XML, o Stack do método que chamou o log (dependendo da Severidade não é colocado).
 
 
= Tags =
 
O '''RFWLogEntry''' tem ainda um conjunto de Tags. Essas tags podem ser passadas pelo desenvolvedor durante a chamada do método .log*() para identificar os registros (permitindo filtros posteriores). Algumas tags são definidas automaticamente pelo próprio '''RFWLogger'''. As tags automáticas são:
* Caso estejamos utilizando o [[RFWSessions]] para controlar a sessão de autenticação, o label do usuário é colocado como tag;
* Caso tenha sido inicializado no [[RFW]], o nome da aplicação também é colocado como uma tag;
 
= Funcionamento =
 
O '''RFWLogger''' é uma classe estática e pode ser usada a qualquer momento. Todas as chamadas aos métodos '''.log*()''' criam entradas de log automaticamente que ficam armazenadas em uma lista dentro do próprio '''RFWLogger'''.
 
O módulo não persiste nem salva seus logs em nenhum lugar além da memória. O sistema deve implementar e inicializar uma Thread que consume os logs, persistindo-os onde achar melhor (banco de dados, arquivos, etc.) o mais rápido possível para evitar o consumo da memória, e ao mesmo tempo cuidando para que esse evento não gere problemas de performance.
 
Em resumo o '''RFWLogger''' oferece uma simples ferramenta para abstrair a maneira de realizar logs em todo o sistema e deixar que o sistema implemente como fará a persistência e análise dessas informações.
 
 
== Configuração ==
 
Por ser uma classe estática, ela tende a funcionar de forma uniforme pelo sistema inteiro. Porém, é preciso tomar cuidado com o escopo criado pela JVM. Dependendo do servidor de aplicações, as instâncias antes e depois da fachada podem ou não compartilhar os mesmos objetos estáticos em memória. Em casos de termos ambientes isolados, é necessário instanciar e o '''RFWLogger''' em todos os escopos.
 
A classe contém alguns atributos estáticos que ajudam a configurar o módulo:
* '''timeToLive''' - define o tempo em segundos máximo que um log será mantido em memória esperando ser consumido. Caso um registro ultrapasse esse tempo de vida ele será automaticamente descartado para que não tenhamos um estouro de memória. Esse tempo deve ser maior que o tempo definido na Thread de consumo e persistência desenvolvida pela aplicação.
* '''timeToClean''' - define o tempo em segundos que a Thread interna do '''RFWLogger''' é chamada para verificar a existência de logs antigos
 
=== CleannerThread ===
 
O módulo possui uma Thread Daemon de limpeza automática dos logs em memória. Ela funciona como um backup para o caso da thread de consumo falhar. Ela se baseia nos parâmetros '''timeToLive''' e '''timeToClean'''.
 
Note que esta é uma Thread de "safe", caso a aplicação não consuma e persista os logs corretamente. A aplicação deve ter uma Thread que consuma os logs, persista-os e já os remova do '''RFWLogger'''.
 
 
=== Thread de Consumo e Persistência ===
 
A thread de consumo deve ser implementada conforme especificações do sistema. Ela deve chamar o método '''''getEntriesList()''''' para obter todos os objetos de registro. Após registrar, ela deve passar a mesma lista para o método '''''removeEntries()''''' para remover os registros do '''RFWLogger'''. Inicialmente a operação foi desenvolvida em dois passas para que em caso de falha da Thread, os objetos não sejam perdidos. Caso a opção seja trabalhar no sistema "best effort", é possível utilizar o método '''''popEntriesList()''''' que obtém a lista e já os remove do módulo.
 
 
{{stop|Logs da Thread de Consumo|Atenção para os logs realizados dentro desta thread, inclusive dentro dos métodos que ela invoca, pois caso ela crie mais registros dentro do '''RFWLogger''' o sistema estará retro-alimentando um ciclo que não só não para como pode crescer até o travamento do sistema! }}

Edição atual tal como às 01h46min de 4 de setembro de 2024

RFWLogger

Introdução

Visão Geral

O RFWLogger é um componente centralizado de logging para o sistema, projetado para gerenciar e registrar eventos, erros, e informações relevantes durante a execução do software. Ele abstrai os detalhes de implementação do processo de log, permitindo que diferentes partes do sistema registrem mensagens de maneira consistente e eficiente. Essa centralização facilita a manutenção, monitoramento e depuração, garantindo que todas as informações críticas sejam capturadas e armazenadas de forma estruturada.

Contexto de Uso

Em qualquer sistema complexo, o registro adequado de eventos é essencial para identificar problemas, entender o comportamento do software e realizar melhorias contínuas. O RFWLogger atende a essa necessidade, oferecendo uma interface uniforme para o registro de logs em diferentes níveis de severidade, como DEBUG, INFO, WARN, ERROR, e EXCEPTION. Ele é amplamente utilizado em todo o sistema para capturar desde mensagens de depuração até exceções críticas, possibilitando uma análise detalhada e rápida resolução de problemas. Além disso, o RFWLogger permite a customização da implementação de logging, adaptando-se às necessidades específicas de cada ambiente ou projeto.


Estrutura do Componente

Classes e Interfaces Envolvidas

O RFWLogger e a interface RFWLoggerImplementation são os componentes centrais do sistema de logging. A seguir, detalhamos o papel de cada um desses elementos:

Classe RFWLogger

A classe RFWLogger é responsável por centralizar todas as operações de log no sistema. Ela oferece métodos estáticos que permitem o registro de diferentes tipos de eventos, como erros, avisos, mensagens de depuração, e exceções. Essa classe utiliza uma implementação de RFWLoggerImplementation para realizar o log propriamente dito, o que significa que a lógica de logging pode ser customizada conforme necessário, sem alterar as chamadas de log em outras partes do sistema.

Interface RFWLoggerImplementation

A interface RFWLoggerImplementation define os métodos que uma implementação de logging deve fornecer. Ela inclui métodos para registrar logs com várias severidades (`DEBUG`, `INFO`, `WARN`, `ERROR`, `EXCEPTION`, etc.), bem como para logar exceções e objetos. A interface permite que diferentes implementações sejam utilizadas, dependendo dos requisitos específicos, como logar em um arquivo, banco de dados, ou serviço externo.

Relacionamento entre RFWLogger e RFWLoggerImplementation

A classe RFWLogger utiliza uma implementação de RFWLoggerImplementation para realizar o registro de logs. Por padrão, RFWLogger usa uma implementação interna simples, que imprime os logs no console. No entanto, essa implementação pode ser substituída dinamicamente utilizando o método `setImpl`, permitindo que o sistema de logging seja adaptado a diferentes ambientes ou necessidades. Esse design flexível permite que o processo de logging seja facilmente customizado, sem exigir mudanças no código que gera os logs.


Métodos da Classe RFWLogger

Log de Erros (logError)

O método `logError` é utilizado para registrar mensagens de erro com a maior prioridade. Ele pode ser chamado com uma simples mensagem ou com um conjunto de tags para categorizar o erro. Este método é essencial para capturar falhas que necessitam de atenção imediata.

RFWLogger.logError("Erro crítico ao processar a requisição");
RFWLogger.logError("Erro na conexão com o banco de dados", "CONEXAO", "BANCO_DE_DADOS");

Log de Exceções (logException)

O método `logException` permite registrar exceções que ocorrem no sistema. Ele converte a exceção em uma string detalhada, incluindo o stack trace, e a loga com a severidade apropriada. Se a exceção for do tipo RFWValidationException ou RFWValidationGroupException, ela é registrada com a severidade `VALIDATION`.

try {
    // código que pode lançar uma exceção
} catch (Exception e) {
    RFWLogger.logException(e);
}

Esse método também pode aceitar tags para categorizar a exceção:

RFWLogger.logException(e, "VALIDACAO", "ENTRADA_DE_DADOS");

Log de Avisos (logWarn)

O método `logWarn` é usado para registrar mensagens de aviso. Essas mensagens indicam potenciais problemas que não interrompem a execução, mas que podem necessitar de atenção. Assim como outros métodos, ele pode aceitar tags para categorizar os avisos.

RFWLogger.logWarn("Memória disponível baixa");
RFWLogger.logWarn("Uso de API obsoleta", "API", "DEPRECADO");

Log de Objetos (logObject)

O método `logObject` permite registrar o estado de um objeto. Ele utiliza o método `RUReflex.printObject` para gerar uma representação do objeto, que é então anexada ao log. Este método é útil para depuração, permitindo visualizar o conteúdo de objetos complexos.

MyObject obj = new MyObject();
RFWLogger.logObject("Estado do objeto", obj);

Log de Depuração (logDebug)

O método `logDebug` é utilizado para registrar mensagens de depuração. Essas mensagens são úteis durante o desenvolvimento e teste do sistema, permitindo acompanhar o fluxo de execução e o estado das variáveis.

RFWLogger.logDebug("Entrando no método processarPedido");

Log de Informações (logInfo)

O método `logInfo` é usado para registrar informações gerais sobre a operação do sistema. Essas mensagens não indicam erros ou problemas, mas são úteis para monitorar o comportamento normal do sistema.

RFWLogger.logInfo("Início do processamento de batch diário");

Log de Melhorias (logImprovement)

O método `logImprovement` é projetado para registrar sugestões de melhorias no código. Essas mensagens podem ser usadas para documentar áreas do código que podem ser otimizadas ou revisadas no futuro.

RFWLogger.logImprovement("Considerar uso de pool de conexões para otimizar desempenho");


Métodos da Interface RFWLoggerImplementation

Severidades do Log (RFWLogSeverity)

A interface RFWLoggerImplementation define uma enumeração interna chamada RFWLogSeverity, que especifica os diferentes níveis de severidade dos logs. Cada nível de severidade indica a importância ou o tipo de evento que está sendo registrado:

  • OBJECT: Usado para registrar o estado de objetos. Ideal para logs detalhados que imprimem a estrutura e valores de um objeto específico.
  • DEBUG: Indica mensagens de depuração. Essas mensagens são voltadas para desenvolvedores e são usadas durante o desenvolvimento e teste.
  • INFO: Usado para registrar informações gerais sobre o funcionamento do sistema, sem indicar erros ou problemas.
  • WARN: Indica avisos sobre potenciais problemas que não interrompem o funcionamento, mas que podem requerer atenção.
  • ERROR: Usado para registrar erros que afetam o funcionamento do sistema e que necessitam de intervenção.
  • DEV: Específico para mensagens voltadas aos desenvolvedores, como sugestões de melhorias ou notas sobre o código.
  • VALIDATION: Indica uma exceção relacionada a validação de dados ou regras de negócio.
  • EXCEPTION: Usado para registrar exceções que ocorrem durante a execução do sistema.

Implementação Padrão e Customização

A interface RFWLoggerImplementation define os métodos que uma implementação de logger deve fornecer. A implementação padrão usada pelo RFWLogger simplesmente imprime logs no console. No entanto, é possível criar implementações personalizadas para, por exemplo, gravar logs em arquivos, enviar logs para um sistema de monitoramento, banco de dados ou conforme necessário.

public class CustomFileLogger implements RFWLoggerImplementation {
    @Override
    public void log(RFWLogSeverity severity, String msg, String content, String exPoint, String... tags) {
        // Lógica para tratar o log conforme desejado.
    }
}

Para usar uma implementação personalizada, basta configurar o RFWLogger para utilizar a nova implementação:

RFWLogger.setImpl(new CustomFileLogger());

Exemplos de Implementações

Aqui estão alguns exemplos de como você pode implementar a interface RFWLoggerImplementation para diferentes cenários:

  • Logger para Arquivo: Uma implementação que grava os logs em arquivos locais, útil para auditoria ou diagnóstico offline.
  • Logger para Banco de Dados: Uma implementação que registra os logs em um banco de dados, permitindo consultas e análises posteriores.
  • Logger para Sistema de Monitoramento: Uma implementação que envia logs para um serviço de monitoramento em tempo real, como o ELK Stack ou Splunk.

Configuração e Extensibilidade

Como Substituir a Implementação Padrão

O RFWLogger permite que você substitua a implementação padrão de logging por uma personalizada, oferecendo flexibilidade para adaptar o sistema às suas necessidades específicas. Para substituir a implementação, utilize o método `setImpl` e forneça uma instância da nova implementação que segue a interface RFWLoggerImplementation.

Exemplo:

public class CustomFileLogger implements RFWLoggerImplementation {
    @Override
    public void log(RFWLogSeverity severity, String msg, String content, String exPoint, String... tags) {
        // Lógica para gravar o log em um arquivo
    }
}

// Substituindo a implementação padrão pelo CustomFileLogger
RFWLogger.setImpl(new CustomFileLogger());

Essa substituição pode ser feita em tempo de execução, permitindo que você adapte o comportamento do logger conforme o ambiente ou requisitos específicos.

Boas Práticas na Implementação de Logs

Aqui estão algumas recomendações para implementar logs de maneira eficaz:

  • Utilize Níveis de Severidade Apropriados: Escolha o nível de severidade que melhor se aplica ao evento sendo registrado. Use `DEBUG` para mensagens detalhadas de desenvolvimento, `INFO` para informações operacionais, `WARN` para potenciais problemas, `ERROR` para falhas críticas, e `EXCEPTION` para capturar exceções.
  • Evite o Uso Excessivo de Tags: As tags devem ser usadas para categorizar logs de forma a facilitar a filtragem e análise. Evite incluir informações que só aparecerão em um único evento, preferindo criar entradas específicas de `INFO` ou `DEBUG` para dados voláteis.
  • Mantenha Mensagens de Log Claras e Objetivas: Certifique-se de que as mensagens de log sejam claras e expliquem o contexto do evento registrado. Isso facilita a análise posterior e a compreensão dos logs por outros desenvolvedores.
  • Inclua Informações Relevantes: Sempre que possível, inclua informações adicionais, como o estado do sistema ou de objetos, para ajudar na depuração e análise de problemas.

Personalização do Comportamento do Logger

O RFWLogger é altamente configurável e pode ser adaptado para diferentes cenários:

  • Alteração Dinâmica da Implementação: Você pode trocar a implementação de logging em tempo de execução conforme necessário, o que é útil em ambientes de desenvolvimento e produção com diferentes requisitos de logging.
  • Integração com Sistemas de Monitoramento: Considerando a arquitetura modular do RFWLogger, é possível integrar o logger com sistemas de monitoramento externos, como Splunk, ELK Stack, ou outras ferramentas de observabilidade. Isso pode ser feito implementando uma nova versão da interface RFWLoggerImplementation que envia os logs para esses serviços.
  • Customização de Formatos de Log: Dependendo da implementação escolhida, você pode personalizar o formato das mensagens de log para incluir timestamps, IDs de correlação, ou outras metainformações relevantes para a análise e rastreamento de problemas.

Exemplos Práticos

Cenários Comuns de Uso

Nesta seção, apresentamos exemplos de como o RFWLogger pode ser utilizado em situações reais do sistema, ajudando a entender melhor a aplicação prática dos métodos de logging.

Exemplo 1: Registro de Erros Críticos

try {
    // Código que pode lançar uma exceção
} catch (Exception e) {
    RFWLogger.logError("Erro ao processar a transação", "TRANSAÇÃO", "ERRO");
    RFWLogger.logException(e);
}

Neste exemplo, um erro crítico durante o processamento de uma transação é registrado, juntamente com a exceção detalhada que causou o erro.

Exemplo 2: Registro de Avisos de Baixa Severidade

if (memoriaDisponivel < LIMITE_MINIMO) {
    RFWLogger.logWarn("Memória disponível abaixo do limite recomendado", "MEMÓRIA", "RECURSOS");
}

Aqui, um aviso é registrado quando a memória disponível cai abaixo de um limite seguro. Isso permite monitorar a saúde do sistema e tomar ações preventivas.

Exemplo 3: Registro de Informações Gerais

RFWLogger.logInfo("Início do processamento de pedidos noturnos");

Este exemplo demonstra o uso do log de informações para registrar eventos normais do sistema, como o início de um processamento em lote.

Exemplo 4: Logando o Estado de um Objeto para Depuração

Pedido pedido = new Pedido();
RFWLogger.logObject("Estado do pedido antes do processamento", pedido, "DEPURAÇÃO", "PEDIDO");

Este exemplo mostra como o RFWLogger pode ser usado para registrar o estado de um objeto antes de uma operação crítica, facilitando a depuração se algo der errado.

Depuração e Análise

A utilização eficaz do RFWLogger permite uma análise detalhada dos eventos registrados no sistema. Aqui estão algumas dicas para usar os logs na depuração e monitoramento:

  • Identificação de Problemas Recorrentes: Ao analisar os logs, preste atenção em mensagens de erro e exceção que se repetem, indicando problemas que precisam de correção.
  • Monitoramento de Recursos: Use logs de aviso para monitorar o uso de recursos como memória e CPU, e identificar possíveis gargalos antes que causem falhas no sistema.
  • Rastreamento de Fluxo de Execução: Utilize logs de depuração para acompanhar o fluxo de execução do sistema, especialmente em operações complexas que envolvem várias etapas ou componentes.
  • Análise Pós-Morte: Após uma falha, os logs são a principal ferramenta para entender o que ocorreu. Certifique-se de que as mensagens de log incluam todas as informações relevantes, como parâmetros de entrada e o estado do sistema.

Esses exemplos e dicas mostram como o RFWLogger pode ser integrado no fluxo de trabalho diário para melhorar a monitorização, a depuração e a manutenção do sistema.

Limitações Conhecidas

Uso Cíclico do RFWLogger

Stop 256.png
Limitação de Uso Interno do RFWLogger

Um dos problemas do modelo atual do RFWLogger é que ele não pode ser utilizado diretamente nas classes que ele próprio utiliza, como nos métodos do RFWInterceptor e do RFWDAO. Isso ocorre porque, quando o RFWLogger tenta persistir os logs no banco de dados, ele gera novos logs sobre essa operação, resultando em um ciclo recursivo de persistência de logs.

Por esse motivo, é recomendado que esses tipos de logs continuem sendo registrados pelo sistema de log em arquivo do servidor de aplicação, evitando o problema de recursão infinita.

Uma solução potencial seria a criação de um DAO exclusivo para o RFWLogger, o que eliminaria o problema ao utilizá-lo com o RFWDAO. No entanto, o problema relacionado ao `SessionManager#SMInterceptor` exigiria o desenvolvimento de uma fachada completa apenas para esse propósito. Embora essa solução seja viável, ela ainda não foi implementada. Para saber se o sistema está em modo de desenvolvimento, consulte a classe RFW.


Múltiplos ClassLoaders da Aplicação

O RFWLogger é uma classe estática que é carregada pelo ClassLoader do módulo onde está localizada. Em uma aplicação J2EE, onde diferentes módulos (como WARs e EJBs) podem ser gerenciados por diferentes ClassLoaders, essa característica pode gerar problemas se não for adequadamente configurada.

Cada módulo que levanta seu próprio ClassLoader requer uma configuração específica da implementação da interface RFWLoggerImplementation. Se a implementação personalizada do logger não for configurada em cada um desses ClassLoaders, poderão ocorrer os seguintes problemas:

  • Inconsistência nos Logs: Diferentes módulos da aplicação podem acabar utilizando implementações de log diferentes, resultando em logs que não são centralizados ou que seguem padrões distintos, dificultando a análise e o monitoramento.
  • Falha na Configuração Customizada: Se a implementação correta não for configurada em todos os módulos, alguns módulos podem continuar usando a implementação padrão do RFWLogger, o que pode não atender aos requisitos específicos da aplicação (como gravar logs em arquivos específicos ou sistemas de monitoramento).

Para evitar esses problemas, é crucial garantir que a implementação do RFWLogger seja corretamente configurada em cada módulo da aplicação J2EE, assegurando uma experiência de logging consistente em todo o sistema.

Referências e Links

Referência a Outros Componentes

  • RFWBundle: Classe utilizada para obter mensagens de erro e outras informações internacionalizadas no sistema. É frequentemente usada em conjunto com o RFWLogger para registrar logs localizados.
  • RFWValidationException: Exceção específica para erros de validação, registrada com a severidade `VALIDATION` no RFWLogger.
  • RFWValidationGroupException: Exceção que agrupa múltiplos erros de validação, também registrada com a severidade `VALIDATION`.
  • RUReflex: Classe utilizada para refletir e imprimir o estado de objetos no log, particularmente útil para o método `logObject` do RFWLogger.