jonhoo / inferno

A Rust port of FlameGraph
Other
1.64k stars 117 forks source link

Documentation, especially of folded format #309

Open kelko opened 9 months ago

kelko commented 9 months ago

Maybe this is obvious for all the rest, but I have a very hard time to understand what string format exactly I should write as input into stdin of inferno-flamegraph. I understand, that this library follows the original FlameGraph from brendangregg, but even when searching there I couldn't find a comprehensive and understandable definition of the input format. Most talks about what tools to use for which language (trace, dtrace, perf, ...) and how to collapse their outputs.

I'm comming from a different direction and want to re-format timing information I collect from within a program so that I can use flamegraph as visualization. So I don't need to understand how to combine perf & collapse & ... but I would like to know what format I need to write to be able to generate expressive flame graphs. As inferno-flamegraph is usable as standalone tool I would like to ask you whether you could extend your documentation also on those aspects.

I understand that basic form is:

action[;subaction]* (space) count

But some questions still arise:

Additionally, but linked to this: I see there are some CLI options like --nameattr or --nametype which seem to have effect on how the folded format content is drawn. Is there any documentation on those somewhere?

jonhoo commented 9 months ago

Hi there!

Ideally, this should all be documented on https://docs.rs/inferno/latest/inferno/flamegraph/fn.from_lines.html, but at the moment it is a little thin. There's also some documentation of the format in the original flamegraph.pl: https://github.com/brendangregg/FlameGraph/blob/cd9ee4c4449775a2f867acf31c84b7fe4b132ad5/flamegraph.pl#L18-L29

For your questions:

The CLI options are documented here: https://docs.rs/inferno/latest/inferno/flamegraph/struct.Options.html, and that documentation should be replicated in the CLI when you run --help. They are defined here: https://github.com/jonhoo/inferno/blob/86131d445bbe338c0b178933e1fa93393644fc05/src/bin/flamegraph.rs#L18.

If you want to take a stab at doing a PR to improve the documentation, that'd be great!

kelko commented 9 months ago

Hey @jonhoo . Thanks for the answer.

But I would like to come back to the flamechart feature, because after reading your answer I suspect there might be a bug:

You wrote "so that stacks by the same name/prefix aren't merged". I created a simple test input:

A 2
A;B 2
A;B 2
A 3
A;B 2
A;B 2

Based on your answer I would suspect the flamechart to have 2 "A" and 4 "B" elements. But the actually generated SVG has 1 "A" (merged both A) and 2 "B" (merged both consecutive "B", without the "A" line in between):

example_flamechart

This is the reason why I was unsure about whether or not some kind of unique identifier was necessary

jonhoo commented 8 months ago

Ah, yes, so, the effect of --flamechart is really to just not re-sort the input. The rest of the plotting code remains the same, which includes walking up and down adjacent stacks to merge them. That's why you're observing that it merges your adjacent A;B stacks. If you think about it, it sort of makes sense: it needs to merge the A's underlying those Bs, so some amount of merging has to happen. And following that argument, why should the Bs not be merged but the A's should? And similarly, why should the A on line 4 not be merged with the preceding As? Without knowing the semantics of your program, I think the best it can do is merge any frames that are immediately-horizontally-adjacent to a frame by the same name as itself (which is what the code currently does).