gRPC + Prometheus
Métricas no Grafana com interceptors — Artigo 16
Postman collection, código do artigo, diff com o artigo 15.
Sumário: Desenvolvimento de APIs em Go
Próximo Artigo: Go + Neo4j — Modelando o Brasil em Grafos
Artigo Anterior: Go + gRPC — Utilizando protobuf
Introdução
No episódio 10, intitulado “Go + Observabilidade: Métricas com o Prometheus”, abordamos como enviar métricas para o Prometheus a partir de uma API Go. Em sequência, no artigo “Grafana + Prometheus: Visualizando as Métricas de Nossa API”, mostramos como integrar o Prometheus com o Grafana, permitindo a criação de dashboards e a visualização das Golden Metrics de nossa API.
Observabilidade é um tópico muito importante (ainda estou devendo os episódios de Logs e Traces, confia que um dia saí kk). Como adicionamos novos endpoints em nossa API utilizando gRPC no último artigo, precisamos adaptar nossa integração para metrificar essas novas funcionalidades.
Este artigo será breve, pois a maneira como estruturamos nossa API tornou as coisas bastante simples. Para implementar a metrificação dos endpoints gRPC, basta adicionar um interceptor em nosso servidor gRPC.
Interceptors
Um interceptor, como o próprio nome sugere, é um recurso do protocolo gRPC que permite adicionar interceptadores à comunicação que ocorre. Essa interceptação pode ser feita tanto a nível de cliente quanto a nível de servidor. Os interceptors são úteis para diversos casos, como:
- Tratamento de metadados
- Logging
- Injeção de falhas
- Cache
- Métricas
- Autenticação e autorização
No nosso caso, utilizaremos os interceptors para o envio de métricas. No entanto, antes de simplesmente implementá-los, é importante entender os diferentes tipos de interceptadores que existem.
Tipos de Interceptadores
Existem dois tipos de interceptadores: os Unary
e os Stream
. Como não estamos enviando nenhum tipo de arquivo grande via essa comunicação, não há necessidade de fazer Streaming. Por isso, vamos utilizar o Unary
. Após a definição do tipo de interceptor, precisamos decidir se vamos utilizar apenas um ou se vamos utilizar uma cadeia de interceptadores. Para fins de extensão, optei por utilizar o ChainUnaryInterceptor
.
Como mostrado no código 1, o ChainUnaryInterceptor
recebe um vararg de UnaryServerInterceptor
, que é o seguinte tipo:
Nossa implementação do interceptador será uma struct que possuirá um método com a mesma assinatura apresentada no código 2. Esse método será praticamente igual ao middleware de métricas para os endpoints REST, apresentado anteriormente.
Interceptador de Métrica
Assim como no envio de métricas dos endpoints REST, aqui estamos utilizando nosso pacote interno de endpointmetrics
. A diferença é que algumas tags que usamos nos endpoints REST, como method
, pattern
e status_code
, não estão presentes aqui, pois estamos lidando com uma tecnologia diferente.
No código 3, vale ressaltar que adicionamos uma nova tag chamada Protocol
, onde definimos o valor GRPC
. Nos endpoints velhos, temos essa tag com o valor REST
. Para incorporar efetivamente o interceptor na API gRPC, tivemos que alterar o wireup, que ficou da seguinte forma:
Na linha 20 do código 4, temos a adição do interceptador sendo injetado no NewServer
. Com essas modificações, conseguimos coletar métricas dos novos endpoints com o mesmo nível de detalhes apresentado nos artigos anteriores.
Conclusões e Próximas Etapas
Neste artigo, vimos como coletar métricas dos endpoints gRPC da mesma forma que fazemos com os endpoints REST. Para realizar esse trabalho, utilizamos o conceito de interceptors, que é um recurso fornecido pelo protocolo e nos permite criar uma espécie de middleware para interceptar as chamadas antes que elas cheguem aos handlers.
No próximo artigo, veremos como integrar duas APIs utilizando gRPC e começaremos a criar um ambiente de microserviços mais complexo.