- Documentação
- Observabilidade
- Profiling Contínuo de CPU
Profiling Contínuo de CPU
Todo serviço no Guara Cloud emite amostras de profiling de CPU continuamente. A plataforma coleta tudo via eBPF e armazena no Grafana Pyroscope, e renderiza como flamegraphs interativos no dashboard. Não tem SDK para instalar, variável de ambiente para configurar nem toggle de opt-in: profiling fica sempre ligado para todo serviço que você fizer deploy e para todo serviço de catálogo que você provisionar.
Onde encontrar
São duas superfícies:
- Página de detalhe do serviço → aba Profiling. O flamegraph de um único serviço na janela de tempo que você escolher. Use quando o foco é em um serviço só.
- Profiling Explorer. Uma página dedicada que deixa você escolher qualquer projeto / serviço / janela de tempo na sidebar e comparar flamegraphs lado a lado. Use quando estiver investigando entre serviços ou compartilhando um profile com alguém do time.
Em ambas as superfícies você pode dar zoom em frames de stack, ver as porcentagens self e total de CPU e copiar uma URL deep-link que captura projeto, serviço, janela de tempo e estado do zoom.
Retenção por plano
O quão longe no passado você pode consultar profiles depende do plano. O picker do dashboard esconde opções fora da sua retenção.
| Plano | Retenção de profiles |
|---|---|
| Hobby | 24 horas |
| Pro | 7 dias |
| Business | 7 dias |
| Enterprise | 7 dias |
Se você pedir uma janela maior que a retenção do seu plano via API, a plataforma retorna um erro claro PROFILING_TIER_RETENTION_EXCEEDED com a janela máxima permitida.
Runtimes suportados
Profiling funciona para todo runtime que o Guara Cloud suporta. A fidelidade de símbolos (se os frames de stack ficam com nomes ou aparecem como endereços) depende de o runtime precisar de ajuda do JIT para expor seus frames. A plataforma injeta as variáveis de ambiente certas automaticamente conforme o runtime do seu serviço — você não precisa fazer nada.
| Runtime | Fidelidade de símbolos | Observações |
|---|---|---|
| Node.js | Completa | Injeta NODE_OPTIONS=--perf-basic-prof-only-functions --interpreted-frames-native-stack. |
| JVM (Java, Kotlin, Scala) | Completa | Injeta JAVA_TOOL_OPTIONS=-XX:+PreserveFramePointer. |
| Python | Completa | eBPF puro — sem variáveis de ambiente. |
| Go | Completa | eBPF puro — sem variáveis de ambiente. |
| Rust | Completa | eBPF puro — sem variáveis de ambiente. |
| Outros runtimes nativos | Best-effort | Frames podem aparecer como endereços se o runtime não expuser símbolos. |
Se você já estiver definindo NODE_OPTIONS ou JAVA_TOOL_OPTIONS nas variáveis de ambiente do seu serviço, a plataforma concatena ao seu valor em vez de sobrescrever.
Lendo um flamegraph
Um flamegraph é uma visão top-down de onde o seu serviço gastou CPU durante a janela selecionada:
- Largura de um frame = quanto de CPU ele consumiu (porcentagem total).
- Empilhamento = caller acima, callee abaixo. A folha mais larga no fundo de qualquer torre costuma ser o hot loop.
- Self % (no hover) = tempo gasto diretamente naquela função, sem incluir os callees.
- Total % = self mais todos os callees.
Use a caixa de busca para destacar todo frame cujo nome de função casa com uma substring — útil quando você lembra o nome de uma função mas não onde ela mora no call graph.
Clique em um frame para dar zoom (o resto do grafo colapsa para aquela subárvore). Clique no breadcrumb acima do grafo para voltar.
Do trace para o profile
Ao abrir um span de trace na visão de Traces, a ação Ver profile te leva direto ao flamegraph do mesmo serviço na janela em volta. É o caminho mais rápido para responder “a requisição foi lenta — o serviço estava CPU-bound ou esperando I/O?”.
Erros que você pode ver
| Código de erro | O que significa |
|---|---|
PROFILING_NO_DATA | Sem amostras na janela escolhida. O serviço pode ter acabado de subir, ficado idle ou crashado. |
PROFILING_TIER_RETENTION_EXCEEDED | Sua janela vai mais longe que a retenção do seu plano. Escolha uma janela mais curta ou faça upgrade. |
PROFILING_PYROSCOPE_UNAVAILABLE | O backend de profiling está temporariamente indisponível. Tente de novo em alguns instantes. |
Privacidade e overhead
O profiling baseado em eBPF amostra a CPU em uma taxa fixa (tipicamente ~100 Hz por CPU) e captura apenas call stacks — nunca dados da aplicação, corpos de requisição, variáveis de ambiente ou conteúdo de memória. O overhead fica em poucos por cento de CPU por serviço no pior caso e é invisível na prática.
Pela CLI
guara services profiles get renderiza um flamegraph ASCII para a mesma janela que o dashboard mostraria, mais uma tabela top-N por self time para identificar os frames quentes de cara. Use de uma sessão de shell, de um jump-box SSH, ou jogue --json na sua própria ferramenta.
guara services profiles get
guara services profiles get --time-range 1h --top 20
guara services profiles get --from 2026-05-02T15:00:00Z --to 2026-05-02T15:15:00Z
guara services profiles get --json | jq .data.metadata
Saída de exemplo (truncada):
my-api · profile · 2026-05-02T15:00:00Z → 2026-05-02T15:15:00Z
▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 100.0% total
▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 62.4% handleRequest
▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 38.1% db.query
▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 25.8% pg.client.send
▇▇▇▇▇▇▇▇ 12.6% serialize
▇▇▇▇▇▇▇▇▇▇▇▇ 18.7% gc.minorMark
Top 10 by self time
# SELF % FRAME
1 25.8% pg.client.send
2 18.7% gc.minorMark
3 12.6% serialize
4 8.4% crypto.randomFillSync
5 7.1% net.write
…
Tier: Pro · retention 168h · window 15m
Quando stdout não é um TTY (piped para outro comando, redirecionado para arquivo), o flamegraph em si é omitido e apenas a tabela top-N é impressa, para legibilidade.
Veja guara services profiles get na referência da CLI para a lista completa de flags.