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 …


This content originally appeared on DEV Community and was authored by Matheus Mina

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.

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.

# HELP failure_rate The total number of failed events
# TYPE failure_rate counter
failure_rate 3280

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.

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:

package main

import (
  "fmt"
  "net/http"

  "github.com/prometheus/client_golang/prometheus/promhttp"
)

func main() {
  fmt.Println("Monitoring service...")
  http.Handle("/metrics", promhttp.Handler())
  http.ListenAndServe(":8080", nil)
}

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.

services:
  myapp:
    image: myapp
    build: .
    container_name: myapp
    ports:
      - 8080:8080
    restart: unless-stopped
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yaml'
    ports:
      - 9090:9090
    restart: unless-stopped
    volumes:
      - ./prometheus:/etc/prometheus
      - prom_data:/prometheus
volumes:
  prom_data:

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.

global:
  scrape_interval: 15s
  scrape_timeout: 10s
  evaluation_interval: 15s
scrape_configs:
- job_name: myapp
  honor_timestamps: true
  scrape_interval: 15s
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: http
  static_configs:
  - targets:
    - 'myapp:8080'

Também definimos o Dockerfile da nossa aplicação falsa:

# copied from the internet
# syntax=docker/dockerfile:1

FROM golang:1.23

# Set destination for COPY
WORKDIR /app

# Download Go modules
COPY go.mod go.sum ./
RUN go mod download

# Copy the source code. Note the slash at the end, as explained in
# https://docs.docker.com/reference/dockerfile/#copy
COPY ./ ./

# Build
RUN CGO_ENABLED=0 GOOS=linux go build -o /myapp

# Optional:
# To bind to a TCP port, runtime parameters must be supplied to the docker command.
# But we can document in the Dockerfile what ports
# the application is going to listen on by default.
# https://docs.docker.com/reference/dockerfile/#expose
EXPOSE 8080

# Run
CMD ["/myapp"]

Se quiser verificar se tudo está funcionando, é só acessar http://localhost:9090 e ver se deu certo a configuração. 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:

successRate := promauto.NewCounter(prometheus.CounterOpts{
  Name: "success_rate",
  Help: "The total number of succeded events",
})

successRate.Inc()

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. 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.

successRate := promauto.NewCounter(prometheus.CounterOpts{
  Name: "success_rate_pg",
  Help: "The total number of succeded events",
})

p.successRate.Inc()

err := push.New("http://pushgateway:9091", "pg").
  Collector(p.successRate).
  Grouping("myapp", "success_rate_pg").
  Push()

if err != nil {
  fmt.Println("Could not push completion time to Pushgateway:", err)
}

Também é necessário configurar o compose para iniciar o Pushgateway.

services:
  # ... myapp and prometheus already exposed
  pushgateway:
    image: prom/pushgateway
    container_name: pushgateway
    restart: unless-stopped
    expose:
      - 9091
    ports:
      - "9091:9091"

E por fim, vamos dizer ao Prometheus que ele deve varrer o Pushgateway também.

global:
  scrape_interval: 15s
  scrape_timeout: 10s
  evaluation_interval: 15s
scrape_configs:
- job_name: pushgateway
  honor_timestamps: true
  scrape_interval: 15s
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: http
  static_configs:
  - targets:
    - 'pushgateway:9091'

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?


This content originally appeared on DEV Community and was authored by Matheus Mina


Print Share Comment Cite Upload Translate Updates
APA

Matheus Mina | Sciencx (2025-02-05T19:04:21+00:00) Métricas com Go e Prometheus. Retrieved from https://www.scien.cx/2025/02/05/metricas-com-go-e-prometheus/

MLA
" » Métricas com Go e Prometheus." Matheus Mina | Sciencx - Wednesday February 5, 2025, https://www.scien.cx/2025/02/05/metricas-com-go-e-prometheus/
HARVARD
Matheus Mina | Sciencx Wednesday February 5, 2025 » Métricas com Go e Prometheus., viewed ,<https://www.scien.cx/2025/02/05/metricas-com-go-e-prometheus/>
VANCOUVER
Matheus Mina | Sciencx - » Métricas com Go e Prometheus. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/02/05/metricas-com-go-e-prometheus/
CHICAGO
" » Métricas com Go e Prometheus." Matheus Mina | Sciencx - Accessed . https://www.scien.cx/2025/02/05/metricas-com-go-e-prometheus/
IEEE
" » Métricas com Go e Prometheus." Matheus Mina | Sciencx [Online]. Available: https://www.scien.cx/2025/02/05/metricas-com-go-e-prometheus/. [Accessed: ]
rf:citation
» Métricas com Go e Prometheus | Matheus Mina | Sciencx | https://www.scien.cx/2025/02/05/metricas-com-go-e-prometheus/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.