Aller au contenu

Commandes FlameGraph

FlameGraph est une collection de scripts par Brendan Gregg qui génèrent des flame graphs SVG interactifs à partir de données de traces de pile. Les flame graphs visualisent le logiciel profilé en montrant quels chemins de code consomment le plus de ressources, rendant les goulots d’étranglement immédiatement visibles.

Installation

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

Flux de travail principal

# Le processus standard en 3 étapes :
# 1. Capturer les piles (perf, bpftrace, dtrace, etc.)
# 2. Replier les piles en lignes individuelles
# 3. Générer le flame graph SVG

# Exemple avec 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

Repliage des piles

# Replier la sortie de perf script
./stackcollapse-perf.pl out.perf > out.folded

# Replier avec annotations PID
./stackcollapse-perf.pl --pid out.perf > out.folded

# Replier avec les IDs de threads
./stackcollapse-perf.pl --tid out.perf > out.folded

# Replier la sortie DTrace
./stackcollapse.pl out.dtrace > out.folded

# Replier la sortie bpftrace
./stackcollapse-bpftrace.pl out.bpftrace > out.folded

# Replier la sortie Java jstack
./stackcollapse-jstack.pl out.jstack > out.folded

# Replier la sortie Go pprof
./stackcollapse-go.pl out.pprof > out.folded

# Replier la sortie Python cProfile
./stackcollapse-python.pl out.cprofile > out.folded

# Replier la sortie Xcode Instruments
./stackcollapse-instruments.pl out.instruments > out.folded

# Replier la sortie strace
./stackcollapse-stap.pl out.strace > out.folded

# Replier le grep récursif de /proc/PID/stack
./stackcollapse-recursive.pl out.procstack > out.folded

Génération de Flame Graphs

# Flame graph basique
./flamegraph.pl out.folded > flamegraph.svg

# Titre personnalisé
./flamegraph.pl --title "My App CPU Profile" out.folded > flamegraph.svg

# Sous-titre personnalisé
./flamegraph.pl --subtitle "Production 2026-05-21" out.folded > flamegraph.svg

# Définir la largeur minimale d'affichage (pourcentage)
./flamegraph.pl --minwidth 0.5 out.folded > flamegraph.svg

# Largeur et hauteur personnalisées
./flamegraph.pl --width 1400 --height 24 out.folded > flamegraph.svg

# Ordre de pile inversé (graphique icicle — croît vers le bas)
./flamegraph.pl --inverted out.folded > icicle.svg

# Palette de couleurs personnalisée
./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

# Nom du comptage sur l'axe Y
./flamegraph.pl --countname "microseconds" out.folded > flamegraph.svg

# Type de nom personnalisé
./flamegraph.pl --nametype "Function:" out.folded > flamegraph.svg

Flame Graphs CPU

# Flame graph CPU on-CPU depuis 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 CPU on-CPU depuis 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 CPU espace utilisateur uniquement
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

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

# Avec bpftrace pour l'analyse 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 mémoire

# Flame graph d'allocation mémoire depuis 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 différentiels

# Comparer deux profils avec difffolded.pl
# 1. Capturer le profil de référence
perf record -F 99 -a -g -- sleep 30
perf script > baseline.perf
./stackcollapse-perf.pl baseline.perf > baseline.folded

# 2. Capturer le profil de comparaison (après modifications)
perf record -F 99 -a -g -- sleep 30
perf script > comparison.perf
./stackcollapse-perf.pl comparison.perf > comparison.folded

# 3. Générer les piles pliées différentielles
./difffolded.pl baseline.folded comparison.folded > diff.folded

# 4. Générer le flame graph différentiel
# Rouge = croissance (régression), bleu = diminution (amélioration)
./flamegraph.pl --negate diff.folded > diff_flamegraph.svg

# Normaliser au même nombre d'échantillons
./difffolded.pl -n baseline.folded comparison.folded > diff_normalized.folded
./flamegraph.pl --negate diff_normalized.folded > diff_norm.svg

Filtrage et transformation

# Chercher des fonctions spécifiques dans les piles pliées
grep 'tcp_' out.folded | ./flamegraph.pl > tcp_only.svg

# Exclure les piles du noyau
grep -v 'vmlinux' out.folded | ./flamegraph.pl > user_only.svg

# Filtrer par processus spécifique
grep 'my_app' out.folded | ./flamegraph.pl > my_app.svg

# Combiner plusieurs fichiers de piles pliées
cat profile1.folded profile2.folded | ./flamegraph.pl > combined.svg

# Trier les piles pliées pour comparaison
sort out.folded > sorted.folded

Format des piles pliées

# Format : cadres de pile séparés par des points-virgules suivis d'un espace et du comptage
# Le bas de la pile est à gauche, le sommet (feuille) à droite

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

Fonctionnalités interactives du SVG

Les fichiers SVG générés incluent une interactivité intégrée :

FonctionnalitéDescription
SurvolAffiche le nom de la fonction, le nombre d’échantillons et le pourcentage
ClicZoom sur un cadre spécifique et ses enfants
Ctrl+F / RechercheMet en surbrillance les cadres correspondants en magenta
Réinitialiser le zoomCliquer sur “Reset Zoom” ou appuyer sur Échap
Clic droitOuvre le menu contextuel du navigateur pour sauvegarder

Flux de travail par langage

Java

# Avec async-profiler (recommandé pour Java)
./asprof -d 30 -f out.html jps_pid
# Ou générer des piles pliées
./asprof -d 30 -o collapsed -f out.folded jps_pid
./flamegraph.pl out.folded > java_cpu.svg

Python

# Avec py-spy pour générer des piles pliées
py-spy record -f raw -o out.folded --pid 1234
./flamegraph.pl out.folded > python_cpu.svg

Node.js

# Avec 0x (wrapper autour de perf pour Node.js)
npx 0x my_app.js
# Ou perf avec --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

Conseils

# Augmenter le taux d'échantillonnage pour les charges courtes
perf record -F 999 -g -- ./short_task

# Utiliser le déroulement DWARF pour des piles utilisateur précises
perf record -g --call-graph dwarf -F 99 -p 1234 -- sleep 30

# Vérifier si les frame pointers sont disponibles
readelf -S /usr/bin/myapp | grep -i frame

# Enchaîner le tout en une ligne
perf script | ./stackcollapse-perf.pl | ./flamegraph.pl > flamegraph.svg