Métricas com Go e Prometheus
No mundo do desenvolvimento, é necessário saber como a aplicação que estamos trabalhando está se comportando e a maneira mais conhecida de realizarmos isso é por meio de métricas. Elas podem ser de diversos tipos, como, por exemplo, de desempenho, de produto ou de saúde. Atualmente, o Prometheus é amplamente utilizado pelo mercado a fim de coletar essas métricas.
Como funciona?
Ele é um serviço open-source mantido pela CNCF, a Cloud Native Computing Foundation. Ele funciona da seguinte maneira: um endpoint é exposto na aplicação. Esse endpoint retorna um texto no formato esperado, e o Prometheus acessa esse endpoint de tempos em tempos coletando as informações dali.
|
|
O formato é bem simples, para cada métrica, você vai ter pelo menos três entradas:
- O #HELP mostra a descrição da métrica.
- O #TYPE define o tipo da métrica.
- A terceira linha mostra o valor da métrica.
Como utilizar em Go?
Em aplicações escritas com Go, temos uma biblioteca que facilita ainda mais a exposição dessas métricas. Ela implementa um handler que expõe por padrão as principais métricas relacionadas ao software, como, por exemplo, goroutines, memória, heap, etc. O exemplo abaixo demonstra melhor como se usa:
|
|
Pode-se notar que com poucas linhas temos o endpoint de métricas e um servidor web funcionando! Agora, como configurar um Prometheus para coletá-las? O primeiro passo é subir ambas as aplicações, para isso o melhor é utilizar o docker compose
.
|
|
No arquivo compose, é definida que a aplicação vai escutar na porta 8080
e o Prometheus na porta 9090
. Ele também espera um arquivo de configuração. Este arquivo define onde e com qual frequência ele deve fazer a varredura.
|
|
Também definimos o Dockerfile da nossa aplicação falsa:
|
|
Se quiser verificar se tudo está funcionando, é só acessar http://localhost:9090
e ver se deu certo a configuração.
Métricas customizadas
Contudo, muitas vezes as métricas padrões não são suficientes para representar o comportamento da nossa aplicação e é necessário definir métricas customizadas. Ao utilizar a biblioteca padrão do Prometheus para Go, essa tarefa se torna trivial e simples, como o exemplo abaixo:
|
|
Desta forma, uma nova métrica será retornada ao acessar o endpoint /metrics
. Porém, nem sempre é possível ter um servidor web para ter as métricas expostas dessa forma.
Enviando métricas de forma ativa
A partir dessa premissa, foi desenvolvido o Pushgateway. Ele funciona da seguinte forma: você envia suas métricas por chamadas HTTP e ele armazena e expõe o endpoint /metrics
para a coleta do Prometheus. Todavia, nem sempre é uma boa ideia utilizar esta estratégia, pois, segundo a própria documentação oficial:
- Quando se monitora múltiplas instâncias por meio de um único Pushgateway, ele se torna um ponto único de falha e um potencial gargalo.
- Você perde o monitoramento automático da saúde da sua aplicação, gerada em cada varredura.
- O Pushgateway nunca esquece nenhum dado que foi enviado para ele e vai sempre os expor para o Prometheus, exceto caso seja manualmente deletado.
Para mais informações, recomendo a leitura dessa documentação. Mas, como existem casos de uso, vamos ver como podemos usar a biblioteca do Prometheus para fazer um Push. O exemplo abaixo demonstra que muda muito pouco do exemplo anterior. Só adicionamos a instrução referente ao Push e para onde ele deve ser realizado.
|
|
Também é necessário configurar o compose para iniciar o Pushgateway.
|
|
E por fim, vamos dizer ao Prometheus que ele deve varrer o Pushgateway também.
|
|
Conclusão
Vale a pena mencionar que, para o exemplo, eu utilizei somente o tipo de métrica Counter, ou em português Contador. Contudo, existem diversos outros tipos que podem ser encontrados aqui! Para mais exemplos utilizando o Prometheus com Go, você pode checar os exemplos oficiais da biblioteca ou a PoC onde implemento um simulador de monitoramento sintético e gero métricas através do endpoint e do Pushgateway.
Se você gostou do post, me diz: quais métricas você geralmente monitora na sua aplicação? Elas são métricas padrões ou customizadas?