Ir al contenido

Comandos de FlameGraph

FlameGraph es una colección de scripts de Brendan Gregg que generan flame graphs SVG interactivos a partir de datos de trazas de pila. Los flame graphs visualizan software perfilado mostrando qué rutas de código consumen más recursos, haciendo los cuellos de botella de rendimiento inmediatamente visibles.

Instalación

Linux/Ubuntu

# Clone the repository
git clone https://github.com/brendangregg/FlameGraph.git
cd FlameGraph

# Add to PATH (optional)
export PATH="$PATH:$(pwd)"

# Verify
./flamegraph.pl --help 2>&1 | head -3

# Dependencies — Perl is required (usually pre-installed)
perl --version

Flujo de trabajo principal

# El proceso estándar de 3 pasos:
# 1. Capturar pilas (perf, bpftrace, dtrace, etc.)
# 2. Colapsar/plegar pilas en líneas individuales
# 3. Generar el flame graph SVG

# Ejemplo con perf:
perf record -F 99 -a -g -- sleep 30
perf script > out.perf
./stackcollapse-perf.pl out.perf > out.folded
./flamegraph.pl out.folded > flamegraph.svg

Colapsadores de pilas

# Colapsar salida de perf script
./stackcollapse-perf.pl out.perf > out.folded

# Colapsar con anotaciones de PID
./stackcollapse-perf.pl --pid out.perf > out.folded

# Colapsar con IDs de hilos
./stackcollapse-perf.pl --tid out.perf > out.folded

# Colapsar salida de DTrace
./stackcollapse.pl out.dtrace > out.folded

# Colapsar salida de bpftrace
./stackcollapse-bpftrace.pl out.bpftrace > out.folded

# Colapsar salida de Java jstack
./stackcollapse-jstack.pl out.jstack > out.folded

# Colapsar salida de Go pprof
./stackcollapse-go.pl out.pprof > out.folded

# Colapsar salida de Python cProfile
./stackcollapse-python.pl out.cprofile > out.folded

# Colapsar salida de Xcode Instruments
./stackcollapse-instruments.pl out.instruments > out.folded

# Colapsar salida de strace
./stackcollapse-stap.pl out.strace > out.folded

# Colapsar grep recursivo de /proc/PID/stack
./stackcollapse-recursive.pl out.procstack > out.folded

Generación de Flame Graphs

# Flame graph básico
./flamegraph.pl out.folded > flamegraph.svg

# Título personalizado
./flamegraph.pl --title "My App CPU Profile" out.folded > flamegraph.svg

# Subtítulo personalizado
./flamegraph.pl --subtitle "Production 2026-05-21" out.folded > flamegraph.svg

# Establecer ancho mínimo de visualización (porcentaje)
./flamegraph.pl --minwidth 0.5 out.folded > flamegraph.svg

# Ancho y alto personalizados
./flamegraph.pl --width 1400 --height 24 out.folded > flamegraph.svg

# Orden de pila invertido (gráfico icicle — crece hacia abajo)
./flamegraph.pl --inverted out.folded > icicle.svg

# Paleta de colores personalizada
./flamegraph.pl --color hot out.folded > flamegraph.svg
./flamegraph.pl --color mem out.folded > flamegraph.svg
./flamegraph.pl --color io out.folded > flamegraph.svg
./flamegraph.pl --color java out.folded > flamegraph.svg

# Nombre del conteo en el eje Y
./flamegraph.pl --countname "microseconds" out.folded > flamegraph.svg

# Tipo de nombre personalizado
./flamegraph.pl --nametype "Function:" out.folded > flamegraph.svg

Flame Graphs de CPU

# Flame graph de CPU on-CPU desde perf
perf record -F 99 -a -g -- sleep 30
perf script > out.perf
./stackcollapse-perf.pl out.perf > out.folded
./flamegraph.pl --title "CPU Flame Graph" out.folded > cpu.svg

# Flame graph de CPU on-CPU desde bpftrace
sudo bpftrace -e 'profile:hz:99 { @[kstack] = count(); }' > out.bpftrace
./stackcollapse-bpftrace.pl out.bpftrace > out.folded
./flamegraph.pl out.folded > cpu_bpf.svg

# Flame graph de CPU solo espacio de usuario
perf record -F 99 -g --call-graph dwarf -p 1234 -- sleep 30
perf script > out.perf
./stackcollapse-perf.pl --kernel out.perf > out.folded
./flamegraph.pl --color java out.folded > user_cpu.svg

Flame Graphs Off-CPU

# Usando BCC offcputime
sudo offcputime-bpfcc -f 30 > offcpu.folded
./flamegraph.pl --color=io --title="Off-CPU Time" --countname=us offcpu.folded > offcpu.svg

# Usando bpftrace para análisis off-CPU
sudo bpftrace -e '
tracepoint:sched:sched_switch {
    @start[tid] = nsecs;
}
tracepoint:sched:sched_wakeup /@start[args.pid]/ {
    @[kstack, args.comm] = sum(nsecs - @start[args.pid]);
    delete(@start[args.pid]);
}' > offcpu.bt

Flame Graphs de memoria

# Flame graph de asignación de memoria desde perf
perf record -e kmem:kmalloc -a -g -- sleep 10
perf script > mem.perf
./stackcollapse-perf.pl mem.perf > mem.folded
./flamegraph.pl --color=mem --title="Memory Allocations" --countname="bytes" mem.folded > mem.svg

Flame Graphs diferenciales

# Comparar dos perfiles usando difffolded.pl
# 1. Capturar perfil de referencia
perf record -F 99 -a -g -- sleep 30
perf script > baseline.perf
./stackcollapse-perf.pl baseline.perf > baseline.folded

# 2. Capturar perfil de comparación (después de cambios)
perf record -F 99 -a -g -- sleep 30
perf script > comparison.perf
./stackcollapse-perf.pl comparison.perf > comparison.folded

# 3. Generar pilas plegadas diferenciales
./difffolded.pl baseline.folded comparison.folded > diff.folded

# 4. Generar flame graph diferencial
# Rojo = crecimiento (regresión), azul = reducción (mejora)
./flamegraph.pl --negate diff.folded > diff_flamegraph.svg

# Normalizar al mismo número de muestras
./difffolded.pl -n baseline.folded comparison.folded > diff_normalized.folded
./flamegraph.pl --negate diff_normalized.folded > diff_norm.svg

Filtrado y transformación

# Buscar funciones específicas en pilas plegadas
grep 'tcp_' out.folded | ./flamegraph.pl > tcp_only.svg

# Excluir pilas del kernel
grep -v 'vmlinux' out.folded | ./flamegraph.pl > user_only.svg

# Filtrar a un proceso específico
grep 'my_app' out.folded | ./flamegraph.pl > my_app.svg

# Combinar múltiples archivos de pilas plegadas
cat profile1.folded profile2.folded | ./flamegraph.pl > combined.svg

# Ordenar pilas plegadas para comparación
sort out.folded > sorted.folded

Formato de pilas plegadas

# Formato: marcos de pila separados por punto y coma seguidos de un espacio y conteo
# La base de la pila está a la izquierda, la parte superior (hoja) a la derecha

main;read_data;parse_json;validate 42
main;read_data;parse_json;transform 87
main;handle_request;send_response 156
main;handle_request;log_request 23

Características interactivas del SVG

Los archivos SVG generados incluyen interactividad incorporada:

CaracterísticaDescripción
Pasar el ratónMuestra nombre de función, conteo de muestras y porcentaje
ClicAmplía un marco específico y sus hijos
Ctrl+F / BuscarResalta marcos coincidentes en magenta
Restablecer ZoomClic en “Reset Zoom” o presionar Escape
Clic derechoAbre menú contextual del navegador para guardar

Flujos de trabajo por lenguaje

Java

# Usando async-profiler (recomendado para Java)
./asprof -d 30 -f out.html jps_pid
# O generar pilas plegadas
./asprof -d 30 -o collapsed -f out.folded jps_pid
./flamegraph.pl out.folded > java_cpu.svg

Python

# Usando py-spy para generar pilas plegadas
py-spy record -f raw -o out.folded --pid 1234
./flamegraph.pl out.folded > python_cpu.svg

Node.js

# Usando 0x (wrapper alrededor de perf para Node.js)
npx 0x my_app.js
# O perf con --perf-basic-prof
node --perf-basic-prof my_app.js &
perf record -F 99 -p $! -g -- sleep 30
perf script > out.perf
./stackcollapse-perf.pl out.perf > out.folded
./flamegraph.pl out.folded > node_cpu.svg

Consejos

# Aumentar la tasa de muestreo para cargas de trabajo cortas
perf record -F 999 -g -- ./short_task

# Usar desenrollado DWARF para pilas de usuario precisas
perf record -g --call-graph dwarf -F 99 -p 1234 -- sleep 30

# Verificar si los frame pointers están disponibles
readelf -S /usr/bin/myapp | grep -i frame

# Encadenar todo en una línea
perf script | ./stackcollapse-perf.pl | ./flamegraph.pl > flamegraph.svg