Flame graphs are a way of visualizing profiled software by representing the call stack as a graph of horizontal layers with the x axis representing the time of each call and the y axis representing the nested calls on the stack as stacked layers. Flame graphs make it easy to see how long a function takes to execute as well how often each function is invoked.
Creating Flame Graphs
eflame is an Erlang package that makes it easy to generate flame graphs for Erlang applications. For Elixir we need to use a fork of eflame with a mix.exs
file so we can add it as a dependency to an Elixir project. The fork is already published to Hex.pm so using it is as simple as adding this to your project’s mix.exs
file’s dependency section:
mix.exs
{:eflame, "~> 1.0", only: [:dev]}
Using eflame
Using eflame is easy. Wrap the code you want to profile in a call to :eflame.apply/2
. For example:
:eflame.apply(fn() ->
# Generate a flame graph of a single function call
System.get_env()
end, [])
Run the code you’ve wrapped in the :eflame.apply
call. It will generate a file named stacks.out
in the applications root directory. The .out
file contains the data needed to construct the flame graph. To generate an SVG flame graph from the data in the file run the stack_to_flame.sh
script. The script is located in the deps/eflame
directory:
# Input the .out file, save output to flame.svg
$ ./deps/eflame/stack_to_flame.sh < stacks.out > flame.svg
Then open the generated flame.svg
file to see the graph! If you open it in a browser you should be able to see more details about the call stack by hovering over each element in the graph.
System.get_env/0
being called 10 times by the Enum.each/2
function.References
-
Brendan Gregg’s flame graph article: http://www.brendangregg.com/flamegraphs.html
-
eflame fork for Elixir: https://github.com/Nebo15/eflame
-
original eflame: https://github.com/proger/eflame