.NET 5 + Serilog: implementando Logs com Elasticsearch, SQLite, …
Flexível e extremamente popular entre Desenvolvedores .NET, o Serilog é uma alternativa open source para logging compatível com diversas tecnologias. Os logs gerados podem ser registrados em arquivos, direcionados para o console, armazenados em bancos relacionais ou NoSQL…
Já abordei inclusive o uso do Serilog nos seguintes artigos:
ASP.NET Core: implementando Logs com Serilog + MongoDB
ASP.NET Core + Serilog: implementando Logs com SQL Server e Azure Table Storage
Neste novo post trago novos exemplos de implementações empregando o Serilog com .NET 5, utilizando para isto o Elasticsearch, o SQLite, o SQL Server, o MongoDB e o Azure Table Storage como meios de armazenamento.
Aplicação em que serão gerados os logs
O exemplo que serviu de base para as diferentes implementações apresentadas neste artigo é uma API REST para cálculo de juros compostos criada com o .NET 5 e o ASP.NET Core.
Na listagem a seguir está a implementação do Controller que define tal API. Partindo da premissa de que o projeto foi devidamente ajustado, o uso da instância de ILogger (recebida via injeção de dependência no construtor) direcionará os logs para o meio de persistência configurado com o Serilog:
Já na imagem seguinte podemos observar esta aplicação sendo acessada a partir do Swagger:
SQL Server, MongoDB e Azure Table Storage
Os artigos mencionados anteriormente fornecem uma visão geral sobre o funcionamento do Serilog em conjunto com o SQL Server, o MongoDB e o Azure Table Storage. Logo, por questões de simplificação, não entrarei em maiores detalhes nestes exemplos.
A seguir estão os links para download de cada implementação:
.NET 5 + ASP.NET Core + REST API + Serilog + SQL Server
.NET 5 + ASP.NET Core + REST API + Serilog + MongoDB
.NET 5 + ASP.NET Core + REST API + Serilog + Azure Table Storage
SQLite
O SQLite é uma alternativa open source e que em um projeto .NET depende apenas da inclusão de uma biblioteca com suporte ao mesmo, dispensando assim a instalação de um mecanismo mais elaborado de persistência. Trata-se de uma opção bastante útil para testes e provas de conceito.
Um banco de dados baseado nesta tecnologia terá a extensão .db, com o arquivo appsettings.json trazendo um exemplo de string de conexão para uso de uma base SQLite:
Para os testes com Serilog fez uso dos packages:
- Serilog.AspNetCore
- Serilog.Sinks.SQLite
Na classe Program estão as configurações para a gravação dos logs com Serilog + SQLite:
- Na chamada WriteTo.SQLite foram indicadas a string de conexão e o nome da tabela que conterá as informações (LogsAPIFinancas);
- A chamada a WriteTo.Console permitirá direcionar os logs também para o console, uma opção útil para monitoramento do que acontece na aplicação;
- Ao acionar o método UseSerilog a utilização do Serilog será ativada.
Na próxima imagem podemos visualizar os logs que foram direcionados para o console (utilizando o Windows Terminal + PowerShell):
É possível ainda consultar o conteúdo do arquivo gerado (log.db na pasta Logs) através da ferramenta gratuita DB Browser for SQLite:
Este exemplo foi disponibilizado no seguinte repositório do GitHub:
Elasticsearch
O Elasticsearch é um mecanismo para armazenamento e busca de dados não estruturados (documentos JSON). Constitui uma alternativa bastante comum para a manipulação de logs no ambiente corporativo, com o seu uso sendo geralmente combinado ao Kibana (este último uma interface para visualização de dados).
Para os testes com o Serilog criei um ambiente baseado no Elasticsearch e no Kibana, empregando para isto o Docker Compose:
Na aplicação de exemplo utilizei desta vez o package Serilog.Sinks.Elasticsearch:
Já no arquivo appsettings.json indiquei a URL para acesso ao Elasticsearch:
A classe Program difere pouco da implementação baseada em SQLite:
- Na chamada a WriteTo.Elasticsearch foi informada uma instância do tipo ElasticsearchSinkOptions (namespace Serilog.Sinks.Elasticsearch), com as configurações para utilização do Serilog com este mecanismo de persistência;
- Dados no Elasticsearch são agrupados sob a forma de um index (algo similar a uma tabela relacional ou coleção em um banco NoSQL orientado a documentos);
- Ao configurar a instância de ElasticsearchSinkOptions foram preenchidas as propriedades AutoRegisterTemplate (para registrar automaticamente um template, estrutura que contém definições sobre como um index será criado), AutoRegisterTemplateVersion (com a versão do Elasticsearch a ser tomada como base, neste caso a 7) e IndexFormat;
- A propriedade IndexFormat conterá o nome do index em que os logs serão agrupados como documentos. Podemos utilizar padrões de data/hora para separar os dados entre diferentes indexes, conforme necessidades de agrupamento de logs específicas de uma aplicação. O valor default para esta propriedade é logstash-{0:yyyy.MM.dd}; alterei a mesma para apifinancas-{0:yyyy.MM}, de forma que os logs sejam agrupados por ano/mês.
Acessando a interface do Kibana na porta 5601 teremos a página inicial desta ferramenta:
Acionar então a funcionalidade Discover em Analytics:
O Kibana indicará a necessidade de criação de um index pattern, a fim de possibilitar a exploração dos dados:
Após clicar na opção Create index pattern preencher em Index pattern name o valor apifinancas-*:
Acionando o botão Next step selecionar @timestamp em Time field, concluindo a criação do index pattern com um clique no botão Create index pattern:
A tela a seguir indica que o index pattern foi criado com sucesso:
Acessando novamente Discover em Analytics uma visualização com os logs será exibida:
Acessando novamente Discover em Analytics uma visualização com os logs será exibida:
Podemos filtrar por informações sobre erros (level: Error), por exemplo:
Esse projeto também está no GitHub:
Referências
Serilog: simple .NET logging with fully-structured events
serilog/serilog-aspnetcore: Serilog integration for ASP.NET Core
serilog/serilog-sinks-elasticsearch: A Serilog sink that writes events to Elasticsearch
serilog-sinks-sqlite: A Serilog sink that writes to SQLite
serilog-sinks-mssqlserver: A Serilog sink that writes events to Microsoft SQL Server
serilog/serilog-sinks-mongodb: A sink for Serilog that writes events to MongoDB
serilog/serilog-sinks-azuretablestorage: A Serilog sink that writes events to Azure Table Storage