.NET

13 fev, 2020

Centralizando logs com ElasticSearch, Kibana, Serilog, Docker e .NET Core 3.1

100 visualizações
Publicidade

Um experimento que está sendo bem sucedido e gostaria de compartilhar com vocês

Uns tempos atrás fiz uma postagem sobre utilização do Serilog para criar logs de aplicação, basicamente todo log de erro da aplicação estava sendo escrito para um disco onde o sistema estava hospedado.

Essa abordagem pode servir para alguns projetos de pequena expressão ou pouco impacto de negócio, porém, se você está inserido em um contexto de negócio maior e que demanda constante análise de problemas e comportamento de suas aplicações, utilizar o ElasticSearch com o Kibana pode ser uma ótima opção — Ah, “dockerizar” também pode lhe trazer bons resultados para fazer sua vida mais fácil para subir as imagens com pouco esforço na parte de infraestrutura, mas avalie antes se é o caso para seu projeto.

Meu problema

Recentemente entrei em um projeto que tem várias APIs espalhadas e mesmo utilizando ferramentas Cloud (ferramenta no modelo serviço) os logs dessas APIs são pouco (ou quase nunca) vistos. Analisando essa situação, e como entrei recentemente no projeto, senti falta de dados para tomar decisões e sugerir melhorias com informações sem achismo, afinal eu não tinha a visão de negócio necessária nesse primeiro instante para julgar/entender os motivos pelos quais o que foi feito no passado foi feito dessa forma.

Para ilustrar melhor, imagine o seguinte cenário em que me encontrei, onde tenho mais de 20 APIs (com contextos delimitados mas praticamente no padrão monolito) acessando uma mesma base de dados SQL Server, sem estratégia de relisiência de código, sem estratégia de retry pattern, sem diversas práticas recomendadas para se ter um código melhor — enfim, um problema típico de mercado:

Exemplo do projeto real que encontrei

A pesquisa

Pesquisei por diversas ferramentas e serviços para conseguir centralizar os logs das APIs, existem excelentes opções, porém o ElasticSearch e o Kibana mostraram-se boas opções de utilização para o meu cenário. Um dos pontos que é preciso considerar nessa escolha são os requerimentos de hardware para utilizar o ElasticSearch, dependendo do conteúdo, você pode precisar de um hardware considerável. Nesse caso como estou apenas salvando texto, os requerimentos não são altos. Novamente, avalie seu cenário.

Os pré-requisitos

Para conseguir seguir esse tutorial é esperado que você tenha instalado na sua máquina:

  • Docker (pode ser Docker for Windows, mas lembre-se de trocar para Linux containers!)
  • Visual Studio Code ou 2017 ou 2019
  • .NET Core SD 2.1.300 (ou superior) — no exemplo desse tutorial estamos usando .NET Core 3.1

Criando sua aplicação

Crie um projeto .NET Core web application, pode ser via Visual Studio ou command line:

Selecione a opção Web Application:

Crie uma pasta chamada “Docker” e dentro dela um arquivo “docker-compose.yml”.

O docker-compose vai conter a imagem do ElasticSearch e Kibana, que podemos obter desse link. Com algum prompt de comando vá até a pasta onde seu docker-compose está e execute o comando docker-compose up -d

A primeira vez que você executar o docker fará o download das imagens. Em seguida, execute o comando docker ps para exibir os containers rodando.

Como configuramos as portas 9200 e 5601 para o ElasticSearch e Kibana respectivamente, verifique se está funcionando localmente:

ElasticSearch rodando localmente:

Kibana rodando localmente:

Problemas para rodar o ElasticSearch? Eu também tive, e tive que fazer uma pesquisa para identificar que não havia espaço suficiente no Java, por isso setamos o environment no docker-compose:

environment:
— bootstrap.memory_lock=true
— “ES_JAVA_OPTS=-Xms512m -Xmx512m”
— discovery.type=single-node

Se você está tendo algum problema diferente desse, sugiro pesquisar para identificar a causa raíz do seu problema. Aqui a gente analisou os logs e conseguimos uma solução massa com ajuda do Rafael Almeida (KUDOS!)

Voltando ao projeto, agora precisaremos instalar o Serilog, responsável por gerenciar os logs da aplicação e enviá-lo ao ElasticSearch:

Serilog;
Serilog.Sinks.ElasticSearch;
Serilog.Extensions.Logging;

Adicione a configuração do ElasticSearch ao appsettings.json do projeto apontando para o host especificado no seu docker-compose:

{
  "Logging": {
    "LogLevel": {
        "Default": "Information",
        "System": "Information",
        "Microsoft": "Information"
    }
  },
  "ElasticConfiguration": {
    "Uri": "http://localhost:9200/"
  }
}

Agora configurando o Startup.cs:

Crie uma variável para obter a URL do arquivo de configuração e use o método do Logger para incluir as informações de log no ElasticSearch:

Após isso, no método Configure do Startup.cs, adicione o método AddSerilog():

No método OnGet do Index, adicionamos um try/catch para simular uma exceção:

Inicie seu projeto

Agora, inicie seu projeto e comece a enviar os logs para o ElasticSearch:

Agora, vamos para o Kibana. Por padrão, ele não vai exibir nenhum log, é preciso configurar primeiro um “index pattern”, ou seja, um padrão de indexação para exibir seus logs. Para isso, você pode incluir um padrão que faça sentido, por exemplo: “logstash-*

E especifique vai usar o campo “@timestamp” para padrão de criação do index.

Clicando em “Discover”, agora você verá os logs da sua aplicação.

O Kibana é uma ferramenta completa, você consegue (e deve) criar visões e Dashboards conforme sua necessidade. Não vou me aprofundar nessa questão, porém é muito tranquilo encontrar informações de como fazê-lo. Com isso, você terá subsídios para tomar melhores decisões baseado no comportamento do seu sistema.

Conclusão

Com frequência a estratégia de log é criar um arquivo texto no servidor de aplicação e deixar para analisá-lo (ou não) com frequência. A praticidade e vantagens de usar o ElasticSearch e o Kibana se mostrou sensacional no projeto que atuo, pois além de usufruir das facilidades do Docker para rodar ambos, consegui centralizar a estratégias de log em um lugar apenas.

Com isso, temos maior propriedade para analisar o comportamento das nossas aplicações e tomar decisões baseadas em dados.

Exemplo no Github

Você pode baixar o projeto exemplo do meu Github, clicando nesse link.