Ir para o conteúdo principal

Estudo do sistema de Logs no sistema Consignação


Data de elaboração 09/05/2023
Responsável pelo estudo
  1. Emanuel Rufino Alcantara de Lima (Analista)
Equipe do estudo
  1. André Honório de Andrade Silva (Tecnico)
  2. Gezinéia Paula da Costa (Product Owner)
  3. Gustavo Felix (Analista)
  4. Rafael Passos dos Santos (Assessor)
  5. Alef Carvalho (Analista)
  6. Gustavo Felix (Analista)
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.

Foi verificado que os seguintes campos estão presentes:

  1. COD_LOG: campo número auto incrementado identificador do registro na tabela.
  2. DAT_LOG: Data de registro do log.
  3. DES_OPERACAO: campo que identifica qual tipo de operação realizada na entidade.
  4. DES_TABELA: Nome da tabela que está sofrendo a operação.
  5. DES_LOG: log em json gerado que mostra os dados do registro que estão sendo modificados.
  6. GID_APLICACAO: Código único do sistema pertencente àquele log.

image.png

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.

image.png

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:

  1. 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.
  2. 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.)

image.png

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:

  1. Criar os campos: IP, CPF/CNPJ na tabela LogRegistrador.
  2. Adicionar esses campos no construtor da classe LogRegistrador.
  3. 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

  1. Ao contrário do estudo anterior, 
  2. Esta será a primeira alteração do banco de dados feita pelo time em projetos JAVA.
  3. 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
Adicionar informações adicionais no log ? Caso seja necessária alguma informação a mais no log 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.