A Observabilidade ajuda as equipes SRE, fornecendo os dados e insights de que necessitam para solucionar e corrigir problemas rapidamente ou até mesmo impedir de maneira proativa que os problemas ocorram . Mas… o atual “estado da arte” da Observabilidade ainda não é o suficiente.
Até o momento, há um sucesso razoável na coleta de dados para Observabilidade, mas muitas vezes os dados ficam em forma de linha (por exemplo, spans) em discos. Infelizmente, esses dados são muito pouco usados e, portanto, muito poucos insights estão sendo derivados. Logo, apenas uma pequena fração do valor prometido dentro do conceito de Observability está sendo realmente entregue.
Em termos gerais, existem 3 elementos na Observabilidade: coletar os dados corretos, apresentar os dados corretos ao usuário e, em seguida, encerrar o ciclo, permitindo que o engenheiro analise o problema. Eles são suportados pelos 3 pilares de Observabilidade: métricas, logs e rastreamento. No entanto, embora esses pilares sejam necessários, eles não são suficientes.
Este post é um esforço para descrever como a Observability para resolução de problemas pode e deve ser feita sob o ponto de vista do usuário.
Coletando os dados certos
Quando falamos em Observabilidade, dois conjuntos de ferramentas se sobressaem: as ferramentas mais específicas, como Zipkin e Jaeger; e as ferramentas de monitoramento de desempenho de aplicativos (APM) mais amplas, tais como DataDog, Newrelic, Elastic, Grafana entre outros.
Ao monitorar sistemas, precisamos de informações de todos os níveis, desde o método e rastreamento em nível de sistema operacional até banco de dados, servidor, chamada de APIs, threads e rastreamento de dados de logs transacionais. Pedir aos desenvolvedores para adicionar instrumentação e obter essas estatísticas é caro e demorado e deve ser evitado sempre que possível. Em vez disso, os desenvolvedores devem ser capazes de usar plugins, interceptação e injeção de código para coletar dados o máximo possível.
As ferramentas APM fizeram um bom trabalho nesse sentido. Em geral, possuem instrumentação (por exemplo, agentes Java) incorporados em linguagens de programação para coletar dados de rastreamento em nível de método e adicionaram lógica de filtro personalizado para detectar banco de dados, servidor, chamada de API, thread e rastreamento de dados de logs transacionais observando os métodos de rastreamento. Além disso, as APMs adicionaram plugins às ferramentas de middleware comumente usadas para coletar e enviar dados instrumentados. (Uma desvantagem dessa abordagem é que as necessidades de instrumentação mudarão à medida que as linguagens de programação e o middleware evoluem).
Com Microsserviços, a maior parte do processamento abrange vários serviços e, portanto, várias máquinas. Com isso, os dados que discutimos até agora são coletados em muitas máquinas e, para entender o processamento de ponta a ponta, devemos propagar o contexto através de todas as invocações – até mesmo as chamadas assíncronas.
Por exemplo, quando um sistema recebe uma requisição, um identificador deve ser criado e passado por todas as invocações acionadas por essa requisição. Partes diferentes do sistema devem incluir esse identificador em todas as métricas, rastreamentos e logs, o que nos permite conectar posteriormente todo o processamento relacionado à invocação. Existem outras maneiras de obter o mesmo resultado. Por exemplo, a telemetria aberta compartilha um identificador entre cada processo pai e processo cliente, mas com essa abordagem, rastrear uma requisição de ponta a ponta incorre em muito mais sobrecarga.
A coleta de dados adiciona sobrecarga e, se o sistema lida com grandes cargas, geralmente não é possível medir tudo. Normalmente, a quantidade de logs já está bem ajustada para grandes cargas de trabalho e é gerenciável. Como coletamos métricas periodicamente, cargas maiores no sistema geralmente não aumentam significativamente a sobrecarga de coleta de métricas. Por outro lado, o rastreamento de sobrecarga está diretamente relacionado ao número de requisições e muitas vezes não pode ser totalmente rastreado em face de grandes cargas. Até mesmo o sistema Dapper do Google rastreia apenas 1 em cada 1000 solicitações.
Portanto, os SREs devem apresentar amostras rastreando apenas algumas requisições, como 1 em cada 100. Com a amostragem, é possível reduzir a sobrecarga, mas há uma chance de que, quando ocorrer um erro, não hajam dados de Observabilidade relevantes entre os dados coletados. Isso leva a desafios para os quais precisamos estar preparados para enfrentar.
Em primeiro lugar, se cada serviço selecionar amostras de forma independente, teremos apenas alguns rastreamentos para uma determinada requisição. Isso pode levar a situações em que temos apenas pequenas partes de cada solicitação do usuário, tornando a Observabilidade inútil. Para evitar isso durante a amostragem, é preciso escolher algumas requisições do usuário e rastreá-las de ponta a ponta em todos os detalhes.
Um segundo desafio é que uma taxa de amostragem de 1 em 100 é ótima para um serviço que faz 5.000 solicitações por segundo, mas não funciona para um serviço que possua apenas 50 mensagens por dia. Uma política de amostragem mais adaptável – como 100 amostras no máximo por segundo – funcionará melhor.
Mais trabalho precisa ser feito para selecionar de forma inteligente quais requisições serão amostradas. Por exemplo, uma abordagem proposta chamada de adaptive tracking analisa os dados recentes e prevê quais requisições têm maior probabilidade de erro. Em seguida, faz o rastreamento dessas requisições.
Apresentando os dados corretos ao solucionador de problemas
Os engenheiros não podem ficar olhando os logs ou gráficos esperando que ocorra um problema. Precisamos enviar alertas a eles quando surgirem problemas em potencial. Os alertas podem vir de várias formas, como e-mails e SMS.
Quando o alerta chegar, os engenheiros que usam dados de Observabilidade para solucionar problemas NÃO devem examinar todos os dados. Simplesmente não é um uso eficiente do tempo. Em vez disso, primeiro é preciso detectar anomalias de desempenho e direcionar a atenção dos desenvolvedores ou engenheiros para os dados correspondentes. Depois que um usuário recebe o alerta e faz o check-in, devemos apresentar os dados na forma mais fácil de entender e apontar possíveis anomalias.
Os sistemas de Observabilidade podem alcançar a detecção de anomalias por meio de regras definidas pelo usuário ou mesmo a partir de uma combinação de análise estatística e aprendizado de máquina. Embora estejamos usando essas soluções com ambas as abordagens, conforme mostrado no exemplo de esboço de falha, a última tem espaço para melhorias significativas.
A maioria das ferramentas atuais resolve problemas de apresentação de dados, permitindo que os usuários criem suas próprias visualizações e gráficos. Os engenheiros podem então decidir sobre indicadores-chave de desempenho (KPIs) úteis a serem renderizados e criar seus próprios gráficos correspondentes, que podem ser usados para debug e solução de problemas.
Esses gráficos são úteis para detectar o status atual de um sistema e perceber problemas recorrentes comuns. No entanto, eles não funcionam bem com processos de solução de problemas em que o engenheiro cria hipóteses para a causa do problema e, a seguir, analisa, verifica e, se necessário, refina ou altera a hipótese.
Em vez disso, podemos aprender com ferramentas de profiling, como o Java Flight Recorder. Os profilers não fornecem uma ferramenta de painel nem pedem aos usuários que criem seus próprios gráficos para entender o problema. Em vez disso, eles fornecem algumas visualizações bem projetadas, como árvores de chamadas, visualizações de pontos de acesso ou visualizações de memória que ajudam os engenheiros a solucionar problemas. As ferramentas de Observability podem fazer o mesmo.
Quando um engenheiro sabe que existe um problema potencial e usa o sistema de Observabilidade para investigá-lo, ele precisa pular rapidamente para o momento em que o problema potencial pode ter ocorrido e visualizar métricas, logs e rastreamentos no contexto.
Por exemplo, a visualização a seguir mostra logs e métricas organizados ao longo de uma linha do tempo de maneira significativa. Os usuários podem observar o que aconteceu e como as métricas se comportaram em uma única visualização. Frequentemente, as notáveis capacidades de detecção de padrões do olho humano ajudam a conectar as situações atuais com as experiências anteriores.
Podemos compreender o valor da [imagem acima] contrastando-a com observações alternativas. Muitas ferramentas de Observability adotaram uma visualização alternativa onde o usuário pode desenhar vários gráficos e mover um cursor em todos os gráficos simultaneamente com base no tempo em análise. Embora mais fácil de implementar, esse modo de visualização não ajuda no reconhecimento de padrões visuais tanto quanto a visão mencionada anteriormente, porque várias séries de tempo estão espalhadas e não se encaixam em uma única tomada tão naturalmente. Por outro lado, a visualização proposta na imagem acima mostra todos os dados relevantes na mesma tela, em contexto, tornando mais fácil para o olho humano comparar e contrastar.
Se houver change point detection claros associados ao problema, a visão anterior ajudará significativamente o engenheiro. No entanto, pode ser que o problema esteja mais disperso e seja difícil reconhecê-lo em um determinado momento. Nesses casos, para encontrar o problema, examinamos os dados agregados em vez de um rastreamento específico.
Por exemplo, o gráfico a seguir mostra como a latência é distribuída entre diferentes funções agregadas em muitas requisições.
A visualização apresenta gargalos como “vales” e, se necessário, os usuários podem comparar essa visualização ao longo do tempo e criar um gráfico diferencial, mostrando como os traços atuais diferem dos comportamentos normais.
Em alguns outros casos, os problemas se originam em um ponto e se manifestam em todo o sistema. Então, para encontrar o culpado, precisamos de uma visualização da topologia mostrando as dependências entre os componentes que contribuem para uma requisição.
Por exemplo, se o banco de dados ficou lento, veremos todos os serviços downstream mostrando latências altas e até mesmo empilhamento de conexão. Em resumo: somente entendendo como os erros se propagam pela topologia é possível encontrar sua causa raiz.
Para tornar a análise simples e focada, é útil ter uma topologia gerada dinamicamente que mostra apenas os serviços e servidores relevantes ou APIs.
Quando encontramos as causas potenciais, mudamos para rastros relacionados a execuções problemáticas e as examinamos para encontrar o problema. Neste ponto, é útil ter uma integração com o editor de código-fonte, onde os devs podem ver o código-fonte enquanto fazem uma varredura nos rastreamentos.
Essas visualizações são detalhadas, conectadas e refinadas, permitindo que o engenheiro filtre, analise e amplie os problemas. É difícil para o usuário final construir esse tipo de experiência rica e cheia de nuances. Em vez disso, as ferramentas de Observabilidade devem ser construídas nessas visualizações e permitir que o engenheiro de software as personalize selecionando feeds de dados subjacentes às visualizações. Por exemplo, é comum desenhar as visualizações acima com base na latência, mas a ferramenta pode permitir que os usuários alterem as visualizações para selecionar uma medida diferente, como tempo de espera de bloqueio, e ampliar um problema específico.
Outro insight relevante e interessante é o que mudou no sistema de uma forma geral antes que o problema específico ocorresse. Muitas vezes, os erros são causados por algo que mudou no sistema, como uma atualização de código, uma mudança de configuração, atualizações de dependência ou até mesmo uma mudança de deploy. Conforme discutido por Bogomil Balkansky, a capacidade de extrair dados do pipeline de integração/entrega contínua (CI/CD) e deploy ativo também pode melhorar muito os processos de solução de problemas. Por exemplo, se a organização já usa GitOps, é uma questão de mostrar a diferença entre os dois deploys.
Finalmente, a própria ferramenta de Observability pode ajudar o engenheiro identificando as causas raízes potenciais e explicando as evidências. A maioria das ferramentas existentes tem pelo menos um caso de uso, mas funcionam apenas para tipos limitados de problemas. A Explainable AI, modelos de IA que podem explicar como se chega a uma previsão assertiva, tem feito algum progresso recentemente. No entanto, este ainda é um campo em franca evolução.
—
Com informações da InfoQ