Stratus3D

A blog on software engineering by Trevor Brown

Elixir Flame Graphs

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.

flame
Figure 1. A flame graph of System.get_env/0 being called 10 times by the Enum.each/2 function.

References