Comments (14)
I was thinking about something similar but would like to suggest taking it one step further:
- parse (reads the data and emits stacks) but doesn't combine - data gets streamed.
- collapses stack traces (takes data from 1 and combines them)
- sort
- render
Now, where I'm going with this is the ability to create a live view from this. we could have cargo flamegraph --serve
that opens a port and lets you see the flame graph building up live in the browser as your system runs.
And I imagine the same interface, as it is more split apart will also work for other tools or am I missing something?
from inferno.
Sounds good to me; I should be able to produce such iterator easily.
I wonder though if in the long run an interface which has collapsing integrated wouldn't be better - the extra integration could probably me made more performant, and it would be potentially simpler to use.
Something like this maybe:
struct FlameBuilder<T> {}
impl FlameBuilder<T> where T: PartialEq + Eq + PartialOrd + Ord + ... {
fn new() -> Self {}
fn add_stack_trace<I>(&mut self, I)
where I: IntoIterator<Item = T> {}
fn generate<F>(self, output: F, write_frame: W) -> Result<()>
where F: Write, W: FnMut(&T, &mut F) -> Result<()> {}
}
The write_frame
is there since the T
s might not be strings, e.g. in my case they wouln't be printable by themselves as they contain IDs to interned strings, hence the customizable writer.
from inferno.
@koute sadly the algorithm for producing the flamegraph actually requires walking through all the frames present in each stack sample. That's why I proposed the above: we need both the count for each stack sample present, and the frames of that stack sample to be able to detect and merge shared parent frames.
from inferno.
@jonhoo The API in my post does allow you to walk through all the frames though. (: The add_stack_trace
method isn't meant to be called only once per a unique stack trace, but once every sample, so it can be internally collated and processed in whatever way you'd see fit. (I guess add_sample
would be a better name for it; sorry, it was late and I was tired.)
from inferno.
Oh, I see. Hmm, I still don't think that's enough, as we actually need to walk each stack multiple times (twice, specifically) to do the merging. Maybe if we require that the iterator also be Clone
?
Actually, thinking some more about it, that interface looks more like what you'd pass to collapse
than to flamegraph
. collapse
would then collapse the samples into their counts, and then pass that to flamegraph
. Keeping that interface generic I think will be tricky. One alternative would be to include the collapsed count in add_stack_trace
, and then you could totally have it be the interface to flamegraph
.
from inferno.
Yes, it does look like an interface to collapse
, and that's deliberate. The distinction between collapsing the stack traces and generating the flamegraph is somewhat artificial I think - it definitely makes sense for standalone scripts since you want multiple collapse
-like scripts to normalize the input (which can be of various different formats) into a common format and one flamegraph
script to generate the desired output, however for an API you'd ideally want to just throw a bunch of stack traces and have the library massage it in whatever way it deems necessary.
Oh, I see. Hmm, I still don't think that's enough, as we actually need to walk each stack multiple times (twice, specifically) to do the merging. Maybe if we require that the iterator also be
Clone
?
You don't need to make the iterator Clone
; it'd be enough to mark the T
with Clone
(since those are either going to be integers, or &str
, which are both cheap to copy), and then you could whatever with those, e.g. push those frames to a Vec
, and then you can iterate over as many times as you'd like (and you can cache the Vec
inside of FlameBuilder
, so it'd be essentially free).
from inferno.
I was more thinking if we don't want to (potentially re-)allocate a Vec
for each stack. I'd be totally fine making what you propose the interface to collapse, and then the same but with counts the interface for flamegraph, and then also provide an interface that's the same as the one to collapse but that also does the flamegraphing (which is then what you'd use).
from inferno.
I'd be totally fine making what you propose the interface to collapse, and then the same but with counts the interface for flamegraph, and then also provide an interface that's the same as the one to collapse but that also does the flamegraphing (which is then what you'd use).
So, basically, we'd have something like this for the "collapse or directly generate a flamegraph":
struct FlameBuilder<T> {}
impl FlameBuilder<T> where T: PartialEq + Eq + PartialOrd + Ord + Clone {
fn new() -> Self {}
fn add_sample<I>(&mut self, I)
where I: IntoIterator<Item = T> {}
fn collapse<F>(self, output: F, write_frame: W) -> Result<()>
where F: Write, W: FnMut(&T, &mut F) -> Result<()> {}
fn generate_flamegraph<F>(self, output: F, write_frame: W) -> Result<()>
where F: Write, W: FnMut(&T, &mut F) -> Result<()> {}
}
and another (different) interface just for generating a flamegraph from already collapsed frames?
from inferno.
Almost. The stuff the code has to do in response to an add_sample
call differs depending on whether you're just trying to collapse or also wanting to produce a flame graph, so I suspect we'll want them to be separate. I also don't think that'll come at too much of a cost, since collapsing will need a separate "pass" anyway.
from inferno.
@koute would something like sketched out in #98 work for noperf?
from inferno.
I'm looking at using inferno to generate flame charts, has there been any progress on a programmatic api?
from inferno.
Not beyond the discussion you see in this issue, no. But if you want to take a stab at writing up a PR, I'd be happy to review it!
from inferno.
I've poked around the code a bit, but I'm not really sure how things go from trace file to flamegraph, is all the data that's involved a number of samples and some strings? Shouldn't some sort of duration or something be involved too? (Disclaimer: I'm not familiar with the ins and outs of flamegraphs whatsoever so forgive me if I'm missing something)
from inferno.
Sorry to be so slow to get back to you — I'm very short on spare time these days it seems. Maybe @jasonrhansen can give you some pointers?
from inferno.
Related Issues (20)
- Color diffusion mode gives less useful results in flamechart mode HOT 2
- Support for simplifying recursive function calls as stackcollapse perl scripts HOT 7
- Support for collapsing source lines from -F+srcline in `perf script` outputs HOT 1
- atty 0.2 has a potential unaligned read HOT 3
- 0.11.15 build fails on Rust 1.62 HOT 1
- Single stack detection can be wrong if the event contains multiple colon HOT 3
- `Input data ends in the middle of a stack.` when using on result of attaching HOT 1
- Differential output tooltips are confusing HOT 4
- Differential output only calculates diff correctly for leaves (most specific frames) HOT 4
- support hot/cold flamegraphs HOT 1
- Document cargo features in readme HOT 1
- flamegraph does not contain sys_enter_* calls with params HOT 3
- Documentation, especially of folded format HOT 3
- publish packages HOT 5
- Error in generated SVG: PCDATA invalid Char value (macos) HOT 5
- Dependencies versions too loose HOT 1
- wallClockProfiler support
- graph diffs from perl flamegraph HOT 3
- Upgrade quick-xml
- Align FlameGraph color scheme to match original Perl script output HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from inferno.