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 |
|---|---|
| Survol | Affiche le nom de la fonction, le nombre d’échantillons et le pourcentage |
| Clic | Zoom sur un cadre spécifique et ses enfants |
| Ctrl+F / Recherche | Met en surbrillance les cadres correspondants en magenta |
| Réinitialiser le zoom | Cliquer sur “Reset Zoom” ou appuyer sur Échap |
| Clic droit | Ouvre 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