Gerando logs em JSON com log4net

code

Recentemente, minha equipe ficou a cargo de um sistema legado escrito em .NET Framework. Um dos grandes problema deste legado, é que não tínhamos nenhuma visibilidade do que ocorria no sistema.

Uma das formas de resolver este problema, era enviar logs do sistema ao Kibana (plugin de visualização de dados para o Elasticsearch), que foi a opção que escolhemos.

Enviar logs no formato “standard” ao Kibana, complicava a criação de gráficos mais complexos no Grafana (aplicação web com visualização interativa de tabelas, gráficos e alertas). Daí surgiu a necessidade de gerar logs no formato JSON.

Para gerar logs no formato JSON, necessitamos criar um novo layout e formatar o saída no formato desejado.

Nossa classe terá o nome de JsonLayout e deve extender LayoutSkeleton (do namespace log4net.Layout). A classe LayoutSkeleton implementa duas interfaces (ILayout e IOptionHandler), por isso devemos implementar os métodos: ActivateOptions e Format.

Já temos a nossa classe criada, necessitamos implementar nossa formatação customizada no método Format.

Nesse exemplo, vamos imprimir no log os campos:

  • messageObject (que passamos como parámetro ao logear)
  • requestId
  • pid
  • timestamp
  • level
  • logger
  • location
  • thread
  • exceptionObject (exception que passamos como parámetro ao logear um erro)
  • exceptionObjectString

Assim ficou a nossa classe:

Agora só falta referenciar nossa classe JsonLayout no arquivo log4net.config:

<configuration>
  <log4net>
    <appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender,log4net">
      ...
      <layout type="MyNamespace.JsonLayout">
      </layout>
    </appender>
    ...
  </log4net>
</configuration>

Escrevemos um log na nossa aplicação:

E voilà:

{
  "messageObject": {
    "message": "new log message",
    "field": "some data"
  },
  "requestId": "9e20b1b3-9064-4ebf-9d84-6662c7673324",
  "pid": 25829,
  "timestamp": "2020-12-17T00:16:15.0696380Z",
  "level": "INFO",
  "logger": "Log4netOutputJson.Program",
  "location": "Log4netOutputJson.Program",
  "thread": "1",
  "exceptionObject": null,
  "exceptionObjectString": null
}

O projeto de exemplo está hospedado no GitHub: https://github.com/victorlss/log4net-output-json

Audit Trail com Entity Framework Core

Uma Trilha de Auditoria (também chamada de Log de Auditoria) é uma das maneiras mais eficazes de rastrear as ações dos usuários, fornecendo evidências de uma sequência de atividades que afetam informações, processos etc.

Usando o Entity Framework Core, podemos facilmente auditar as alterações, sobrescrevendo o método SaveChanges ().

Vamos ao que interessa

Defina a classe context e as classes de entidade que conformam seu modelo:

Agora, devemos definir uma classe context auditável e o modelo AuditTrail:

Com os comandos de migração EF, criamos nossa base de dados e suas tabelas:

dotnet ef migrations add InitialCreate --context BloggingContext
dotnet ef database update --context BloggingContext

Vamos aos testes

Adicionaremos dados a nossa tabela Blog:

INSERT INTO [Blogging].[dbo].[Blogs] (Url) 
VALUES ('blog.victorleonardo.com');

Agora, devemos efetuar uma atualização ao registro que acabamos de inserir, utilizando nossa classe context auditável:

Voilà:

This image has an empty alt attribute; its file name is Screen-Shot-2019-04-28-at-4.41.21-PM.png