Debugging; Deu ruim, e agora?
Tags: programming, productivity, architecture
Published: 2021-11-12 10:20:12

Debugar sistemas distribuídos não é uma tarefa simples. Uma das primeiras ferramentas que precisamos é um modelo mental de como o sistema se comporta (ou como desejamos que ele se comporte). Tente desenhar num esquema simples o fluxo das interações, onde chegam as requisições, quais bancos de dados estão envolvidos, quais subsistemas são consultados. Não precisa ser um modelo extremamente detalhado, mas um que fique fácil identificar as partes.

> :warning: **Spoiler**: Se você está com dificuldades de fazer um modelo, ou se a interações estão ficando extremamente complexas e acopladas, talvez seja um sinal de que está na hora de simplificar o sistema. Repensar subsistemas, agrupá-los quando possível, mantendo domínios de informações similares nesses grupos.

![Exemplo de modelo mental](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jjuv4nr1jcc8igtvolid.png)

No modelo acima conseguimos facilmente ver as partes envolvidas sem entrar nos detalhes do que seriam os subsistemas. Será que temos OpenId Connect para autenticação? Será que é um ES com muitos nós atendendo a busca? Do nosso ponto de vista tanto faz, só precisamos entender que os sistemas existem e que podem ser eventuais pontos de falha — com sorte existem outros times cuidando dessas partes. Com o modelo em mãos, temos que ver se temos métricas que possam indicar falhas em qualquer uma das relações, depois verificamos se há logs interessantes ou, melhor ainda, se temos um sistema de tracing com instrumentação adequada. Agora, com sorte, já temos informações suficientes para fazer qualquer investigação no nosso sistema.

Começamos olhando as métricas e vendo se algo fugiu do padrão. Por exemplo, se o sistema de busca ficar lento, vamos notar latências aumentando no nosso sistema. Se o sistema de vídeos sair do ar, vamos encontrar erros 500 nas métricas e logs. Será que o nosso sistema saiu do ar por alguma dessas dependências? Se for uma dependência forte, temos que lidar adequadamente, retornar uma informação de erro para nossos usuários. Talvez possamos degradar a qualidade do serviço pelo período que o subsistema ficou fora do ar. Se fizermos isso, precisamos de uma métrica indicando quantas vezes estamos degradando a nossa qualidade — para eventualmente conversar com o time responsável e mostrar o impacto aos usuários.

> :warning: **Métricas**: leia o [texto de métricas](/pedrokiefer/metricas-the-good-the-bad-and-the-ugly-4b7e) para uma discussão maior sobre o assunto.

Os logs terão informações mais detalhadas sobre o problema, um stacktrace pode permitir que você ache a linha exata onde o sistema quebrou. Correlacionando os logs de outros subsistemas ajudará a entender qual foi o dado que gerou o erro. Tente isolar ao máximo a fonte causadora do problema, isso vai tornar o processo de correção muito mais fácil pois você já terá um caso de uso para implementar um novo teste!

Não culpe a infraestrutura antes de verificar os logs e entender o que está acontecendo. Se é um problema de infraestrutura, provavelmente outras aplicações também serão afetadas, não somente a sua. Investigue e aprenda sobre as peças de infraestrutura, pergunte aos colegas sobre as escolhas que foram feitas e proponha outras caso a atual não atenda mais o produto.

Passada a turbulência do incidente é hora de reunir os times envolvidos e fazer um postmortem. Aqui não queremos só ver causa-efeito, mas queremos uma análise ampla e profunda do que gerou o problema. A partir disso conseguimos traçar ações de melhoria contínua, e não só resolver o problema pontualmente. Tente aplicar a técnica dos cinco porquês. Essa técnica consiste em ficar perguntando repetidas vezes "Por quê?", sempre tentando buscar a causa raiz, que pode não ser um problema de código, mas uma falta de conhecimento do time, ou um problema de comunicação entre times. Nos aprofundando na causa conseguimos crescer como time e evitar que uma classe de problemas similares se repita.