Arquitetura

Micro serviços e a correlação de logs

Uma arquitetura de micro serviços nos traz inúmeros benefícios, mas não sem alguns desafios. Um deles é a forma como trabalhamos com logs.  

Em uma aplicação monolítica podemos, de forma fácil, acessar o servidor e consultar os arquivos de log. Agora, em uma arquitetura de micro serviços onde os mesmos estão distribuídos em diversos lugares, temos o desafio de como acessá-los e entender como eles se relacionam.  

Existem alguns padrões e ferramentas que nos auxiliam com o gerenciamento e correlação de logs em ambientes distribuídos. 

O primeiro problema a ser resolvido é centralização dos logs em um único local, para que possamos acessá-los de uma forma fácil. Para isso, existem diversas soluções.  

Para esse exemplo utilizamos a stack open source conhecida como ELK em conjunto com logspout-logstash. 

O logspout-logstash é uma ferramenta que captura os logs dos containers executando no docker. Logo após encaminha para o Logstash, que é um pipeline de processamento de dados, que nos permite aplicar transformações em nossos logs e enviá-los para o Elasticsearch, um poderoso motor de busca baseado no Apache Lucene. 

Para visualização desses logs podemos utilizar o Kibana, que é a ferramenta gráfica onde podemos realizar as nossas consultas e criarmos dashboards. 

Em seguida, podemos utilizar a configuração abaixo, para criar um pipeline do Logstash, com entrada, processamento e saída.

Agora com a stack configurada e pipeline funcionando, precisamos entender a relação entre os logs dos nossos serviços – qual a ordem de execução, quem chamou quem, pois conforme vamos distribuindo nossa aplicação fica mais difícil sabermos por onde uma requisição passou.  

Quando um micro serviço falha ou começa a degradar a performance pode gerar uma cascata de erros e é muito importante que encontremos a origem do problema rapidamente.

Para nos ajudar a resolver esse ,surgiu o conceito de trace distribuído (OpenTracing), que define que um identificador único seja criado e repassado para todos os participantes da requisição. Ele é baseado no Google’s Dapper paper.  

Quando estamos trabalhando com serviços Java utilizando Spring Boot temos o auxílio do Spring Cloud Sleuth, que provém a auto configuração do sistema de trace distribuído com o Zipkin como ferramenta de visualização. 

O Spring Sleuth fica responsável de realizar a instrumentação do código, isto é, interceptação das requisições para repassar este identificador através delas.

Na imagem abaixo temos o Kibana exibindo os logs dos serviços de uma aplicação de exemplo (GitHub), composto por 4 micro serviços, 3 utilizando Spring MVC e 1 utilizando Spring Webflux. Todos com a dependência do Spring Cloud Sleuth.  

O fluxo da requisição inicia no serviço A, passa para o serviço B que chama de forma paralela os serviços C e D.  

Com o Kibana realizamos uma consulta por um “traceid” e podemos observar todo o fluxo por onde a requisição passou. 

O identificador fica disponível no contexto do MDC log, assim é possível adicioná-lo ao padrão de log do projeto, utilizando Spring Cloud Sleuth, onde tudo é configurado de forma automática. Assim, com uma simples consulta temos todos os serviços envolvidos na mesma requisição. 

Na imagem abaixo podemos ver que não temos nenhuma configuração especial na chamada http feita do serviço A para o serviço B. O Spring Cloud Sleuth se encarrega de todo o trabalho para nós.  

Ele também pode realizar a instrumentação do consumo e produção de eventos. Assim, mesmo que uma parte do fluxo seja realizada de forma assíncrona, é possível acompanhar todo o processamento. 

Além dos dados disponibilizados no log, é possível utilizar serviços como Zipkin Server ou Jaeger para coletar os traces e disponibilizá-los através de uma interface gráfica, assim permitindo realizar algumas outras analises, como latência entre os micros serviços. 

Conclusão

Os logs são muitos importantes, mesmo geralmente só sendo valorizados quando estamos enfrentando algum problema em produção.  

A forma que os gerenciamos é muito importante para uma rápida resolução do problema, principalmente conforme o número de serviços aumenta.  

Como citamos, existem inúmeras ferramentas que podem nos auxiliar, sendo várias delas open source e sob os cuidados da Cloud Native Computing Foundation (CNCF), que podem ser vistas neste landscape

Referências:  

https://microservices.io/patterns/observability/distributed-tracing.html

https://opentracing.io

https://docs.spring.io/spring-cloud-sleuth/docs/2.2.5.RELEASE/reference/html

https://www.cncf.io

https://github.com/deviantony/docker-elk

%d blogueiros gostam disto: