Grafana Query Analysis
Skill para analisar queries individuais do Grafana (dashboard pg_stat_statements) a partir de screenshots e produzir um relatório HTML diagnóstico completo.
Input esperado
Uma pasta dentro de backlog/ com o ID da query como nome (ex: backlog/-1783987887916083306/).
Dentro dessa pasta haverá imagens PNG dos gráficos do Grafana. Os nomes dos arquivos indicam a métrica:
| Nome esperado do arquivo | Métrica |
|---|---|
avg_runtime*.png |
Avg. runtime (30m avg.) |
calls*.png |
Calls (30m aggregate) |
total_runtime*.png |
Total runtime (30m aggregate) |
cache_hit*.png |
Shared Buffers Hit Ratio |
temp_blocks*.png |
Temp Blocks Read/Written (30m aggregate) |
blk_readwrite*.png |
Backend block Read/Write time (30m agg.) |
io_time_pct*.png |
% of total_time spent in direct IO (30m avg.) |
Se o nome não seguir esse padrão, inferir pela legenda visível no próprio screenshot.
Workflow obrigatório
backlog/{query-id}/ → in-progress/{query-id}/ → done/{query-id}/
- Mover para in-progress antes de começar a análise
- Ler todas as imagens da pasta usando o Read tool (suporta PNG)
- Extrair os valores de cada métrica visualizando os screenshots
- Gerar o relatório HTML (ver especificação abaixo)
- Salvar o HTML como
done/{query-id}/relatorio.html - Mover a pasta de
in-progress/{query-id}/paradone/{query-id}/- As imagens devem ir junto para que o HTML possa referenciá-las com caminhos relativos
Como extrair valores dos screenshots
Para cada imagem, identificar:
- Título do gráfico (confirma qual métrica é)
- Período (ex: "03:20 → 09:10 · 2026-06-03")
- Valor médio visível na legenda ou estatísticas do Grafana (ex: "Avg: 824 ms")
- Tendência ao longo do tempo: estável, crescente, decrescente, picos pontuais
- Valores min/max se visíveis
Se uma métrica não tiver screenshot, registrar como "não disponível" no relatório.
Thresholds de avaliação
Use estes critérios para classificar cada métrica como ✅ OK / ⚠️ Atenção / ❌ Crítico:
| Métrica | ✅ OK | ⚠️ Atenção | ❌ Crítico |
|---|---|---|---|
| avg_runtime | < 100 ms | 100 ms – 500 ms | > 500 ms |
| calls/30m | qualquer | — | — |
| total_time/30m | < 30 s | 30 s – 120 s | > 120 s |
| cache hit ratio | > 99% | 90% – 99% | < 90% |
| temp blocks | = 0 | > 0 (baixo) | alto |
| blk_read_time | ≈ 0 | depende calls | > 50% avg_runtime |
| io_time_pct | < 20% | 20% – 60% | > 60% |
Regras do codebase
Antes de montar os caminhos de investigação, ler o arquivo references/rules.md. Ele contém padrões do código da equipe que devem ser ignorados na análise.
Diagnóstico: cadeias causais comuns
Identificar qual padrão se aplica e incluir a cadeia no relatório:
Padrão IO-bound (mais comum):
cache hit < 90%→ leituras físicas excessivas →io_time_pct > 60%→avg_runtimealto- Causas: tabela não cabe em
shared_buffers, falta de índice causando seq scan, tabela muito grande
Padrão CPU-bound:
io_time_pct < 20%masavg_runtimealto → CPU é o gargalo- Causas: sorts sem índice, funções caras, JOINs com muitas linhas, regex
Padrão spill para disco (temp blocks alto):
temp_blocks_written > 0→work_meminsuficiente para ordenação/hash join- Causas: ORDER BY / GROUP BY em muitas linhas sem índice, hash joins em grandes datasets
Padrão tráfego alto:
calls/30mmuito alto +avg_runtimeok → query eficiente mas chamada em excesso- Oportunidade: cache na aplicação, reduzir frequência
Especificação do relatório HTML
O HTML deve seguir exatamente o design system do arquivo de referência references/grafana-query-manual.html (dark theme Grafana-like).
Estrutura obrigatória
1. Cabeçalho
- Título: "Análise — Query {query-id}"
- Subtitle: banco · período · data
2. Query analisada (se o texto SQL estiver visível nos screenshots, extrair; senão omitir)
3. Tabela de tipos de agregação (30m avg. vs 30m aggregate)
4. Tabela de diagnóstico completo
- Linha por métrica: nome | valor | status badge | conclusão
5. Cadeia causal (flow steps)
6. Caminhos de investigação (ol numerado)
7. Cards de métricas (uma por screenshot disponível)
- Número sequencial
- Título da métrica
- <img> apontando para o arquivo PNG com caminho relativo
- Label com período e valor médio
- Seções: "O que o Postgres registra" / "O que o Grafana mostra" / "Do seu dashboard" / "Interpretação"
- Callout colorido (ok/warn/error/info) com diagnóstico
8. Footer com data de geração
CSS variables obrigatórias (copiar exatamente)
--bg: #0f1117;
--surface: #1a1d27;
--surface2: #22263a;
--border: #2e3347;
--green: #73bf69;
--yellow: #fade2a;
--red: #f2495c;
--blue: #5794f2;
--text: #d9dbe0;
--muted: #8a8fa8;
--code-bg: #141720;
Lightbox
Incluir o script de lightbox para ampliar imagens ao clicar (copiar do arquivo de referência).
Caminhos das imagens
Usar caminhos relativos dentro da mesma pasta:
<img class="metric-chart" src="avg_runtime.png" alt="...">
Exemplo de callout por diagnóstico
<!-- IO-bound crítico -->
<div class="callout error">
<span class="callout-icon">❌</span>
<span><strong>IO-bound crítico.</strong> X% do tempo de execução é espera de disco...</span>
</div>
<!-- Cache hit baixo -->
<div class="callout error">
<span class="callout-icon">❌</span>
<span><strong>Cache hit X% é crítico.</strong> O ideal é >99%...</span>
</div>
<!-- Temp blocks zerado -->
<div class="callout ok">
<span class="callout-icon">✅</span>
<span>Sem arquivos temporários. work_mem suficiente para esta query.</span>
</div>
Qualidade do relatório
- Todos os cálculos devem ser mostrados (ex:
313 calls × 824ms ≈ 258s de espera/30min) - A cadeia causal deve conectar os sintomas com a causa raiz
- Os caminhos de investigação devem ser específicos para a query analisada (não genéricos)
- Se a query SQL estiver visível nos screenshots, mencionar tabelas e filtros específicos
- Adaptar o diagnóstico ao padrão identificado (IO-bound, CPU-bound, etc.)
Ao finalizar
# Mover pasta de in-progress para done (preservando imagens)
mv in-progress/{query-id} done/{query-id}
O HTML final fica em done/{query-id}/relatorio.html com imagens na mesma pasta.