Estudo do sistema de Logs no sistema Consignação
Data de elaboração | 09/05/2023 |
---|---|
Responsável pelo estudo |
|
Equipe do estudo |
|
Alvo | Consignação |
Origem |
Implementação: Estudo do sistema de Logs no sistema Consignação |
Objetivo |
O presente estudo visa analisar como está sendo criado os logs do sistema Consignação. Dessa forma, utilizá-lo para adequar as necessidades de auditoria. |
Documentação correlata | |
Observações | O presente estudo pretende também pretende levantar as Historias dos cards para a Sprint |
1. Objetivo
O presente estudo visa analisar como está sendo criado os logs do sistema Consignação. Dessa forma, utilizá-lo para adequar as necessidades de auditoria.
1.1 JUSTIFICATIVA
Atualmente existe um sistema de logs no Consignação, porém a equipe Vingadores não tem conhecimento de como esse log é feito, por isso este estudo está sendo realizado.
1.2 RESULTADOS ESPERADOS
Espera-se que, após este estudo, seja possível levantar quais são os esforços necessários para adequar o modo que o log está sendo realizado no sistema Consignação para adequá-lo às necessidades de auditoria.
2. Introdução
O sistema Consignação necessita de mais informações no sistema de logs.
3. Desenvolvimento
3.1 CENÁRIO ATUAL
Para o início do estudo, foi identificada uma base de dados contendo os logs do sistema consignação.
Tabela 1. Tabela de logs com dados anonimizados
Método Salvar na classe TipoDeVerbaServico
Para identificar o funcionamento do log foi utilizado o método Salvar da classe TipoDeVerbaServico. Nessa classe, foi possível identificar o salvamento do log, através da utilização do método registrar, da classe LogServico.
Imagem 2. Exemplo de criação de logs no salvamento do Tipo de Verba
Classe LogServico
A classe LogServico trata das regras de negócio dos logs do sistema. Ela é responsável por registrar logs de operações realizadas em entidades do sistema, através da persistência de objetos do tipo LogJson.
O serviço é composto por dois métodos:
- O método registrar, que recebe como parâmetros uma entidade (que pode ser qualquer objeto do sistema), um funcionário, uma enumeração LogJsonOperacaoEnum, que representa a operação realizada (CREATE, UPDATE ou DELETE) e um guid da aplicação (nesse caso, do sistema consignação). Este método é responsável por recuperar o nome da tabela que representa a entidade passada como parâmetro e chamar um método para realizar o registro do log.
- O método recuperarEntidadeNome, que recebe como parâmetro uma entidade e é responsável por recuperar o nome da tabela que representa a entidade, a partir do uso da anotação @Table na classe da entidade.
Além disso, a classe LogServico possui uma classe interna chamada LogRegistrador, que implementa a interface Runnable. Essa classe é responsável por construir o objeto LogJson com as informações necessárias para ser persistido no banco de dados.
Classe LogRegistrador
A classe LogRegistrador implementa a interface Runnable e é responsável por registrar operações de log em uma entidade, ou objeto, em um banco de dados.
O construtor da classe recebe uma instância de ILogJsonRepositorio que é uma interface para acesso ao banco de dados onde serão salvos os logs, um objeto que representa a entidade que sofrerá o log, um valor do tipo LogJsonOperacaoEnum que representa a operação que está sendo realizada (como criar, atualizar ou excluir a entidade), o nome da tabela em que a entidade está armazenada, o GID (identificador global) da aplicação que está realizando a operação, e o nome do funcionário responsável pela operação.
A classe também possui um método run() que é chamado quando a classe é executada em uma thread. Esse método realiza a validação dos campos obrigatórios da entidade e, caso todos os campos estejam preenchidos, cria uma string JSON que representa a entidade usando a biblioteca ObjectMapper, do Jackson, e a salva no banco de dados através da instância de ILogJsonRepositorio. Caso algum erro ocorra durante a execução, uma mensagem de erro é exibida no log da aplicação.
A classe LogServico possui também quatro classes internas que implementam as interfaces JsonSerializer e JsonDeserializer. Essas classes são utilizadas pelo ObjectMapper para serializar e deserializar os objetos do tipo LocalDateTime e LocalDate. Isso é necessário para que os valores desses campos sejam corretamente armazenados e recuperados no banco de dados.
Interface LogJsonRepositorio
A interface LogRepositorio é utilizada na persistência das informações no banco de dados. Ela é decorada com @Repository a qual permite utilizar os métodos padrões de CRUD (save, saveAll, exists, findAll, findById, deleteById, deleteAll, count, etc.)
Framework SLF4J
O Simple Logging Facade for Java (SLF4J) é um framework de logging para a linguagem de programação Java. O objetivo do SLF4J é fornecer uma API simples e unificada para a criação e o registro de mensagens de log em uma variedade de bibliotecas de logging populares, como Log4j, JDK logging e Logback, com ele o desenvolvedor pode simplesmente escrever código para o SLF4J e o SLF4J lidará com a escolha e a configuração da biblioteca de logging apropriada.
Classe Logger
A classe Logger do pacote org.slf4j é uma interface de registro de eventos que permite que os aplicativos Java gerem mensagens de log em diferentes níveis de gravidade, como TRACE, DEBUG, INFO, WARN e ERROR. A interface Logger fornece métodos para registrar mensagens de log em diferentes níveis de gravidade e incluir informações adicionais, como a origem da mensagem de log.
Classe LoggerFactory
A classe LoggerFactory faz parte do pacote org.slf4j, que é um framework de logging para a linguagem Java. O objetivo do LoggerFactory é fornecer uma instância de logger que pode ser usada para registrar mensagens em um arquivo de log.
Ao criar uma instância da classe Logger, o LoggerFactory é usado para fornecer uma implementação do logger apropriada para a plataforma em que o código está sendo executado. Isso significa que, em vez de criar uma instância do logger diretamente, é melhor criar uma instância usando o LoggerFactory.
A classe LoggerFactory possui vários métodos estáticos para criar instâncias do logger, incluindo:
getLogger(String name): cria uma instância do logger com o nome especificado.
getLogger(Class<?> clazz): cria uma instância do logger para a classe especificada.
Além disso, o LoggerFactory pode ser configurado para usar diferentes implementações do logger, dependendo das necessidades do aplicativo. Por exemplo, é possível configurar o LoggerFactory para usar o Log4j em vez do logger padrão do SLF4J. Isso é feito editando o arquivo de configuração slf4j.properties ou logback.xml para incluir as dependências do Log4j e alterar a configuração do logger padrão.
3.2 SOLUÇÃO
Considerando a análise realizada sobre o funcionamento do registro no sistema de consignação, conseguimos encontrar uma solução viável para a inclusão das informações requisitadas no registro de logs do banco de dados.
De acordo com a solicitação as seguintes informações são necessárias:
- IP
- DATA e HORA
- CPF do Servidor/CNPJ do funcionário
- String
Ter o registro de toda movimentação, registro de quem fez a baixa de averbações manuais, fechamento, acesso ao sistema, qualquer exclusão, criação de cargo, cadastro de servidor(matricula), e verbas.
De acordo com o estudo anterior a respeito dos logs, essas informações podem ser obtidas conforme mencionado no documento.
Para que esses dados sejam persistidos, são necessárias as seguintes ações:
- Criar os campos: IP, CPF/CNPJ na tabela LogRegistrador.
- Adicionar esses campos no construtor da classe LogRegistrador.
- Verificar uma forma genérica de obter esses dados e passar para o construtor. Sugestão: Utilizar a classe AbstractServico e criar os métodos para obter o IP e o CPF/CNPJ, conforme o exemplo abaixo:
public String getIpDoUsuario(){
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
String ip = request.getRemoteAddr();
return ip;
}
Na chamada
String ip = super.getIp();
3.2.1 Considerações e Preocupações
- Ao contrário do estudo anterior,
- Esta será a primeira alteração do banco de dados feita pelo time em projetos JAVA.
- Os novos campos dos registros passados ficarão em branco ou nulos.
3.2 IMPLEMENTAÇÃO E HISTÓRIAS DE USUÁRIOS
O que? | Pontos | Regras | Produto |
Incluir os campos IP, CPF/CNPJ na classe e migrar para o banco de dados | 5 |
- Verificar se o campo cpf/cnpj é necessário, pois já possui o login do usuário na tabela, o que é suficiente para identificar o usuário |
Consignação |
Adicionar os campos no construtor da classe LogRegistrador e incluí-los em cada chamada |
13 |
- No código foi possível identificar 55 chamadas para esse código |
Consignação |
Consignação |
4. Conclusão
Após uma análise cuidadosa sobre o funcionamento do registro no sistema de consignação, conseguimos encontrar uma solução prática e viável para incluir as informações necessárias no registro de logs do banco de dados. A criação dos campos IP e CPF/CNPJ na tabela LogRegistrador e a utilização da classe AbstractServico para obter esses dados de forma genérica são algumas das ações necessárias para garantir a persistência das informações. É importante lembrar que essa será a primeira alteração no banco de dados pelo time em projetos JAVA, e que os registros anteriores ficarão em branco ou nulos nos novos campos criados.