Log transacional

O log transacional do sistema é implementado por meio da tabela iLog. Essa tabela armazena todas as alterações (Log) realizadas pelos usuários na base de dados. Essa tabela é atualizada pelo método ApplyUpdates e nela são registrados os valores anteriores e posteriores de todas as alterações realizadas pelos usuários.

Com todas essas informações é possível fazer um processo de auditoria no sistema com o objetivo de identificar o que foi feito e quando foi feito. Quando há erro de dados em um registro, geralmente se olha o log transacional para verificar toda a “vida” daquele registro na base de dados.

Tipos de log

As classes de log estão presentes na tabela iAuxiliaryTable, tendo como classe “Tipos de Log” (-1898145949).

Existem classes para as mais diversas operações, exemplo: bloqueio de usuário, registro alterado, registro removido, etc. Com isso, é possível identificar que tipo de operação foi realizada em uma determinada versão.

Se o usuário inseriu um registro, esse registro terá uma versão e estará na iLog com o tipo registro inserido.

Desfazer alterações

No processo de desfazer alterações, é possível voltar um registro para os valores antes de uma determinada alteração. Por exemplo: alguém alterou o CPF da pessoa João (000.000.000-00) para 111.111.111-11. Pelo processo de desfazer log é possível voltar ao valor anterior, ou seja, João volta a ter o CPF 000.000.000-00, pois o estado do registro é retornado ao que era antes da alteração.

  • Acesse o processo “Admin > Auditoria > Desfazer ou Refazer Alterações”;
  • Insira os parâmetros para pesquisa de uma alteração. Por padrão é sempre utilizado a versão para voltar ao estado anterior;
  • Selecione os registros que deseja alterar e depois clique em gravar.

Observação: esse processo é extremamente perigoso e pode comprometer a integridade dos dados, uma vez que ele permite o desfazimento parcial de operações. Referências também podem ficar órfãs quando a inserção de registros é desfeita. O uso desse processo sempre deve ser orientado por um desenvolvedor a fim de avaliar o impacto da reversão das alterações.

Auditoria através da iLog

Realizar auditoria em um registro é bem simples e irá informar todas as alterações realizadas no registro, desde sua criação. Informando também quem fez alteração, quando e qual foi a alteração. Para realizar a auditoria, pelo browser, basta ir no registro que se deseja verificar e clicar no botão “Histórico de alterações do registro” presente na grade. Com isso, haverá um redirecionamento para um relatório que informará todas as alterações do registro.

Outra forma de verificar as alterações é através do relatório “Admin > Auditoria > Consultar alterações”.

Limpeza de dados

Após alguns anos de uso do sistema, poderá ser necessário diminuir o tamanho da tabela iLog, pois, dada a sua natureza de registrar todas as alterações do sistema, o tamanho dela tenderá a ser maior que a soma de todos os dados das demais tabelas. Para diminuir o seu tamanho, devem ser apagados os registros de log transacionais antigos e que não são mais relevantes para fins de auditoria.

Para cada classe de dados do sistema, pode ser configurado o tempo de retenção do log transacional. Essa configuração deve ser realizada em um arquivo x-model ou x-class de uma classe de dados por meio da propriedade transactionLogMaxDays. Caso ela não seja definida em uma classe, será utilizado o valor de sua classe-mãe. Isso ocorrerá recursivamente até que se encontre uma classe que defina a propriedade. As configurações definidas para as classes de dados podem ser visualizadas no processo “Admin > Auditoria > Limpar tabela de log”.

É recomendada a criação de uma automação de limpeza diária do log transacional. Essa automação pode ser feita via agendador de scripts, por meio do processo “Admin > Agendador de scripts”. Esse agendamento deve ser realizado preferencialmente no servidor de aplicação, com as seguintes configurações:

  • Nome: Limpeza da tabela de log transacional
  • Período: Diário
  • Hora: 00:00
  • Script VFS: Clear TransactionLog.js

Ao preencher o campo “Script VFS” com “Clear TransactionLog.js”, o campo “Script URI” deverá ser preenchido automaticamente com “vfs:ikey?-1898146458”. O campo “Script VFS” também pode ser preenchido com a chave “-1898146458” em vez do nome do arquivo.

É recomendado que a limpeza do log transacional ocorra em um horário de baixa utilização da base de dados, portanto a execução diária à meia-noite sugerida pode ser alterada para um outro horário ou até ter uma periodicidade menor, como semanal, de acordo com o contexto de utilização da base de dados.

Outra possibilidade seria comandar a automação a partir de outro sistema, utilizando a rota POST /api/devops/v1/transaction-log/clear.

O usuário utilizado para criar o agendamento ou o token de acesso para consumo da API precisa ter permissão ao escopo de autorização system.clearTransactionLog. Usuários do grupo “Administrators” possuem esse escopo por padrão.

Por último, também é possível efetuar a limpeza manualmente através do processo “Admin > Auditoria > Limpar tabela de log”. No entanto, a limpeza periódica e automatizada garante que não será acumulado um volume excessivo de log transacional a ser limpo, reduzindo o tamanho e a duração das transações relacionadas à limpeza dos dados.

Importante: os logs transacionais são utilizados para sincronizar os dados do cache local, portanto nunca deve ser configurada uma retenção de log transacional inferior à 90 dias para as classes de dados que são armazenadas no cache. Pelo mesmo motivo, a tabela iLog sempre deve ser limpa utilizando as alternativas apresentadas acima, garantindo que a retenção configurada seja respeitada. A limpeza completa da tabela iLog provoca a perda da integridade dos dados do cache local e, caso isso ocorra, deve ser executado o processo “Admin > Cache local > Descartar o cache de dados e de chaves” a fim de forçar a reconstrução dos caches.

iTag

O conceito de iTag resume-se a uma forma de agrupar alterações na tabela iLog. Com ela, é possível marcar dados a serem removidos posteriormente. Desta forma, em casos de teste, por exemplo, é possível criar e gravar dados em nossa estrutura de dados e, após terminados os testes, pode-se desfazer todas as alterações que foram realizadas e registradas sob uma iTag. Podemos então dividir o uso de iTags em dois momentos: gravação de alterações utilizando iTag; desfazimento de alterações marcadas com a iTag do primeiro momento. Vejamos como realizar estes dois momentos.

Gravando alterações com iTag

O applyUpdates do objeto Database considera a existência de uma iTag. Assim, para marcar as alterações realizadas com uma iTag deve-se alterar a propriedade changeLogTag de um objeto Database com uma tag única (recomenda-se o uso de GUID). Feito isto, todas as chamadas do método applyUpdates deste objeto gravarão as alterações na iLog preenchendo o campo iTag da iLog. Uma vez gravadas as alterações na iLog com o campo iTag preenchido, essas alterações poderão ser desfeitas mais facilmente em um segundo momento.

Exemplo:

let db, ds;

db = new Database('localhost:80','minhaBase');
db.login('usuario','senha');
db.changeLogTag = ngin.util.createGUID(false);

ds = database.query("SELECT * FROM ivfs WHERE iKey IN (-1111111,-222222,-333333)");

tratamento1(ds); // método fictício que abstrai a manipulação e alteração dos dados do dataset.
db.applyUpdates([ds]);

tratamento2(ds);
db.applyUpdates([ds]);
// método fictício que abstrai a manipulação e alteração dos dados do dataset.

No exemplo acima, na linha 5, temos a iTag sendo gerada e configurada no Database. As alterações realizadas nos métodos de tratamento 1 e 2, e gravados nos applyUpdates consequentes, são gravadas na iLog com a iTag configurada na linha 5.

Desfazendo alterações com iTag

Uma vez de posse da iTag que marcou as alterações gravadas na iLog, pode-se reverter as alterações facilmente com o método ngin.db.undoLogByTag(iTag).

Exemplo:

__includeOnce('ufs:/ngin/db.js');

const iTag = recuperaITag() // método fictício que abstrair a persistência de uma iTag.
const undoVersions = ngin.db.undoLogByTag(iTag);

O exemplo acima desfaz todas as versões de alteração contidas na iLog com a tag informada no parâmetro do método undoLogByTag.