1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
use std::io::Write; use std::io::Result as IoResult; use super::{SpanPtr, Span, ThreadFrame}; use std::collections::BTreeMap; use std::rc::Rc; pub fn dump_html<W: Write>(out: &mut W, frame: &ThreadFrame) -> IoResult<()> { fn dump_span<W: Write>(out: &mut W, name:&'static str, span: &Span) -> IoResult<()>{ try!(writeln!(out, "{{")); try!(writeln!(out, r#"name: "{}","#, name)); try!(writeln!(out, "value: {},", span.value)); try!(writeln!(out, "count: {},", span.count)); try!(writeln!(out, "children: [")); try!(dump_spans(out, &span.children)); try!(writeln!(out, "],")); try!(writeln!(out, "}}")); try!(writeln!(out, ",")); Ok(()) } fn dump_spans<W: Write>(out: &mut W, spans:& BTreeMap<&'static str, Rc<SpanPtr>> ) -> IoResult<()> { for (name, span) in spans.iter() { let span = span.borrow(); try!(dump_span(out, name, &span)); } Ok(()) } try!(write!(out, r#" <!doctype html> <html> <head> <style> html, body {{ width: 100%; height: 100%; margin: 0; padding: 0; }} {} </style> <script> {} {} {} </script> </head> <body> <script> var width = document.body.offsetWidth; var height = document.body.offsetHeight - 100; var flamegraph = d3.flameGraph() .width(width) .height(height) .tooltip(false) .sort(function(a, b){{ if (a.dummy){{ return 1 }} if (b.value < a.value) {{ return -1; }} else if (a.value > b.value) {{ return -1; }} else {{ return 0; }} }}); d3.select("body").datum({{ children: [ "#, include_str!("../resources/flameGraph.css"), include_str!("../resources/d3.js"), include_str!("../resources/d3-tip.js"), include_str!("../resources/flameGraph.js"))); let spans = frame.root(); let mut root = spans.borrow().clone(); root.value = frame.time_since_start(); try!(dump_span(out, "Self", &root)); try!(write!(out, r#"]}}).call(flamegraph); </script> </body> </html>"#)); Ok(()) }