Bem-vindo à aula 64 do nosso curso de DevOps! Hoje vamos mergulhar em um dos pilares da observabilidade: métricas e monitoramento. Em ambientes modernos, onde sistemas distribuídos e microsserviços são a norma, não é mais suficiente apenas 'deployar' e torcer para funcionar. Precisamos de visibilidade contínua sobre o comportamento dos nossos serviços, capacidade de detectar anomalias rapidamente e meios de entender tendências ao longo do tempo.

Nesta aula, vamos explorar o Prometheus, uma das ferramentas mais populares para coleta e análise de métricas no ecossistema cloud-native. Vamos entender seus conceitos fundamentais, os tipos de métricas que ele suporta, como configurar alertas proativos e como construir dashboards que transformam dados brutos em insights acionáveis. Ao final, você terá uma base sólida para implementar monitoramento eficaz nos seus próprios projetos.

Prometheus (visão geral)

O Prometheus é um sistema de monitoramento e alerta de código aberto, originalmente criado na SoundCloud em 2012 e atualmente um projeto da Cloud Native Computing Foundation (CNCF). Ele se destaca por seu modelo de coleta baseado em pull: o servidor Prometheus periodicamente busca (scrape) métricas de endpoints HTTP expostos pelas aplicações ou por exportadores. Isso difere de outras ferramentas que usam push (como o Graphite), e traz vantagens como maior facilidade de diagnóstico e operação.

O Prometheus armazena os dados em um banco de dados de séries temporais (TSDB) local, com um modelo de dados baseado em métricas identificadas por um nome e um conjunto de chaves/valores (labels). Ele oferece uma linguagem de consulta chamada PromQL, que permite realizar agregações, operações matemáticas e filtros complexos sobre as métricas. Além disso, integra-se facilmente com o Grafana para visualização e com o Alertmanager para envio de alertas.

Um exemplo típico de configuração de scrape no arquivo prometheus.yml:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']

Esse arquivo define que o Prometheus deve coletar métricas do endpoint localhost:9100 (que é o node_exporter, um exportador de métricas do sistema) a cada 15 segundos.

Tipos de métricas

O Prometheus define quatro tipos principais de métricas, cada um adequado para diferentes cenários. Entender esses tipos é crucial para modelar corretamente as informações que você quer coletar.

  • Counter: é um contador acumulativo que só aumenta (ou é resetado para zero em reinicializações). Ideal para contar eventos, como número de requisições, erros, ou itens processados. Por exemplo, o total de requisições HTTP recebidas.
  • Gauge: representa um valor que pode aumentar ou diminuir arbitrariamente, como temperatura, número de conexões ativas, ou uso de memória. É útil para valores instantâneos que podem ser medidos em qualquer momento.
  • Histogram: amostra observações (como duração de requisições) e conta-as em buckets configuráveis. Permite calcular percentis (como o 95º percentil) e também fornece um contador total e uma soma das observações.
  • Summary: similar ao histogram, mas calcula percentis diretamente no cliente (aplicação) e as expõe. Não permite agregação entre instâncias, mas é útil quando você precisa de percentis exatos sem a complexidade de buckets.

Para exemplificar, vamos ver como expor métricas em uma aplicação simples em Python usando a biblioteca prometheus_client:

from prometheus_client import Counter, Gauge, Histogram, start_http_server
import random
import time

# Cria métricas
requests_total = Counter('http_requests_total', 'Total de requisições', ['method', 'endpoint'])
temperature = Gauge('temperature_celsius', 'Temperatura atual em Celsius')
request_duration = Histogram('http_request_duration_seconds', 'Duração das requisições', buckets=[0.1, 0.5, 1, 2.5, 5])

# Inicia o servidor HTTP na porta 8000 para expor as métricas
start_http_server(8000)

while True:
    # Simula uma requisição
    requests_total.labels(method='GET', endpoint='/api').inc()
    temp = random.uniform(20, 30)
    temperature.set(temp)
    with request_duration.time():
        time.sleep(random.uniform(0.1, 0.5))
    time.sleep(1)

Nesse código, estamos criando um contador para o total de requisições, um gauge para temperatura e um histogram para a duração das requisições. O servidor HTTP na porta 8000 expõe as métricas no formato texto que o Prometheus pode coletar.

Alertas

Alertas são essenciais para detectar problemas antes que eles afetem os usuários. No ecossistema Prometheus, os alertas são definidos em regras de alerta (alerting rules) e são avaliados continuamente pelo servidor. Quando uma condição é atendida, o Prometheus envia uma notificação para o Alertmanager, que é responsável por deduplicar, agrupar e rotear as notificações para os canais apropriados (e-mail, Slack, PagerDuty, etc.).

A definição de alertas é feita em arquivos de regras, que são referenciados no prometheus.yml. Um exemplo de regra de alerta:

groups:
  - name: example-alerts
    rules:
      - alert: HighErrorRate
        expr: job:http_errors:rate5m > 0.05
        for: 10m
        labels:
          severity: critical
        annotations:
          summary: "Alta taxa de erros"
          description: "A taxa de erros está acima de 5% por mais de 10 minutos."

Aqui, definimos um alerta chamado HighErrorRate que avalia a expressão PromQL job:http_errors:rate5m > 0.05 (que deve ser uma regra de gravação, mas vamos considerar que já existe). A condição deve ser verdadeira por 10 minutos (for: 10m) para que o alerta seja disparado, evitando falsos positivos por picos momentâneos. O alerta tem um rótulo de severidade e anotações que descrevem o problema.

Para configurar o Alertmanager, você precisa de um arquivo de configuração que define rotas e receivers. Exemplo de alertmanager.yml:

route:
  group_by: ['alertname']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: 'email'

receivers:
  - name: 'email'
    email_configs:
      - to: 'devops@example.com'
        from: 'alertmanager@example.com'
        smarthost: 'smtp.example.com:587'

Esse arquivo define que todos os alertas serão enviados para o e-mail devops@example.com usando o servidor SMTP especificado. O roteamento pode ser mais complexo, com diferentes receivers para diferentes severidades ou equipes.

Dashboards

Dashboards são a forma mais comum de visualizar métricas, permitindo que equipes monitorem a saúde do sistema em tempo real. O Grafana é a ferramenta de visualização mais utilizada com Prometheus. Ele se conecta ao Prometheus como fonte de dados e permite criar painéis interativos com gráficos, tabelas e alertas visuais.

Para criar um dashboard no Grafana, você precisa adicionar uma fonte de dados Prometheus (configurando a URL, por exemplo, http://localhost:9090) e então criar um novo dashboard com painéis. Cada painel é baseado em uma consulta PromQL. Por exemplo, para mostrar a taxa de requisições por segundo, você pode usar a consulta:

sum(rate(http_requests_total[5m])) by (method)

Essa consulta calcula a taxa de aumento do contador http_requests_total em janelas de 5 minutos, agrupada pelo label method.

Um exemplo de código para configurar um dashboard via provisioning (arquivo YAML) no Grafana:

apiVersion: 1
providers:
  - name: 'default'
    orgId: 1
    folder: ''
    type: file
    disableDeletion: false
    editable: true
    options:
      path: /var/lib/grafana/dashboards

Esse arquivo informa ao Grafana para carregar dashboards de arquivos JSON localizados no diretório especificado. Isso permite versionar e gerenciar dashboards como código, uma prática conhecida como "Infrastructure as Code" (IaC).

Boas práticas e observações finais

Para tirar o máximo proveito do monitoramento, considere as seguintes recomendações:

  • Comece com métricas essenciais: colete métricas de recursos (CPU, memória, disco), de aplicação (latência, erros, throughput) e de negócio (vendas, usuários ativos). O padrão RED (Rate, Errors, Duration) para serviços e USE (Utilization, Saturation, Errors) para recursos são excelentes pontos de partida.
  • Use labels com moderação: labels são poderosas, mas um excesso pode aumentar a cardinalidade e degradar o desempenho do Prometheus. Mantenha o número de combinações de labels controlado.
  • Defina alertas acionáveis: cada alerta deve ter uma descrição clara, um runbook associado e a severidade correta. Evite alertas ruidosos que causem fadiga.
  • Documente seus dashboards: adicione anotações e descrições para que outros membros da equipe entendam o que cada gráfico representa.
  • Revise regularmente: métricas e alertas devem ser revistos e ajustados à medida que o sistema evolui.

Monitoramento é um processo contínuo. À medida que você ganha experiência, vai refinar suas consultas, alertas e painéis para melhor refletir a realidade do seu ambiente. Lembre-se de que o objetivo final é melhorar a confiabilidade e a experiência do usuário.

Referências

Exercícios

  1. Exercício 1: Explique a diferença entre os tipos de métricas Counter e Gauge no Prometheus, e dê um exemplo de uso para cada um.

    ✓ Resposta: Counter é um contador acumulativo que só aumenta (ou é resetado para zero em reinicializações), usado para contar eventos como requisições ou erros. Gauge é um valor que pode aumentar e diminuir, como temperatura ou conexões ativas. Exemplo de Counter: total de requisições HTTP. Exemplo de Gauge: número de conexões ativas no momento.
  2. Exercício 2: Escreva uma consulta PromQL que calcule a taxa de erros HTTP (contador http_errors_total) por minuto, agrupada por endpoint.

    ✓ Resposta:
    sum(rate(http_errors_total[1m])) by (endpoint)
  3. Exercício 3: Descreva o papel do Alertmanager no ecossistema Prometheus e cite duas funcionalidades principais que ele oferece.

    ✓ Resposta: O Alertmanager é responsável por gerenciar os alertas gerados pelo Prometheus. Suas principais funcionalidades incluem: deduplicação de alertas (evita múltiplas notificações para o mesmo problema), agrupamento (agrupa alertas relacionados em uma única notificação), e roteamento (envia alertas para diferentes destinos com base em regras como severidade ou equipe).
  4. Exercício 4: Cite três práticas recomendadas para criar dashboards eficazes no Grafana.

    ✓ Resposta: 1) Manter o dashboard focado em um objetivo específico (ex.: saúde do serviço). 2) Usar títulos e descrições claras em cada painel. 3) Utilizar variáveis para permitir filtros dinâmicos (por exemplo, selecionar o ambiente). 4) Evitar excesso de painéis para não poluir a visualização. 5) Revisar e atualizar regularmente os dashboards para refletir mudanças no sistema.
  5. Exercício 5: Suponha que você queira alertar quando o uso de CPU de um servidor ficar acima de 90% por mais de 5 minutos. Escreva uma regra de alerta YAML para isso, considerando que a métrica é node_cpu_seconds_total e que você está usando a taxa de utilização (use a função rate).

    ✓ Resposta:
    groups:
      - name: cpu-alerts
        rules:
          - alert: HighCPUUsage
            expr: 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 90
            for: 5m
            labels:
              severity: warning
            annotations:
              summary: "CPU alta"
              description: "Uso de CPU acima de 90% por mais de 5 minutos."