Monitoramento de Microservices com Prometheus e Grafana
June 8, 2023
O monitoramento contínuo é crucial para tornar os sistemas de microsserviços robustos. Sem o monitoramento adequado, os microsserviços podem rapidamente ficar sobrecarregados, levando a erros e perda de desempenho.
Através do monitoramento contínuo, os desenvolvedores podem detectar problemas com seus serviços assim que eles surgem e tomar medidas para evitar danos significativos. Ele também fornece insights sobre como seus serviços estão performando, permitindo que você tome decisões informadas.
Este artigo apresentará como você pode configurar o monitoramento em sua aplicação de microsserviços usando duas das ferramentas mais populares nesse espaço, Prometheus e Grafana.
O código-fonte e o arquivo Docker Compose para este tutorial estão disponíveis em pottekkat/monitoring-101.
Noções Básicas do Prometheus
O Prometheus é uma ferramenta de monitoramento e alerta de código aberto. Ele "puxa" métricas (medições) dos microsserviços enviando solicitações HTTP e armazena os resultados em um banco de dados de séries temporais.
Você pode instrumentar seus serviços usando as bibliotecas de cliente fornecidas pelo Prometheus. Isso permitirá que você crie e colete métricas personalizadas de seus serviços.
O Prometheus também possui exportadores que permitem que você puxe métricas que não estão no formato do Prometheus. Um exportador age como um intermediário e transforma os dados exportados em um formato legível pelo Prometheus.
O Prometheus fornece uma poderosa linguagem de consulta, PromQL, para trabalhar com esses dados coletados. Você pode usar o PromQL para criar consultas complexas para filtrar, agregar e transformar os dados no formato desejado.
Além de puxar métricas, o Prometheus também pode acionar alertas quando os limites definidos são ultrapassados. O mecanismo de alerta é altamente configurável e pode enviar notificações para lugares como Slack ou e-mail.
O Prometheus possui uma interface gráfica que permite visualizar facilmente as métricas coletadas. Ele também se integra a outras ferramentas avançadas de visualização, como o Grafana.
Tipos de Métricas
O Prometheus oferece quatro tipos principais de métricas:
- Contador: representa um único contador monotonicamente crescente. Seu valor pode aumentar ou ser reiniciado para zero na reinicialização. Você pode usá-lo para representar métricas como o número de solicitações atendidas.
- Gauge: representa um valor numérico que pode subir ou descer. Você pode usá-lo para representar valores como uso de memória ou número de solicitações por segundo.
- Histograma: amostra dados em intervalos configuráveis. Use-o para representar valores como durações de solicitação ou tamanhos de resposta.
- Resumo: semelhante ao histograma, ele também calcula valores configuráveis em uma janela de tempo deslizante.
Você pode aprender mais sobre esses tipos de métricas e como usá-los na documentação oficial.
Aplicação de Exemplo
Nossa aplicação de exemplo consistirá em um gateway de API, um aplicativo Go e um aplicativo Python.
A aplicação retornará "Olá <nome>!" no idioma que você escolher com o <nome>
que você fornecer. O Apache APISIX será o gateway de API que direciona o tráfego para seus serviços.
O diagrama abaixo mostra como o sistema funciona.
- O usuário envia uma solicitação GET para o APISIX, o ponto de entrada da aplicação.
- O APISIX encaminha a solicitação para o serviço Go.
- O serviço Go envia uma solicitação GET para o serviço Python para obter "Olá" no idioma especificado.
- O serviço Python responde com a tradução necessária de "Olá".
- O serviço Go cria a resposta necessária usando o nome fornecido na consulta e a envia para o APISIX.
- O APISIX encaminha a resposta de volta ao usuário.
Configurando o Prometheus para Coletar Métricas
Vamos instrumentar e exportar métricas de todos os serviços em nossa aplicação e coletá-las no Prometheus. Começaremos com nosso gateway de API, Apache APISIX.
Exportando Métricas do APISIX
O Apache APISIX é um gateway de API nativo da nuvem e de código aberto.
Você não precisa saber sobre o APISIX para acompanhar, e pode usar o arquivo Docker Compose fornecido para configurar tudo. Para saber mais sobre o APISIX, visite api7.ai/apisix.
O APISIX oferece um Plugin prometheus que facilita a exportação de métricas no formato Prometheus. Você pode configurar o Plugin em seu arquivo de configuração do APISIX:
apisix:
enable_admin: false # executa o APISIX no modo autônomo
config_center: yaml # usa um arquivo YAML para configuração em vez de armazená-lo no etcd
plugin_attr:
prometheus:
export_uri: /prometheus/metrics # habilita o Plugin prometheus e exporta as métricas para este URI
enable_export_server: false # exporta as métricas na porta padrão do plano de dados
Agora podemos habilitar o Plugin em cada Rota, tornando-o uma Regra global:
routes:
# encaminha solicitações para /hello/* para o go-app
- uri: /hello/*
upstream:
type: roundrobin
nodes:
"go-app:8080": 1
plugins:
# remove o prefixo "/hello" antes de encaminhar a solicitação para o go-app
proxy-rewrite:
regex_uri:
- "/hello/(.*)"
- "/$1"
# exporta métricas do Prometheus para o URI especificado
- uri: /prometheus/metrics
plugins:
public-api:
# habilita o Plugin Prometheus globalmente em todas as Rotas
global_rules:
- id: 1
plugins:
prometheus:
prefer_name: true
#END
Isso exportará as métricas para o endpoint /prometheus/metrics
no Apache APISIX.
Você pode aprender mais sobre as métricas disponíveis na documentação.
Instrumentando e Exportando Métricas do Serviço Go
O Prometheus possui uma biblioteca de cliente Go oficial para instrumentar aplicações Go.
Por padrão, o Prometheus expõe as métricas padrão do Go. Você também pode criar suas próprias métricas específicas da aplicação.
Em nosso serviço, exporemos as métricas padrão e criaremos nossa própria métrica de contador para rastrear o número de solicitações:
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
// Pacotes do Prometheus
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// Response armazena a Mensagem obtida do python-app
type Response struct {
Message string `json:"message"`
}
// idioma e nome padrão
var (
lang = "en"
name = "John"
)
// cria uma nova métrica de contador personalizada do Prometheus
var pingCounter = promauto.NewCounter(
prometheus.CounterOpts{
Name: "go_app_request_count",
Help: "Número de solicitações tratadas pelo go-app",
},
)
// HelloHandler trata as solicitações para o go-app
func HelloHandler(w http.ResponseWriter, r *http.Request) {
lang = r.URL.String()
name = r.URL.Query()["name"][0]
fmt.Println("Solicitação para", lang, "com nome", name)
pingCounter.Inc()
pUrl := os.Getenv("PYTHON_APP_URL")
if len(pUrl) == 0 {
pUrl = "localhost"
}
// chama o python-app para obter a tradução
resp, err := http.Get("http://" + pUrl + ":8000" + lang)
if err != nil {
log.Fatalln(err)
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatalln(err)
}
resp.Body.Close()
var m Response
json.Unmarshal(body, &m)
// envia a resposta com "Olá nome!" no idioma especificado
fmt.Fprintf(w, "%s %s!", m.Message, name)
}
func main() {
// expõe as métricas do Prometheus
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/", HelloHandler)
http.ListenAndServe(":8080", nil)
}
Isso exporá as métricas para o endpoint /metrics
. Você pode aprender mais sobre a biblioteca de cliente Go em seu repositório GitHub.
Instrumentando e Exportando Métricas do Serviço Python
O Prometheus também possui uma biblioteca de cliente Python oficial. Existem também bibliotecas de terceiros que são adaptadas para casos de uso específicos.
Nosso serviço usa FastAPI, e usaremos a biblioteca prometheus_fastapi_instrumentator para instrumentá-lo:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from prometheus_fastapi_instrumentator import Instrumentator
app = FastAPI()
hello = {"en": "Hello", "fr": "Bonjour", "es": "Hola", "ml": "ഹലോ"}
# expõe as métricas padrão do Python para o endpoint /metrics
Instrumentator().instrument(app).expose(app)
@app.get("/{lang}")
async def get_hello(lang):
return {"message": hello[lang]}
Você pode aprender mais sobre como criar métricas personalizadas na documentação.
Configurando o Prometheus
Agora podemos coletar essas métricas no Prometheus.
Você pode configurar o Prometheus para coletar métricas de cada um dos serviços. Por padrão, o Prometheus verifica as métricas no caminho /metrics
:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: "prometheus"
static_configs:
- targets: ["localhost:9090"]
- job_name: "go-app"
static_configs:
- targets: ["go-app:8080"]
- job_name: "python-app"
static_configs:
- targets: ["python-app:8000"]
- job_name: "apisix"
static_configs:
- targets: ["apisix:9080"]
metrics_path: "/prometheus/metrics"
É isso! Agora, se você abrir o painel do Prometheus (padrão na porta 9090
) e clicar em "Status" na barra de navegação e em "Targets", você poderá ver o status das métricas sendo coletadas de seus serviços.
Consultando e Visualizando Métricas no Prometheus
Agora, você pode usar o painel do Prometheus para executar consultas e expressões complexas.
Você pode aprender mais sobre como consultar o Prometheus na documentação oficial.
Usando o Grafana para Consultar o Prometheus
O Grafana é uma plataforma de visualização de dados de código aberto que funciona com o Prometheus para fornecer uma ferramenta abrangente para coletar, consultar e visualizar métricas.
O Prometheus é bom em coletar métricas e consultar, mas carece de ferramentas para criar visualizações significativas. O Grafana supera essa limitação transformando as métricas coletadas em visualizações.
O Grafana também é compatível com muitas outras fontes de dados além do Prometheus.
Depois de implantar o Grafana, você pode abrir a interface web (padrão na porta 3000
).
Primeiro, você precisa adicionar o Prometheus como uma fonte de dados. Para fazer isso, vá para /datasources
ou "Configuração" e "Fontes de dados". Clique em "Adicionar fonte de dados" e selecione Prometheus. Especifique onde o Prometheus está implantado, salve e teste a conexão.
Usando Painéis Pré-construídos do Grafana
O Grafana hospeda um repositório público de painéis que contém painéis pré-construídos do Grafana. Você pode usá-los em sua instância do Grafana para visualizar rapidamente as métricas relevantes.
Usaremos o painel Go Processes que processará e visualizará o status do processo publicado pela biblioteca de cliente Go do Prometheus.
Para importar este modelo, primeiro copie seu ID (6671
) do repositório de painéis. Em sua interface do Grafana, vá para "Painéis" e selecione "Importar". Cole o ID que você copiou e clique em "Carregar".
Você também pode explorar outros painéis pré-construídos ou criar os seus próprios. Consulte a documentação para saber mais sobre isso.
O Que Vem Depois?
Isso é tudo para este tutorial!
Este artigo foi apenas uma introdução sobre como você pode configurar o monitoramento em seus serviços, e eu encorajo você a aprender mais sobre o Prometheus e o Grafana a partir dos recursos mencionados abaixo:
O código completo e o arquivo Docker Compose para este tutorial estão disponíveis em pottekkat/monitoring-101.