MÓDULO 10 · CONCEITO 07 DE 12

Dashboards e Grafana

Golden signals, USE method, variáveis de template, dashboard as code com Grafonnet/Terraform, SLO dashboards e correlação de sinais

Tempo de leitura ~30 min Pré-requisito 06 · Alertas e On-call Próximo 08 · Log Aggregation

Um dashboard é uma hipótese sobre o que importa monitorar. Dashboards criados sem critério acumulam panels que sempre estão "verdes", não respondem perguntas reais durante incidentes, e criam uma falsa sensação de visibilidade. A diferença entre um dashboard útil e um de vaidade está na pergunta que guia cada panel: "se este panel estiver vermelho, sei exatamente o que fazer?" — se a resposta for não, o panel não deveria existir ou precisar ser reformulado.

Os 4 Golden Signals

O Google SRE Book define quatro sinais que, juntos, capturam o estado de saúde de qualquer serviço orientado a requests. Um dashboard bem construído começa com eles — qualquer dashboard que não responda a esses quatro sinais está incompleto para uso operacional.

1. Latência

O tempo que leva para servir um request. Crucial: distinguir a latência de requests com sucesso da latência de requests com erro. Um erro que retorna em 1ms e um sucesso que demora 800ms são comportamentos completamente diferentes — misturá-los distorce o percentil puxando-o artificialmente para baixo. Prefira histogramas a médias: a média de latência esconde a long tail. P50, P95, P99 revelam a experiência dos diferentes percentis de usuários. Um P50 de 50ms com P99 de 5s indica que 1% dos usuários tem uma experiência péssima que a média mascara completamente.

2. Traffic (Tráfego)

A demanda sendo colocada sobre o sistema. Para serviços HTTP: requests por segundo. Para bancos de dados: queries por segundo. Para streaming: mensagens por segundo ou bytes/s. O tráfego é o denominador que dá contexto a erros e latência — 10 erros em 100 req/s (10%) é um incidente grave; 10 erros em 10.000 req/s (0.1%) pode estar dentro do SLO.

3. Errors (Erros)

A taxa de requests que falham. Inclui falhas explícitas (5xx), implícitas (200 com payload inválido ou truncado), e por política (requests que violam SLO de latência — um 200 em 10 segundos pode ser considerado falha funcional). O error rate deve ser visualizado como fração do tráfego total, não como contagem absoluta, para ter sentido independente do volume.

4. Saturation (Saturação)

Quão "cheio" está o serviço — a fração da capacidade total sendo utilizada. CPU, memória, I/O de disco, pool de conexões, tamanho de fila de mensagens. A saturação é preditiva: um serviço em 80% de CPU provavelmente vai degradar antes de chegar a 100%. Acompanhe a tendência (rate of change) além do valor instantâneo — crescimento linear de uso de memória aponta para um memory leak antes que cause OOM.

USE method

Brendan Gregg define o USE Method para recursos de sistema: Utilization (quanto do recurso está em uso — ex: CPU a 75%), Saturation (quanto trabalho está enfileirado ou sendo atrasado — ex: run queue > nCPUs), Errors (taxa de erros do próprio recurso — ex: disk I/O errors). O USE method é orientado a recursos; o Golden Signals é orientado a serviços. Juntos cobrem os dois lados: o que o usuário está experimentando (Golden Signals) e por que o sistema está se comportando assim (USE).

Estrutura de um Dashboard Eficaz

Um dashboard mal estruturado é tão prejudicial quanto nenhum dashboard — causa confusão durante incidentes e dificulta a leitura de tendências. O princípio fundamental: organize do macro para o micro.

Hierarquia top-down

Visão de saúde geral no topo (SLO status, error budget), depois golden signals por serviço, depois detalhes (por endpoint, por instância, por região). Durante um incidente, você lê de cima para baixo — a primeira linha deve responder "está tudo bem?" em 5 segundos. Detalhes de diagnóstico ficam em rows colapsáveis ou dashboards separados.

Consistência de time range

Todos os panels do mesmo dashboard devem usar o mesmo time range via variável $__timeRange. Mixar panels com ranges fixos diferentes cria comparações enganosas — um spike parece diferente dependendo do zoom. Evite hardcodar ranges em panels individuais; use sempre o time range global do dashboard.

Thresholds visuais nos panels

Grafana suporta thresholds visuais: linha vermelha ou fundo colorido ao cruzar um valor. Use isso para mostrar o SLO target diretamente no gráfico — o engenheiro vê imediatamente quando a métrica está abaixo do objetivo sem precisar lembrar o número de cabeça.

Data links para correlação

Configure data links: clicar em um spike de error rate deve abrir o trace correspondente no Jaeger/Tempo, ou os logs correlacionados no Loki. Essa navegação entre sinais é o que diferencia um stack de observabilidade integrado de ferramentas desconectadas.

// Data link no Grafana — de métrica para trace (Tempo)
{
  "title": "View traces",
  "url": "/explore?left=${__data.fields.traceID}&datasource=Tempo",
  "targetBlank": true
}

// Data link de métrica para logs (Loki) — com correlação por label
{
  "title": "View logs for ${__series.name}",
  "url": "/explore?left={\"datasource\":\"Loki\",\"queries\":[{\"expr\":\"{service=\\\"${__series.name}\\\"}|=\\\"error\\\"\"}]}&from=${__value.time}&to=${__value.time}+300000",
  "targetBlank": true
}

Variáveis de Template

Variáveis de template tornam dashboards reutilizáveis através de serviços, ambientes e instâncias — eliminam a necessidade de duplicar dashboards para cada variação. Um único dashboard parametrizado por $environment e $service serve toda a plataforma.

// Variável: ambiente (query em labels do Prometheus)
name: environment
type: query
query: label_values(http_requests_total, environment)
// resultado: [production, staging, development]

// Variável: serviço (dependente do ambiente selecionado)
name: service
type: query
query: label_values(http_requests_total{environment="$environment"}, service)

// Variável: instância (dependente do serviço selecionado)
name: instance
type: query
query: label_values(up{service="$service"}, instance)

// Variável de intervalo — adapta a resolução ao zoom do time range
name: interval
type: interval
values: [1m, 5m, 10m, 30m, 1h]
auto: true  // Grafana escolhe baseado no time range ativo

// Uso nos panels:
// rate(http_requests_total{
//   environment="$environment",
//   service="$service"
// }[$interval])
multi-value e all

Habilite multi-value quando fizer sentido comparar instâncias lado a lado — ex: latência por instância para detectar hot spots onde uma instância específica está degradada. Use "Include All option" para toggle rápido entre "todos os serviços" e um serviço específico. O Grafana gera automaticamente o regex correto para PromQL com multi-value: {service=~"$service"}. Variáveis dependentes (serviço depende do ambiente) são recalculadas automaticamente quando o valor pai muda.

Dashboard as Code

Dashboards criados manualmente na UI têm os mesmos problemas que infraestrutura sem IaC: impossível revisar mudanças em PR, difícil replicar entre ambientes, sem histórico de alterações, e sem forma de garantir consistência entre dashboards de serviços diferentes. Dashboard as code resolve isso tratando dashboards como artefatos de software.

Abordagens

// Terraform — dashboard e alerta de SLO como código
resource "grafana_dashboard" "service_overview" {
  config_json = templatefile("${path.module}/dashboards/service-overview.json", {
    datasource = var.prometheus_datasource_uid
    service    = var.service_name
  })
  folder = grafana_folder.team_platform.id
}

resource "grafana_rule_group" "slo_alerts" {
  name             = "${var.service_name}-slo"
  folder_uid       = grafana_folder.team_platform.uid
  interval_seconds = 60

  rule {
    name      = "HighErrorBurnRate"
    condition = "C"

    data {
      ref_id         = "A"
      datasource_uid = var.prometheus_datasource_uid
      model = jsonencode({
        expr = "rate(http_requests_total{status=~'5..', service='${var.service_name}'}[1h]) / rate(http_requests_total{service='${var.service_name}'}[1h])"
      })
    }

    data {
      ref_id         = "C"
      datasource_uid = "__expr__"
      model = jsonencode({
        type       = "threshold"
        conditions = [{ evaluator = { type = "gt", params = [0.01] } }]
      })
    }

    annotations = {
      summary     = "${var.service_name}: high error rate"
      runbook_url = "https://wiki.internal/runbooks/${var.service_name}"
    }
    labels = {
      severity = "page"
      team     = var.team
    }
  }
}

SLO Dashboard

Um dashboard de SLO é separado dos dashboards operacionais — seu propósito é responder perguntas de negócio: "quanto do error budget resta? estamos consumindo budget em ritmo sustentável? quando o budget vai esgotar se mantiver o ritmo atual?"

// PromQL — panels essenciais de um SLO dashboard

// Panel 1: Success Rate atual (stat/gauge)
sum(rate(http_requests_total{status!~"5.."}[5m]))
/ sum(rate(http_requests_total[5m]))
// threshold: red < 0.998, yellow < 0.999, green >= 0.999

// Panel 2: Error Budget Restante (gauge em %)
1 - (
  (1 - avg_over_time(
    (
      sum(rate(http_requests_total{status!~"5.."}[5m]))
      / sum(rate(http_requests_total[5m]))
    )[30d:5m]
  ))
  / (1 - 0.999)  // dividido pelo budget total (0.001)
)
// threshold: red < 0, yellow < 0.25, green >= 0.25

// Panel 3: Burn Rate 1h (stat)
(1 - sum(rate(http_requests_total{status!~"5.."}[1h])) / sum(rate(http_requests_total[1h])))
/ (1 - 0.999)
// threshold: red > 14.4, yellow > 6, green <= 6

// Panel 4: Série histórica 30d com SLO target (timeseries)
avg_over_time(
  (
    sum(rate(http_requests_total{status!~"5.."}[5m]))
    / sum(rate(http_requests_total[5m]))
  )[30d:1h]
)
// Adicionar constant threshold line em 0.999 — área abaixo é erro acumulado visível

// Panel 5: Budget consumido por dia (bar chart)
// Minutos de budget consumidos em cada dia
(1 - day:success_rate:avg) * 24 * 60
grafana SLO plugin

O Grafana 10+ tem SLO plugin nativo: você define o SLO (datasource, query de sucesso, query total, target percentual, janela) e o Grafana gera automaticamente o dashboard com todos os panels acima e as regras de alerta de burn rate correspondentes. Reduz significativamente o boilerplate de configuração manual e garante consistência entre os dashboards de SLO de diferentes serviços.

Correlação de Sinais no Grafana

O valor máximo do Grafana aparece quando você conecta métricas, logs e traces em um único workflow de investigação. Sem correlação, você navega manualmente entre ferramentas copiando timestamps e IDs — com correlação, a navegação é um clique.

Métricas → Traces via Exemplars

Quando o Prometheus scrape inclui exemplars em histogramas (OTel os emite automaticamente), o Grafana exibe diamantes no gráfico de série temporal. Clicar em um diamante abre o trace correspondente no Tempo — você vai diretamente do spike do P99 para o trace que causou aquele spike.

Logs → Traces via Trace ID

Se os logs contêm o trace_id (injetado via OTel Logs Bridge), o Loki Explore detecta automaticamente o campo e exibe um botão "View Trace" — abre o trace no Tempo sem busca manual. Configure "derived fields" no datasource Loki para ativar essa detecção.

Traces → Logs via Trace ID

No Tempo, o Grafana mostra logs do Loki correlacionados ao trace — todos os logs emitidos durante o span são exibidos ao lado do trace waterfall. Requer configuração de "trace to logs" no datasource Tempo.

// Grafana datasource Tempo — configuração de correlação bidirecional
{
  "tracesToLogsV2": {
    "datasourceUid": "loki-uid",
    "spanStartTimeShift": "-1m",
    "spanEndTimeShift": "1m",
    "tags": ["service.name", "host.name"],
    "filterByTraceID": true,
    "filterBySpanID": false,
    "customQuery": true,
    "query": "{service=\"${__tags.service.name}\"} |= \"${__trace.traceId}\""
  },
  "tracesToMetrics": {
    "datasourceUid": "prometheus-uid",
    "queries": [
      {
        "name": "Request rate",
        "query": "rate(http_requests_total{service=\"$${__tags.service.name}\"}[5m])"
      },
      {
        "name": "Error rate",
        "query": "rate(http_requests_total{service=\"$${__tags.service.name}\",status=~\"5..\"}[5m])"
      }
    ]
  }
}

Anti-patterns de Dashboard

Decisões de engenharia

Dashboard por serviço ou por domínio?

Ambos, em níveis diferentes. Dashboard de serviço: golden signals e SLO de um serviço específico — ponto de entrada durante on-call. Dashboard de domínio (ex: checkout, payments): visão cross-service de uma jornada de usuário — útil para entender impacto de negócio de um incidente que afeta múltiplos serviços. Dashboard de plataforma: todos os serviços em visão compacta (status + error budget) — triagem inicial de incidentes. A hierarquia: plataforma → domínio → serviço → detalhe por endpoint/instância.

Grafana Cloud vs self-hosted?

Grafana Cloud: zero operação, LGTM stack integrado (Loki, Grafana, Tempo, Mimir), free tier generoso para times pequenos, SLA gerenciado. Self-hosted: controle total de dados (importante para compliance), sem custo de SaaS, dados nunca saem da sua infra. O custo oculto do self-hosted: operar Loki + Mimir + Tempo + Grafana em alta disponibilidade é um projeto de engenharia em si. Para a maioria dos times de produto com menos de 50 engenheiros, Grafana Cloud é a escolha certa. Self-hosted faz sentido quando compliance, soberania de dados ou custo a escala justificam.

Qual ferramenta de dashboard as code?

Terraform grafana provider: boa escolha se o time já usa Terraform — dashboard, alertas, datasources e pastas no mesmo workflow de IaC. Grafonnet: expressivo para times que precisam de muita programabilidade e geração de dashboards parametrizados. JSON + Git: zero dependências, começo mais simples, mas diffs ilegíveis em mudanças grandes. Estratégia pragmática: começar com JSON versionado (simples, sem overhead), migrar para Terraform quando a escala de serviços justificar abstrações e automação de deploy.

Exemplars vs logging de trace ID: como decidir?

Exemplars são a correlação de maior valor: vinculam um ponto específico na série temporal ao trace exato que causou aquele comportamento — navegação direta do P99 para o trace culpado. Requerem suporte no SDK (OTel suporta), Prometheus configurado para armazenar exemplars, e o datasource Grafana configurado para exibi-los. Trace ID nos logs é mais fácil de implementar (OTel Logs Bridge injeta automaticamente) e cobre o caminho logs → traces. Para correlação completa, implemente ambos: exemplars para métricas → traces, trace_id nos logs para logs → traces, e configure trace to logs no Tempo para traces → logs.

Como praticar

  1. Crie um dashboard de golden signals parametrizado com variáveis de template para $environment e $service: um panel de error rate (fração de 5xx sobre total), um panel de latência (P50/P95/P99 via histograma), um panel de tráfego (req/s), e um panel de saturation (CPU ou pool de conexões). Adicione thresholds visuais no panel de error rate com o SLO target.
    Critério: trocar $environment de production para staging exibe as métricas corretas sem editar nenhuma query; o panel de latência mostra três linhas (P50/P95/P99) e não a média; o panel de error rate tem threshold visual vermelho acima do SLO; o dashboard funciona para pelo menos 2 serviços diferentes sem duplicação.
  2. Configure correlação completa de sinais em um stack local (Docker Compose com Prometheus, Grafana, Tempo, Loki, OTel Collector): habilite exemplars no histograma de latência, configure o datasource Prometheus no Grafana para exibir exemplars com link para Tempo, e configure trace to logs no datasource Tempo. Gere requests e valide a navegação completa: spike na métrica → clique no diamante → trace no Tempo → logs do trace no Loki.
    Critério: diamantes (exemplars) aparecem no gráfico de latência P99; clicar em um diamante abre o trace correspondente no Tempo; dentro do trace, o botão "Logs for this span" exibe logs do Loki com o mesmo trace_id; a navegação completa funciona em menos de 3 cliques.
  3. Implemente um SLO dashboard completo para um serviço: success rate atual (stat), error budget restante em % (gauge com threshold em 25%), burn rate da última 1h (stat com threshold em 14.4×), e série histórica de 30 dias com linha de referência do SLO target. Valide que os panels mostram os valores corretos simulando diferentes níveis de erro.
    Critério: o gauge de error budget muda para amarelo abaixo de 25% e vermelho abaixo de 0%; o stat de burn rate muda para vermelho acima de 14.4×; a série histórica de 30 dias exibe a linha de SLO target horizontal; as queries usam recorded rules (não recalculam a janela de 30 dias bruta a cada refresh).
  4. Versione um dashboard existente como código usando Terraform + grafana provider: exporte o JSON atual do dashboard, adapte-o como recurso grafana_dashboard com variáveis (service_name, datasource_uid), e aplique em um Grafana local via terraform apply. Faça uma mudança pequena (adicionar um panel), revise o diff do Terraform, e aplique.
    Critério: terraform plan mostra o dashboard como recurso a criar; após apply, o dashboard aparece no Grafana com o conteúdo correto; a mudança incremental produz um diff legível no terraform plan; o dashboard pode ser destruído e recriado a partir do código sem perda de configuração.
  5. Conduza uma auditoria de anti-patterns em um conjunto de dashboards existentes (pode ser um projeto de exemplo público do Grafana): identifique pelo menos 4 anti-patterns da lista (vaidade, médias sem percentis, escala Y inadequada, sem variáveis de template, etc.), documente cada um com uma captura de tela ou descrição do panel problemático, e proponha a versão corrigida de cada um.
    Critério: pelo menos 4 anti-patterns identificados com justificativa específica (não genérica); cada anti-pattern tem a query ou configuração corrigida proposta; pelo menos um panel de latência com média foi substituído por P50/P95/P99; a auditoria está documentada em formato que poderia ser compartilhado com o time para guiar futuras revisões de dashboard.

Perguntas de entrevista

    Quais são os 4 Golden Signals e por que latência de erros deve ser separada da latência de sucesso?

    Os 4 Golden Signals (Google SRE Book): Latência (tempo para servir um request), Traffic (volume de demanda — req/s, queries/s, bytes/s), Errors (taxa de requests falhos, explícitos e implícitos), e Saturation (fração da capacidade utilizada — CPU, memória, pool de conexões, filas).

    Latência de erros deve ser separada porque erros geralmente retornam muito rápido — uma exceção lançada imediatamente tem latência de 1-5ms. Se você mistura latência de erros com latência de sucesso, o percentil aparece artificialmente baixo (puxado para baixo pelos erros rápidos). O insight que importa é: "qual a experiência dos usuários que receberam uma resposta válida?" — para isso, filtre os erros da métrica de latência com status!~"5.." na query de latência e crie uma query separada para error rate.

    O que é dashboard as code e quais são as vantagens em relação a dashboards criados na UI?

    Dashboard as code é a prática de definir dashboards em arquivos de configuração (JSON, Jsonnet, HCL) versionados em Git, ao invés de criá-los manualmente na UI. Vantagens: (1) Revisão via PR — mudanças em dashboards passam pelo mesmo processo de code review que código; (2) Replicabilidade — o mesmo dashboard pode ser deployado em múltiplos ambientes sem trabalho manual; (3) Histórico de mudanças — git log mostra quem mudou o quê e por quê; (4) Consistência — abstrações (funções que geram panels padrão de golden signals) garantem que todos os serviços têm o mesmo layout; (5) Disaster recovery — se o Grafana for perdido, os dashboards são recriados automaticamente no próximo Terraform apply. A principal desvantagem é o overhead inicial — criar o primeiro dashboard as code é mais trabalhoso do que arrastar panels na UI.

    Como você implementaria correlação entre métricas, logs e traces no Grafana?

    Em três conexões: (1) Métricas → Traces via Exemplars: configure a instrumentação para emitir exemplars nos histogramas (OTel faz isso automaticamente). No Prometheus, habilite enable-feature=exemplar-storage. No Grafana, configure o datasource Prometheus com link de exemplar apontando para o datasource Tempo. O Grafana exibe diamantes clicáveis no gráfico — cada diamante abre o trace que causou aquele ponto da série. (2) Logs → Traces: injete o trace_id nos logs (OTel Logs Bridge faz automaticamente). Configure "derived fields" no datasource Loki que reconhece o campo trace_id e gera link para o Tempo. (3) Traces → Logs: na configuração do datasource Tempo, configure "Trace to logs" com query Loki que filtra por trace_id e serviço. O resultado é navegação completa: pico na métrica → trace representativo → logs do trace — tudo com um clique em cada etapa.

    Por que usar percentis em vez de médias para latência? O que é a "long tail" e por que ela importa?

    A média oculta informação crítica sobre a distribuição de latência. Exemplo: 99 requests com latência de 10ms e 1 request com latência de 10.000ms resultam em média de 109ms — o número parece razoável, mas 1% dos usuários experenciou 10 segundos de espera. A long tail é exatamente isso: a cauda direita da distribuição de latência, onde a minoria dos requests demora muito mais do que a mediana. Em serviços modernos, a long tail costuma ser longa — latências de P99 de 10-100× o P50 são comuns.

    Percentis relevantes: P50 (mediana — metade dos usuários tem latência abaixo desse valor), P95 (95% dos usuários são atendidos dentro desse tempo), P99 (99% dos usuários). O P99 é particularmente importante porque em microsserviços, um request do usuário pode chamar dezenas de serviços internos — a latência final é o máximo dos P99 de cada chamada, não a média. Em sistemas com muitos microserviços, o P99 de cada um se torna o piso de experiência do usuário no pior caso.

    Como você desenharia um SLO dashboard para um time de produto que não é SRE?

    Um SLO dashboard para um time de produto precisa ser legível por pessoas não especialistas em Prometheus ou observabilidade — o objetivo é responder "como está a saúde do serviço esta semana?" em 30 segundos. Desenharia em três blocos: (1) Saúde atual (stat panels com cores claras): success rate hoje, error budget restante em %, burn rate. Thresholds visuais onde verde = dentro do SLO, amarelo = atenção, vermelho = SLO em risco. (2) Tendência do mês: série histórica de success rate com linha de SLO target horizontal — a área abaixo da linha é o erro acumulado. Bar chart de error budget consumido por dia para ver em quais dias ocorreram problemas. (3) Linha do tempo de incidentes (annotations): eventos de deploy, incidentes, e silences marcados diretamente nos gráficos de série temporal — contexto imediato para picos no gráfico. O dashboard deliberadamente não tem queries PromQL expostas, nem panels de saturation de CPU — esses ficam no dashboard operacional para o on-call. O objetivo aqui é comunicar estado, não diagnosticar.

Referências para aprofundar

  1. livro Site Reliability Engineering — Niall Murphy, Betsy Beyer, Chris Jones, Jennifer Petoff (O'Reilly, 2016). sre.google/sre-book — Capítulo 6 "Monitoring Distributed Systems": Golden Signals, White-box vs Black-box monitoring, a filosofia de "se você não age sobre um alerta, por que ele existe?". Fonte original dos conceitos fundamentais.
  2. artigo The USE Method — Brendan Gregg (2012). brendangregg.com/usemethod.html — Metodologia para análise de recursos de sistema (CPU, disco, rede, memória): Utilization, Saturation, Errors. Complementa os Golden Signals (orientados a serviço) com perspectiva de recursos de infra.
  3. livro Practical Monitoring — Mike Julian (O'Reilly, 2017). Guia prático de estratégia de monitoramento: como estruturar dashboards, quais métricas coletar, como evitar alert fatigue. Boa leitura complementar ao SRE Book com foco em implementação prática em times menores.
  4. docs Grafana Dashboards — Documentação oficial — Grafana Labs (2024). grafana.com/docs/grafana/latest/dashboards — Referência completa de criação de dashboards: variáveis de template, data links, transformações, thresholds, annotations. Inclui guias de best practices de design.
  5. docs Grafana Tempo — Correlação Traces, Logs e Métricas — Grafana Labs (2024). grafana.com/docs/tempo — Configuração de "Trace to logs", "Trace to metrics" e exemplars no datasource Tempo. Cobre os três lados da correlação de sinais no Grafana.
  6. docs Grafonnet — Jsonnet library for Grafana — Grafana Labs (2024). github.com/grafana/grafonnet — Biblioteca Jsonnet para gerar dashboards programaticamente. Inclui abstrações para panels comuns (timeseries, stat, gauge, table), datasources e variáveis. Alternativa ao JSON puro para dashboard as code.
  7. docs Terraform Grafana Provider — Grafana Labs (2024). registry.terraform.io/providers/grafana/grafana — Recursos Terraform para grafana_dashboard, grafana_rule_group, grafana_folder, grafana_data_source. Permite gerenciar toda a configuração do Grafana via IaC no mesmo workflow que a infra.
  8. artigo Grafana Exemplars: Connecting Metrics to Traces — Grafana Labs Blog (2021). grafana.com/blog — Explica como exemplars funcionam na prática: configuração no Prometheus, instrumentação via OTel, e visualização no Grafana. A correlação de maior valor entre métricas e traces.
  9. docs Prometheus Native Histograms e Exemplars — Prometheus Project (2024). prometheus.io/docs/practices/histograms — Diferença entre histogramas clássicos e nativos, como exemplars são armazenados, e como configurar enable-feature=exemplar-storage. Pré-requisito técnico para correlação métricas → traces.
  10. artigo Observability-Driven Development — Honeycomb Engineering (2023). honeycomb.io/blog — Como usar observabilidade durante o desenvolvimento (não só em produção): instrumentar antes de debugar, usar traces para entender comportamento antes de escrever logs. Perspectiva que expande o papel do dashboard além do on-call.
  11. docs Grafana SLO Plugin — Grafana Labs (2024). grafana.com/docs/grafana-cloud/alerting-and-irm/slo — Documentação do plugin nativo de SLO do Grafana 10+: definição de SLO via UI, geração automática de dashboard e alertas de burn rate. Reduz significativamente o boilerplate de configuração manual.
  12. artigo Dashboard Design Patterns for SRE — Google SRE Workbook (2018). sre.google/workbook — Capítulo sobre design de dashboards de observabilidade: hierarquia de informação, quando usar diferentes tipos de visualização (timeseries vs stat vs gauge vs heatmap), e como estruturar dashboards para diferentes audiências.