Flame Graphs jest techniką, która pozwala zlokalizować nam tak zwane “bottlenecki” w naszym kodzie. Dzięki swojej graficznej reprezentacji przypominającej płomienie jesteśmy w stanie w bardzo łatwy sposób zaobserwować procesy, które konsumują największą ilość czasu CPU. Zapraszamy do wpisu aby zobaczyć jak wygenerować własne “płomienie“.
Flame Graphs
Flame Graphs są sposobem reprezentacji danych związanych z wydajnością aplikacji. Dane przedstawione są w formie wykresu przypominającego płomienie:
Jest to sposób reprezentacji danych zaproponowany przez Brendana Gregga, który jest “gościem od performance” w firmie Netflix. Dzięki takiej reprezentacji unikniemy nadmiernej analizy danych, które w większości nie są danymi najważniejszymi.
Github
Aby wygenerować wykres najlepiej sklonować repozytorium Brendana https://github.com/brendangregg/FlameGraph. W repozytorium tym znajduje się plik flamegraph.pl
, którzy służy do generowania wykresu. Najczęściej wydajemy polecenie:
./flamegraph.pl pilk-z-danymi.txt > plik-wynikowy.svg
Po uruchomieniu tego polecania wystarczy otworzyć wygenerowany plik na przykład w przeglądarce.
Plik z danymi
Dane prezentowane na wykresie powinny być dostarczone w odpowiednim formacie:
funkcja-1();funckja-2() czas-CPU-spędzony-na-wykonywaniu-funkcji-2
Sprawdźmy to w praktyce dla danych:
a();b();c() 1 a();b();d() 1
a();b();c() 1 a();b();d() 2
Jak czytać wykres
Na wykresie znajdują się dwie osie:
- oś y (pionowa) – pokazuje głębokość/wysokość stosu wywołań
- oś x (pozioma) – pokazuje nazwy procesów w kolejności alfabetycznej
- kolory – wbrew pozorom nie mają znaczenia
Najważniejsze procesy to te, które znajdują się na samej górze. Są one tak zwanymi procesami on-CPU, czyli procesami, które tak naprawdę są wykonywane na procesorze. Procesy poniżej to te, które wywołały proces na górze (w dokumentacji spotkacie się z określeniem tych procesów jako przodkowie ancestry).
Dane
W poprzednich akapitach przedstawiłem wam przykładowe dane. Jednakże skąd wziąć dane, które rzeczywiście pokażą nam ciekawe informacje? Do pobierania danych o procesach mamy dostępną całą gamę narzędzi. Najpopularniejsze to:
- perf
- DTrace
- jstack
- pprof
Każde z tych narzędzi generuje dane w innym formacie. Autor Flame Graphs dostarczył konwertery, które pozwalają zmienić format wyjściowy na format obsługiwany dla Flame Graphs. Na https://github.com/brendangregg/FlameGraph znajdziecie wiele konwerterów:
stackcollapse.pl
– dla DTrace stacksstackcollapse-perf.pl
– dla Linux’owego perf_events “perf script” wynikustackcollapse-jstack.pl
– dla jstackstackcollapse-go.pl
– dla GoLangowego pprof
Dodatkowe opcje
Samo narzędzie ma sporo dodatkowych opcji:
USAGE: ./flamegraph.pl [options] infile > outfile.svg --title TEXT # change title text --subtitle TEXT # second level title (optional) --width NUM # width of image (default 1200) --height NUM # height of each frame (default 16) --minwidth NUM # omit smaller functions (default 0.1 pixels) --fonttype FONT # font type (default "Verdana") --fontsize NUM # font size (default 12) --countname TEXT # count type label (default "samples") --nametype TEXT # name type label (default "Function:") --colors PALETTE # set color palette. choices are: hot (default), mem, # io, wakeup, chain, java, js, perl, red, green, blue, # aqua, yellow, purple, orange --bgcolors COLOR # set background colors. gradient choices are yellow # (default), blue, green, grey; flat colors use "#rrggbb" --hash # colors are keyed by function name hash --cp # use consistent palette (palette.map) --reverse # generate stack-reversed flame graph --inverted # icicle graph --flamechart # produce a flame chart (sort by time, do not merge stacks) --negate # switch differential hues (blue<->red) --notes TEXT # add notes comment in SVG (for debugging) --help # this message eg, ./flamegraph.pl --title="Flame Graph: malloc()" trace.txt > graph.svg