SLO e error budget: confiabilidade de APIs com Prometheus

    SLI (Service Level Indicator), SLO (Service Level Objective) e error budget são o vocabulário do Site Reliability Engineering para medir confiabilidade de forma objetiva. Em vez de "o sistema está lento", você diz "nosso P99 de latência está em 850ms e nosso SLO é 500ms — 68% do error budget foi consumido este mês".

    Conceitos: SLI, SLO e error budget

    Definir os três conceitos e como se relacionam:

    bash
    # SLI (Service Level Indicator):
    # → A métrica que mede o comportamento do serviço
    # Exemplos:
    #   Disponibilidade: % de requisições bem-sucedidas (status 2xx/3xx)
    #   Latência: % de requisições que respondem em < 500ms
    #   Throughput: requisições processadas por segundo
    
    # SLO (Service Level Objective):
    # → A meta que você quer atingir para o SLI
    # Exemplos:
    #   Disponibilidade: 99.9% das requisições devem ter status 2xx/3xx
    #   Latência: 95% das requisições devem responder em < 500ms
    
    # Error budget:
    # → O quanto de "não conformidade" é permitido
    # 99.9% de disponibilidade = 0.1% de erro permitido
    # Em 30 dias: 0.001 × 30 × 24 × 60 = 43 minutos de downtime permitido
    # Em 7 dias:  0.001 × 7 × 24 × 60 =  10 minutos de downtime permitido
    
    # Quando o error budget acaba:
    # → Parar novos deploys até o fim do período
    # → Focar em confiabilidade, não em features
    # → Isso alinha incentivos entre Dev e Ops
    
    # Conversão disponibilidade → tempo de downtime por mês:
    # 99.0%  → 7.2h
    # 99.5%  → 3.6h
    # 99.9%  → 43min  (three nines — padrão para a maioria das SaaS B2B)
    # 99.99% → 4.3min (four nines — para serviços críticos)

    Calcular SLI de disponibilidade com Prometheus

    Queries PromQL para medir disponibilidade em tempo real:

    bash
    # SLI de disponibilidade — % de requisições bem-sucedidas:
    # "Boas" = 2xx e 3xx | "Ruins" = 5xx
    # (4xx geralmente são erros do cliente, não do serviço)
    
    # Taxa de disponibilidade nas últimas 24h:
    sum(rate(http_request_duration_seconds_count{status_code!~"5.."}[24h]))
    /
    sum(rate(http_request_duration_seconds_count[24h]))
    
    # Error rate (1 - disponibilidade):
    sum(rate(http_request_duration_seconds_count{status_code=~"5.."}[24h]))
    /
    sum(rate(http_request_duration_seconds_count[24h]))
    
    # SLI de latência — % de requisições dentro do SLO de tempo:
    # SLO: 95% das requisições em < 500ms
    sum(rate(http_request_duration_seconds_bucket{le="0.5"}[1h]))
    /
    sum(rate(http_request_duration_seconds_count[1h]))
    
    # Janela deslizante de 30 dias (mais precisa para error budget mensal):
    sum(rate(http_request_duration_seconds_count{status_code!~"5.."}[30d]))
    /
    sum(rate(http_request_duration_seconds_count[30d]))
    
    # Recording rule para pré-computar (performance):
    # rules/slo.yml:
    # - record: job:sli_disponibilidade:ratio_rate1h
    #   expr: |
    #     sum(rate(http_request_duration_seconds_count{status_code!~"5.."}[1h]))
    #     / sum(rate(http_request_duration_seconds_count[1h]))

    Calcular e monitorar o error budget

    Acompanhar quanto do orçamento de erros foi consumido:

    yaml
    # Recording rules para SLO — definir uma vez e usar em múltiplos lugares:
    # prometheus/rules/slo.yml:
    groups:
      - name: slo-nodejs-api
        interval: 1m
        rules:
          # SLI: taxa de sucesso (janelas de tempo diferentes para alertas):
          - record: job:http_sli_sucesso:rate5m
            expr: |
              sum(rate(http_request_duration_seconds_count{job="nodejs-api",status_code!~"5.."}[5m]))
              / sum(rate(http_request_duration_seconds_count{job="nodejs-api"}[5m]))
    
          - record: job:http_sli_sucesso:rate1h
            expr: |
              sum(rate(http_request_duration_seconds_count{job="nodejs-api",status_code!~"5.."}[1h]))
              / sum(rate(http_request_duration_seconds_count{job="nodejs-api"}[1h]))
    
          - record: job:http_sli_sucesso:rate30d
            expr: |
              sum(rate(http_request_duration_seconds_count{job="nodejs-api",status_code!~"5.."}[30d]))
              / sum(rate(http_request_duration_seconds_count{job="nodejs-api"}[30d]))
    
    # Calcular error budget consumido:
    # SLO_TARGET = 0.999 (99.9%)
    # error_budget_total = 1 - SLO_TARGET = 0.001
    # error_budget_consumido = (1 - SLI) / (1 - SLO_TARGET) * 100
    
    # Query no Grafana — % de error budget consumido no mês:
    # (1 - job:http_sli_sucesso:rate30d) / (1 - 0.999) * 100
    
    # Exemplo de resultado:
    # SLI últimos 30d = 0.9995 (99.95%)
    # Error budget consumido = (1 - 0.9995) / (1 - 0.999) * 100 = 50%
    # → 50% do budget foi consumido, 50% resta

    Alertas baseados em burn rate do error budget

    Detectar quando o error budget está sendo consumido rápido demais:

    yaml
    # Alertas de burn rate — alertar quando o budget está sendo queimado em ritmo que,
    # se mantido, vai esgotar o budget antes do fim do mês.
    
    # burn_rate = taxa atual de erro / taxa de erro permitida pelo SLO
    # Se burn_rate = 1: consumindo budget exatamente no ritmo
    # Se burn_rate = 10: consumindo 10x mais rápido → budget esgota em 3 dias (30/10)
    
    # SLO = 99.9% → error_rate_permitida = 0.001
    
    # alerts/slo.yml:
    groups:
      - name: slo-burn-rate
        rules:
          # CRÍTICO: burn rate > 14.4x nas últimas 1h
          # (esgota o budget mensal em ~2 dias)
          - alert: SloBurnRateCritico
            expr: |
              (1 - job:http_sli_sucesso:rate5m) / 0.001 > 14.4
              AND
              (1 - job:http_sli_sucesso:rate1h) / 0.001 > 14.4
            for: 2m
            labels:
              severity: critical
              slo: disponibilidade
            annotations:
              summary: "SLO: burn rate crítico — budget esgotará em ~2 dias"
              description: |
                Burn rate atual: {{ $value | printf "%.1f" }}x.
                Error rate: {{ with query "1 - job:http_sli_sucesso:rate5m" }}{{ . | first | value | humanizePercentage }}{{ end }}.
    
          # WARNING: burn rate > 6x nas últimas 6h
          # (esgota o budget mensal em ~5 dias)
          - alert: SloBurnRateAlto
            expr: |
              (1 - job:http_sli_sucesso:rate5m) / 0.001 > 6
            for: 15m
            labels:
              severity: warning
              slo: disponibilidade
            annotations:
              summary: "SLO: burn rate elevado — atenção ao error budget"

    Dashboard de SLO no Grafana

    Painel visual de SLO com semáforo e histórico de compliance:

    bash
    # Painéis Grafana para SLO:
    
    # 1. Stat panel — SLI atual (com threshold colorido):
    # Query: job:http_sli_sucesso:rate30d * 100
    # Thresholds:
    #   verde: >= 99.9 (dentro do SLO)
    #   amarelo: 99.5 a 99.9 (dentro do budget mas atenção)
    #   vermelho: < 99.5 (violação do SLO)
    # Unit: percent
    
    # 2. Stat panel — Error budget restante %:
    # Query: (1 - (1 - job:http_sli_sucesso:rate30d) / 0.001) * 100
    # Thresholds:
    #   verde: > 50%
    #   amarelo: 10% a 50%
    #   vermelho: < 10%
    
    # 3. Time series — Burn rate ao longo do tempo:
    # Query: (1 - job:http_sli_sucesso:rate5m) / 0.001
    # Linha de referência em y=1 (taxa normal) e y=6 (alerta)
    
    # 4. Time series — SLI ao longo do mês (comparar com SLO):
    # Query: job:http_sli_sucesso:rate1h * 100
    # Linha de referência em y=99.9 (SLO target)
    
    # Importar template pronto: Grafana ID 14348 — SLO Dashboard
    
    # Documentar o SLO em arquivo de configuração:
    # slos/nodejs-api.yml:
    # service: nodejs-api
    # slos:
    #   - name: disponibilidade
    #     indicator: taxa de requisições 2xx/3xx
    #     target: 99.9
    #     window: 30d
    #   - name: latencia
    #     indicator: P95 < 500ms
    #     target: 95.0
    #     window: 30d

    $ runstack deploy --plan starter

    Não quer configurar manualmente?

    Não quer configurar manualmente? Implante o VPS para Node.js em menos de 3 minutos com a Runstack. Infraestrutura da OPEN DATACENTER, com servidores no Brasil.

    Perguntas frequentes