Concrete Logo
Hamburger button

O que os logs podem nos contar sobre nossa aplicação

  • Blog
  • 18 de Junho de 2018
Share

Já passou por uma situação na qual o cliente te liga nervoso, diz que a sua aplicação não funciona, você tem que procurar o que resultou a falha e não sabe por onde começar? Ou então sua aplicação tem vários serviços, cada um em um ambiente, e você até tem uma suspeita da origem da falha, começa a analisar os logs, mas não consegue chegar a nenhuma conclusão razoável? Se sim, este post vai te ajudar!

Monolíticos x Microsserviços

Na arquitetura monolítica, todo o código é armazenado em um pacote só e o log é gerado por ele. Por padrão, os arquivos de log são gerados no mesmo local, as mensagens estão ordenadas por data e eles contêm o rastreamento completo do que ocorreu com a aplicação. Assim, num momento de falha, para descobrir a causa do erro é suficiente analisar somente esse log. É fácil? Não! Mas e nos microsserviços?

Nos microsserviços cada contexto é representado por um serviço independente. Desse jeito, cada um deles pode ter sido desenvolvido com uma tecnologia e/ou armazenado em um ambiente diferente com seu próprio log e com um serviço chamando outro, o que torna mais complexa a tarefa de análise da causa-raiz de um defeito. Mais difícil ainda, não é? Para ilustrar, vamos fazer uma análise sobre os microsserviços. Abaixo tem um exemplo de um e-commerce com seis serviços: produtos, carrinho, usuário, pedidos, pagamentos e notificações.

Exemplo de Arquitetura de Microsserviços.

Imagine que um usuário não consiga efetuar o pagamento. Podemos supor que a falha ocorreu necessariamente no serviço de pagamento ou o pedido foi gerado incorretamente e a falha só apareceu no último serviço? Tem alguma regra que diz que se o usuário tiver com problemas no cadastro ele não pode finalizar uma compra? Será que o produto que ele está comprando estava disponível quando ele colocou no carrinho, mas no momento do pagamento não estava mais? Dado que o arquivo de log do serviço de pedidos não é o mesmo do serviço de pagamento, o que aconteceu depois que o usuário fez o pedido? E se o serviço de pagamento possui múltiplas instâncias, em qual delas foi gravado o log? São muitas as situações para decidir por onde começar a analisar os logs e chegar à conclusão do ponto de falha.

12 Fatores

Essa metologia aborda 12 princípios a serem seguidos para a criação de um projeto SasS (Software as a Service) com sucesso. Eles emergiram como um guia com práticas ideais de desenvolvimento para aplicações escritas em qualquer linguagem de programação e que utilizam qualquer combinação de serviços de suportes. Foi a Heroku, uma plataforma que provê serviços em nuvem (PaaS) para empresas, que passou por vários percalços para criar aplicativos SaaS e, com base nas experiências, criou os 12 fatores.

E o que eles têm a ver com o assunto deste post? Bom, os logs são um dos fatores abordados nesta metodologia. A sugestão é que os logs sejam tratados como um fluxo de eventos e, para tal, as aplicações não devem se preocupar com o roteamento ou a armazenagem de seu fluxo de saída. Além disso, cada processo deve escrever seu próprio fluxo de eventos para o stdout.

Então temos um grande problema: se cada serviço possui seu próprio log, como eu rastreio o log da aplicação?

Soluções e Boas Práticas

Vamos às respostas!

Centralização de Logs

A primeira solução é centralizar os logs. Se todos os microsserviços armazenarem seus logs em um único local já não seria mais fácil coletá-los para análise? Sim, mas como fazer isso? Para isso existem o Logspout, o NXLog, o Graylog, o Logstash e o Splunk. Então, a melhor arquitetura seria essa?

Centralização de Logs

Análise de Logs

Vamos pensar: na arquitetura da figura acima temos todos os logs em um só local, mas como investigar a causa do erro? Se cada microsserviço gerou sua pilha de rastreamento, o fluxo da aplicação provavelmente não vai estar em um só arquivo. Desse modo, precisaríamos construir uma interface gráfica para nos ajudar. Ou, mais fácil ainda, podemos usar os dashboards do Graylog, do Logstash ou do Splunk de forma que a arquitetura seja a da próxima figura.

Serviço de coleta dos logs

Horário UTC

Neste momento já temos uma solução para a centralização dos logs e para análise. Então quer dizer que usando qualquer uma dessas ferramentas nossos problemas acabaram? Mais uma vez, não! Imagine uma situação no exemplo do e-commerce (aquela primeira figura lá em cima) em que o microsserviço de pedidos está na Europa e o de pagamentos no Brasil. Se cada um gerar seus logs no seu horário local, deveremos converter as horas na ocasião que o pedido foi gerado para procurar a sequência no serviço de pedidos. A solução para isso está em gerar os logs com o horário UTC – que é o fuso horário padrão a partir do qual se calculam todas as zonas horárias do mundo. Dessa maneira, todos os logs compartilham o mesmo fuso horário.

Implantação

Falhas podem ocorrer quando um serviço é implantado. Como os serviços são pequenos, podem ocorrer várias implantações em pouco tempo. E se a implantação falhar? Devemos ser capazes de encontrar essa falha rapidamente! Uma boa prática é testar o status do serviço logo após a implantação. Se o teste falhar, o log nos ajuda a detectar o problema. Além disso, nesse momento já sabemos se o que o log está registrando é útil ou não e se ele está produzindo informações desnecessárias ou não.

Agrupamento de Requests

Ao usar microsserviços, a lógica do negócio está toda especializada em cada contexto. Quando precisamos rastrear o que aconteceu pode ser difícil se os requests não estão agrupados. A opção para resolver essa situação é agrupar os requests com identificadores únicos. Quando uma solicitação deixa o primeiro serviço de API e passa o controle para o próximo serviço de API, começamos a nos esforçar para interpretar os logs. Uma falha na API que não é a “porta de entrada” do serviço provavelmente afetará o primeiro serviço, entretanto eles podem parecer dois erros não relacionados. Dessa forma, precisamos de uma maneira de visualizar todo o fluxo, desde que a solicitação atingiu a primeira API e seguindo pelas subsequentes. É aí que o conceito de IDs de correlação entra em cena.

Um ID de correlação é simplesmente um identificador exclusivo, que é passado por todo o fluxo de solicitação e transmitido de forma crucial entre os serviços. Quando cada serviço precisa registrar algo, é possível incluir esse ID de correlação, garantindo assim que possamos rastrear uma solicitação completa do usuário do início ao fim.

Agrupamento de Requests

Conclusão

Usando essas boas práticas, teremos uma aplicação com coleta de logs configurada e, consequentemente, geração centralizada de logs; todas as mensagens de log gravadas relativas ao mesmo fuso horário; implantações tranquilas; e ID de correlação. Satisfeito? Bom, se tiver qualquer dúvida ou observação sobre o assunto, é só deixar seu comentário aqui embaixo. Também vou deixar alguns links caso você queira estudar um pouco mais sobre o assunto. Fechado? Até a próxima!

Referências:

A Concrete é uma empresa da Accenture especializada no desenvolvimento ágil de produtos digitais. No capítulo de Java nós colaboramos ativamente com desenvolvedores e stakeholders dentro e fora do nosso ambiente. Construímos e somos responsáveis por API Java (J2EE ou Spring Framework), que atendem milhares de usuários, colaboramos com representantes de produtos e negócios para definir um roadmap do produto e auxiliamos no desenvolvimento do time em aspectos técnicos. Trabalhe com a gente! Acesse: concrete.com.br/vagas