404 Not Found

404 Not Found


nginx

Monitoramento — Observabilidade Full-Stack com Prometheus + Grafana

Monitoramento é como o painel de um carro—o velocímetro (QPS), temperatura do óleo (latência) e luz do motor (taxa de erro) mantêm você informado sobre a saúde do carro (sistema) a todo momento. Sem um painel, você só saberia que algo estava errado quando a fumaça começasse a sair do motor.

1. O Que Você Vai Aprender


2. A História Real da Alice

(1) Dor: Você Só Percebe o Problema Quando Ele Acontece

Às 3 da manhã, o pool de conexões do banco de dados do PriceTracker se esgotou, e a API começou a retornar erros 500. Alice só descobriu às 8 da manhã, quando os usuários começaram a reclamar. Sem monitoramento em tempo real, Charlie só pôde revisar os logs depois do fato e descobriu que o pool de conexões estava disparando alertas desde as 5 da manhã—se o monitoramento estivesse em vigor, o problema poderia ter sido detectado e resolvido em cinco minutos.

(2) Solução com Prometheus e Grafana

O Prometheus coleta métricas (número de requisições, latência, taxa de erro) a cada segundo; o Grafana as visualiza em tempo real; e o AlertManager envia alertas automaticamente quando as métricas se desviam dos intervalos normais—mudando o processo de "saber dos problemas apenas após reclamações de usuários" para "notificações automáticas em 5 minutos."

(3) Resultado

Picos de latência P99 disparam um alerta em menos de um minuto; notificações automáticas são enviadas antes que o pool de conexões do banco de dados se esgote; o tempo de detecção de problemas foi reduzido de "horas" para "minutos," então Charlie não precisa mais ficar olhando para a tela 24 horas por dia.


3. Expondo Métricas Prometheus

(1) Arquitetura de Monitoramento

100%
flowchart LR
    App[FastAPI App] -->|/metrics| Prom[Prometheus]
    Prom -->|Query| Grafana[Grafana Dashboard]
    Prom -->|Alert| AlertMgr[AlertManager]
    AlertMgr -->|Notify| Slack[Slack / Email]
    Grafana -->|Visualize| Charlie[Charlie DevOps]

(1) ▶ Exemplo: Integração com prometheus-fastapi-instrumentator

PYTHON
# Instalar: uv add prometheus-fastapi-instrumentator
from fastapi import FastAPI
from prometheus_fastapi_instrumentator import Instrumentator

app = FastAPI()

# Adicionar métricas padrão: contagem de requisições, duração, tamanho, exceções
Instrumentator().instrument(app).expose(app)

# Agora o endpoint /metrics expõe métricas Prometheus
# Incluindo: http_requests_total, http_request_duration_seconds, etc.

Saída:

TEXT
# Execução Bem-sucedida

(2) ▶ Exemplo: Métricas Personalizadas

PYTHON
from prometheus_client import Counter, Histogram, Gauge
from fastapi import FastAPI

app = FastAPI()

# Métricas de negócio personalizadas
PRICE_UPDATES = Counter(
    "pricetracker_price_updates_total",
    "Número total de atualizações de preços",
    ["category", "currency"],
)

REQUEST_LATENCY = Histogram(
    "pricetracker_request_latency_seconds",
    "Latência de requisição em segundos",
    buckets=[0.01, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0],
)

ACTIVE_USERS = Gauge(
    "pricetracker_active_users",
    "Número de usuários ativos nos últimos 5 minutos",
)

CACHE_HIT_RATE = Gauge(
    "pricetracker_cache_hit_rate",
    "Porcentagem de taxa de hit do cache Redis",
)

@app.post("/api/v1/prices")
async def create_price(price: PriceCreate):
    result = await service.create_price(price)
    # Registrar métrica personalizada
    PRICE_UPDATES.labels(category="electronics", currency="USD").inc()
    return result

Saída:

TEXT
# Função definida com sucesso

(2) Métricas Chave do Método RED

Métrica Tipo Descrição PromQL
Rate Counter Taxa de Requisição (QPS) rate(http_requests_total[5m])
Errors Counter Taxa de Erro rate(http_requests_total{status=~"5.."}[5m])
Duration Histogram Distribuição de Latência histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

4. Design do Dashboard Grafana

(1) Layout do Dashboard

100%
graph TD
    Title[Dashboard de Monitoramento PriceTracker]
    Title --> Row1[Linha 1: Visão Geral]
    Row1 --> QPS[QPS - Rate]
    Row1 --> P50[P50 Latência]
    Row1 --> P99[P99 Latência]
    Row1 --> ErrRate[Taxa de Erro]
    
    Title --> Row2[Linha 2: Negócio]
    Row2 --> PriceUpd[Atualizações de Preço/min]
    Row2 --> ActiveUsers[Usuários Ativos]
    Row2 --> CacheHit[Taxa de Hit do Cache]
    
    Title --> Row3[Linha 3: Infraestrutura]
    Row3 --> DBConns[Conexões DB]
    Row3 --> RedisConns[Conexões Redis]
    Row3 --> CeleryQ[Tamanho da Fila Celery]

(1) ▶ Exemplo: Configuração JSON do Dashboard Grafana (Trecho)

JSON
{
  "dashboard": {
    "title": "Monitoramento PriceTracker",
    "panels": [
      {
        "title": "Taxa de Requisição (QPS)",
        "type": "timeseries",
        "targets": [
          {
            "expr": "sum(rate(http_requests_total[5m]))",
            "legendFormat": "QPS Total"
          }
        ]
      },
      {
        "title": "Latência P99",
        "type": "stat",
        "targets": [
          {
            "expr": "histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))",
            "legendFormat": "P99"
          }
        ],
        "thresholds": {
          "steps": [
            { "value": 0, "color": "green" },
            { "value": 0.1, "color": "yellow" },
            { "value": 0.5, "color": "red" }
          ]
        }
      },
      {
        "title": "Taxa de Hit do Cache",
        "type": "gauge",
        "targets": [
          {
            "expr": "pricetracker_cache_hit_rate",
            "legendFormat": "Taxa de Hit %"
          }
        ]
      }
    ]
  }
}

Saída:

JSON
{
  "dashboard": {
    "title": "Monitoramento PriceTracker",
    "panels": [
      {
        "title": "Taxa de Requisição (QPS)",
        "type": "timeseries",
        "targets": [
          {
            "expr": "sum(rate(http_requests_total[5m]))",
            "legendFormat": "QPS Total"
          }
        ]
      },
      {
        "title": "Latência P99",
        "type": "stat",
        "targets": [
          {
            "expr": "histogram_quantile(0.99, sum(rate(http_request_duration_seconds_buck

5. Regras de Alerta

(1) ▶ Exemplo: Regras de Alerta do Prometheus

YAML
# prometheus/alert_rules.yml
groups:
  - name: pricetracker_alerts
    rules:
      - alert: HighP99Latency
        expr: histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) > 0.5
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Latência P99 excede 500ms"
          description: "Latência P99 é {{ $value }}s, limite é 0.5s"

      - alert: HighErrorRate
        expr: sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.05
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Taxa de erro excede 5%"
          description: "Taxa de erro é {{ $value | humanizePercentage }}"

      - alert: LowCacheHitRate
        expr: pricetracker_cache_hit_rate < 60
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "Taxa de hit do cache abaixo de 60%"
          description: "Taxa de hit atual é {{ $value }}%"

      - alert: DatabaseConnectionPoolExhausted
        expr: pricetracker_db_connections_in_use / pricetracker_db_connections_max > 0.9
        for: 3m
        labels:
          severity: critical
        annotations:
          summary: "Pool de conexões do banco de dados > 90% utilizado"

Saída:

TEXT
Configuração de monitoramento carregada
Prometheus targets: 3 ativos
Dashboard Grafana: pronto

(2) ▶ Exemplo: Adicionando Stack de Monitoramento ao Docker Compose

YAML
# Adicionar ao docker-compose.yml
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./docker/prometheus.yml:/etc/prometheus/prometheus.yml
      - ./docker/alert_rules.yml:/etc/prometheus/alert_rules.yml
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--alert.rule-files=/etc/prometheus/alert_rules.yml'

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana

  alertmanager:
    image: prom/alertmanager:latest
    ports:
      - "9093:9093"
    volumes:
      - ./docker/alertmanager.yml:/etc/alertmanager/alertmanager.yml

Saída:

TEXT
CONTAINER ID   IMAGE          STATUS         PORTS
abc123         nginx:latest   Up 2 hours     0.0.0.0:80->80/tcp

(3) ▶ Exemplo: Configuração prometheus.yml

YAML
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: "pricetracker-api"
    metrics_path: "/metrics"
    static_configs:
      - targets: ["api:8000"]

rule_files:
  - "alert_rules.yml"

alerting:
  alertmanagers:
    - static_configs:
        - targets: ["alertmanager:9093"]

Saída:

TEXT
A configuração entrou em vigor.

❓ Perguntas Frequentes

P Qual é a diferença entre Prometheus e ELK?
R Prometheus é para monitoramento de métricas (séries temporais numéricas), enquanto ELK é para análise de logs (busca textual). Os dois são complementares—Prometheus é usado para monitorar tendências e gerar alertas, enquanto ELK é usado para revisar logs detalhados para solucionar problemas.
P Qual deve ser o intervalo de coleta de métricas?
R O padrão de 15 segundos oferece um bom equilíbrio. Um intervalo menor (5 segundos) fornece dados mais em tempo real, mas incorre em maiores custos de armazenamento, enquanto um intervalo maior (60 segundos) economiza armazenamento, mas pode perder flutuações breves.
P Muitas métricas personalizadas deixarão a aplicação lenta?
R Cada métrica incorre em um pequeno overhead de CPU. Recomendamos usar menos de 100 métricas personalizadas. A cardinalidade dos labels (o número de valores distintos) tem um impacto maior na performance do que o número de métricas; evite labels com alta cardinalidade (como user_id).
P Como compartilhar um dashboard Grafana?
R Exporte-o como arquivo JSON, e sua equipe pode importá-lo. Grafana.com oferece uma ampla variedade de templates prontos para referência.
P O que fazer se houver muitos alertas (fadiga de alerta)?
R Configure uma duração "for" razoável (para evitar gatilhos causados por flutuações momentâneas), classifique alertas como "warning" ou "critical," agrupe alertas relacionados, e reduza o ruído nos canais de notificação.
P Como monitorar tarefas Celery?
R O Flower fornece monitoramento em nível de tarefa e expõe métricas Prometheus. Métricas chave incluem taxa de sucesso das tarefas, comprimento da fila e uso de memória dos workers.

📖 Resumo


📝 Exercícios

  1. Exercício Básico (Dificuldade: ⭐): Adicione prometheus-fastapi-instrumentator ao FastAPI e verifique se o endpoint /metrics retorna as métricas HTTP padrão (como http_requests_total). Dica: Instrumentator().instrument(app).expose(app)
  2. Exercício Avançado (Dificuldade ⭐⭐): Adicione três métricas personalizadas—PRICE_UPDATES (Counter por categoria), REQUEST_LATENCY (Histogram com buckets de percentil), e CACHE_HIT_RATE (Gauge)—e registre os valores das métricas no endpoint. Dica: Counter(..., ["category"]) + .labels(category="electronics").inc()
  3. Desafio (Dificuldade: ⭐⭐⭐): Adicione Prometheus, Grafana e AlertManager ao Docker Compose; configure prometheus.yml para coletar métricas do FastAPI; escreva duas regras de alerta—uma para P99 > 500 ms e outra para taxa de erro > 5%; e importe o dashboard no Grafana para visualizar métricas em tempo real. Dica: docker/prometheus.yml + alert_rules.yml + configuração de fonte de dados Grafana

---|

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%