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