Stratus3D / eflambe

A tool for rapid profiling of Erlang and Elixir applications
Apache License 2.0
112 stars 15 forks source link

Possibility to see function call arguments in flame graph #46

Open hauleth opened 2 weeks ago

hauleth commented 2 weeks ago

I am working on performance optimisations of Supavisor project. There we extensively use gen_statem module so without seeing what are the arguments of called functions it is hard to analyse the stack trace. Is there any option to track arguments of called functions to be able to pinpoint which particular case was the problematic one?

Stratus3D commented 2 weeks ago

Unfortunately no, there is no way to see arguments passed to the function calls. Arguments can be large, so including them with each call could result in massive amounts of data being written to disk. And viewing it as an SVG could be impossible if the size of the data exceeded your machine's available memory.

I suppose we could have some sort of argument processor callback that would get passed the raw arguments for each function call, and then that function would be responsible for returning a string representing a truncated/simplified version of them. That's not a feature that exists currently but I suppose it could work. Thoughts?

hauleth commented 2 weeks ago

That would be an opt-in option, so the user could enable it only when they know what the hell there will be not much of a problems with arguments. Alternatively you could mark which arguments you would like to persist instead of persisting them all (like in my case I would like to track only single argument instead of all of them).

Stratus3D commented 2 weeks ago

Yes, I'm thinking something really simple here. Arguments are a list, but each call name in the flamegraph is a string. I'm thinking the optional callback would be something like this:

-spec callback_fun(module :: atom(), func :: atom(), args :: list(any())) :: iolist()

It'd take a list of arguments and return a binary or iolist representing the simplified representation of them. The returned string would be formatted in the flamegraph like this:

mymod:myfunc/2(~ <callback return value> ~)

I'm thinking (~ ~) or something like that might be a good way to indicate the contained value is a modified representation of the actual arguments. If the callback wasn't specified or returned empty binary/list we'd omit the (~ ~). Thoughts?

hauleth commented 2 weeks ago

That would be 100% enough for me.