288 lines
6.6 KiB
HTML
288 lines
6.6 KiB
HTML
|
<html>
|
||
|
<head>
|
||
|
<title>
|
||
|
Trace Events
|
||
|
</title>
|
||
|
<style>
|
||
|
body {
|
||
|
font-family: "Courier New";
|
||
|
font-size: 9pt;
|
||
|
}
|
||
|
|
||
|
#header {
|
||
|
position: absolute;
|
||
|
top: 0px;
|
||
|
left: 0px;
|
||
|
border-bottom: 1px dashed black;
|
||
|
background-color: #F0F0F0;
|
||
|
z-index: 3;
|
||
|
}
|
||
|
|
||
|
#outer {
|
||
|
position: relative;
|
||
|
height: 200px;
|
||
|
}
|
||
|
|
||
|
#time_scale {
|
||
|
height: 15px;
|
||
|
width: 100%;
|
||
|
}
|
||
|
|
||
|
#tooltip {
|
||
|
position: absolute;
|
||
|
background-color: #FFFFCC;
|
||
|
display: none;
|
||
|
font-family: "Courier New";
|
||
|
font-size: 9pt;
|
||
|
padding: 5px;
|
||
|
border: 1px solid #CCCC88;
|
||
|
z-index: 3;
|
||
|
}
|
||
|
|
||
|
#legend {
|
||
|
position: fixed;
|
||
|
left: 10px;
|
||
|
bottom: 10px;
|
||
|
padding: 5px;
|
||
|
border: 1px solid silver;
|
||
|
z-index: 10;
|
||
|
background-color: #f0f0f0;
|
||
|
}
|
||
|
|
||
|
h2 {
|
||
|
margin: 5px;
|
||
|
}
|
||
|
|
||
|
#instructions {
|
||
|
position: absolute;
|
||
|
top:
|
||
|
float: right;
|
||
|
display: none;
|
||
|
}
|
||
|
|
||
|
li.time_tick {
|
||
|
background-color: #FFFFCC;
|
||
|
height: 15px;
|
||
|
}
|
||
|
|
||
|
li {
|
||
|
background: pink;
|
||
|
position: absolute;
|
||
|
height: 10px;
|
||
|
list-style: none;
|
||
|
margin: 0px;
|
||
|
padding: 0px;
|
||
|
z-index: 2;
|
||
|
}
|
||
|
|
||
|
li:hover {
|
||
|
border: 1px solid red;
|
||
|
}
|
||
|
|
||
|
.url {
|
||
|
background-color: green;
|
||
|
}
|
||
|
|
||
|
.http {
|
||
|
background-color: blue;
|
||
|
}
|
||
|
|
||
|
.socket {
|
||
|
background-color: black;
|
||
|
}
|
||
|
|
||
|
.v8 {
|
||
|
background-color: orange;
|
||
|
}
|
||
|
|
||
|
</style>
|
||
|
|
||
|
<script src='trace_data.js'></script>
|
||
|
<script>
|
||
|
var scale = 100000;
|
||
|
var row_height = 15;
|
||
|
var trace_initial_time = 0;
|
||
|
var trace_threads = {};
|
||
|
var heartbeats = [];
|
||
|
var trace_total_time = 0;
|
||
|
|
||
|
function process_raw_events() {
|
||
|
trace_initial_time = raw_trace_events[0].usec_begin;
|
||
|
var stack = [];
|
||
|
var e;
|
||
|
for (var i in raw_trace_events) {
|
||
|
e = raw_trace_events[i];
|
||
|
var trace_events = trace_threads["e.tid"];
|
||
|
if (!trace_events) {
|
||
|
trace_events = [];
|
||
|
trace_threads["e.tid"] = trace_events;
|
||
|
}
|
||
|
if (e.name.indexOf("heartbeat.") == 0) {
|
||
|
heartbeats.push(e);
|
||
|
} else if (e.type == "BEGIN") {
|
||
|
trace_events.push(e);
|
||
|
stack.unshift(e);
|
||
|
} else if (e.type == "END") {
|
||
|
for (var s in stack) {
|
||
|
var begin = stack[s];
|
||
|
if ((begin.id == e.id) && (begin.name == e.name) &&
|
||
|
(begin.pid == e.pid) && (begin.tid == e.tid)) {
|
||
|
begin.usec_end = e.usec_begin;
|
||
|
begin.duration = begin.usec_end - begin.usec_begin;
|
||
|
stack.splice(s, 1);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
} else if (e.type == "INSTANT") {
|
||
|
trace_events.push(e);
|
||
|
e.duration = 0;
|
||
|
}
|
||
|
}
|
||
|
if (e.usec_end)
|
||
|
trace_total_time = e.usec_end - trace_initial_time;
|
||
|
else
|
||
|
trace_total_time = e.usec_begin - trace_initial_time;
|
||
|
}
|
||
|
|
||
|
function compute_scale() {
|
||
|
var outer = document.getElementById("outer");
|
||
|
scale = Math.floor(trace_total_time / (outer.offsetWidth - (row_height * 2)));
|
||
|
};
|
||
|
|
||
|
function show_details(tid, i, event) {
|
||
|
var trace_events = trace_threads["e.tid"];
|
||
|
var inner = trace_events[i].name + " " +
|
||
|
trace_events[i].duration / 1000 + "ms<br />" +
|
||
|
trace_events[i].id + "<br />" +
|
||
|
trace_events[i].extra + "<br />";
|
||
|
var tooltip = document.getElementById("tooltip");
|
||
|
tooltip.innerHTML = inner;
|
||
|
if (window.event)
|
||
|
event = window.event;
|
||
|
tooltip.style.top = event.pageY + 3;
|
||
|
tooltip.style.left = event.pageX + 3;
|
||
|
tooltip.style.display = "block";
|
||
|
};
|
||
|
|
||
|
function generate_time_scale() {
|
||
|
var view_size = window.clientWidth;
|
||
|
var body_size = document.body.scrollWidth;
|
||
|
var inner = "";
|
||
|
|
||
|
var step_ms = Math.floor(scale / 10); // ms per 100px
|
||
|
var pow10 = Math.pow(10, Math.floor(Math.log(step_ms) / Math.log(10)));
|
||
|
var round = .5 * pow10;
|
||
|
step_ms = round * (Math.floor(step_ms / round)); // round to a multiple of round
|
||
|
for (var i = step_ms; i < trace_total_time / 1000; i += step_ms) {
|
||
|
var x = Math.floor(i * 1000 / scale);
|
||
|
inner += "<li class='time_tick' style='left: " + x + "px'>" + i + "</li>";
|
||
|
}
|
||
|
var time_scale = document.getElementById("time_scale");
|
||
|
time_scale.innerHTML = inner;
|
||
|
time_scale.style.width = document.body.scrollWidth;
|
||
|
}
|
||
|
|
||
|
function generate_subchart(trace_events, top) {
|
||
|
var inner = "";
|
||
|
var last_max_time = 0;
|
||
|
var last_max_x = 0;
|
||
|
for (var i in trace_events) {
|
||
|
var e = trace_events[i];
|
||
|
var start_time = e.usec_begin - trace_initial_time;
|
||
|
var left = row_height + Math.floor(start_time / scale);
|
||
|
var width = Math.floor(e.duration / scale);
|
||
|
if (width == 0)
|
||
|
width = 1;
|
||
|
if (start_time < last_max_time)
|
||
|
top += row_height;
|
||
|
var style = "top: " + top + "px; left: " + left + "px; width: " + width + "px;";
|
||
|
var js = 'javascript:show_details("' + e.tid + '", ' + i + ', event);';
|
||
|
var cls = e.name.split('.')[0];
|
||
|
inner += "<li class='" + cls + "' onmouseover='" + js + "' id='li-" + i + "' style='" + style + "'></li>\n";
|
||
|
last_max_time = start_time + e.duration;
|
||
|
last_max_x = left + width;
|
||
|
}
|
||
|
var subchart = document.createElement('div');
|
||
|
subchart.setAttribute("class", "subchart");
|
||
|
subchart.setAttribute("id", trace_events[0].tid);
|
||
|
subchart.innerHTML = inner;
|
||
|
subchart.style.height = top + row_height;
|
||
|
subchart.style.width = row_height + last_max_x;
|
||
|
var chart = document.getElementById("chart");
|
||
|
chart.appendChild(subchart);
|
||
|
|
||
|
return top;
|
||
|
};
|
||
|
|
||
|
function generate_chart() {
|
||
|
var chart = document.getElementById("chart");
|
||
|
chart.innerHTML = "";
|
||
|
var top = 60;
|
||
|
for (var t in trace_threads) {
|
||
|
top = generate_subchart(trace_threads[t], top);
|
||
|
}
|
||
|
generate_time_scale();
|
||
|
}
|
||
|
|
||
|
function change_scale(event) {
|
||
|
if (!event)
|
||
|
event = window.event;
|
||
|
if (!event.shiftKey)
|
||
|
return;
|
||
|
var delta = 0;
|
||
|
if (event.wheelDelta) {
|
||
|
delta = event.wheelDelta / 120;
|
||
|
} else if (event.detail) {
|
||
|
delta = - event.detail / 3;
|
||
|
}
|
||
|
if (delta) {
|
||
|
var tooltip = document.getElementById("tooltip");
|
||
|
tooltip.style.display = "none";
|
||
|
var factor = 1.1;
|
||
|
if (delta < 0)
|
||
|
scale = Math.floor(scale * factor);
|
||
|
else
|
||
|
scale = Math.floor(scale / factor);
|
||
|
if (scale > 300000)
|
||
|
scale = 300000;
|
||
|
generate_chart();
|
||
|
if (event.preventDefault)
|
||
|
event.preventDefault();
|
||
|
}
|
||
|
event.returnValue = false;
|
||
|
};
|
||
|
|
||
|
function initial_load() {
|
||
|
if (window.addEventListener)
|
||
|
window.addEventListener('DOMMouseScroll', change_scale, false);
|
||
|
window.onmousewheel = document.onmousewheel = change_scale;
|
||
|
|
||
|
process_raw_events();
|
||
|
compute_scale();
|
||
|
generate_chart();
|
||
|
};
|
||
|
|
||
|
</script>
|
||
|
</head>
|
||
|
<body onload='initial_load();'>
|
||
|
<div id="header">
|
||
|
<h2>Trace Events</h2>
|
||
|
<div id="instructions">
|
||
|
Use shift+mouse-wheel to zoom in and out.
|
||
|
</div>
|
||
|
<div id="time_scale"></div>
|
||
|
</div>
|
||
|
<div id="legend">
|
||
|
<span class="url"> </span> URL<br />
|
||
|
<span class="http"> </span> HTTP<br />
|
||
|
<span class="socket"> </span> Socket<br />
|
||
|
<span class="v8"> </span> V8<br />
|
||
|
</div>
|
||
|
<div id="chart">
|
||
|
<div id="outer">
|
||
|
</div>
|
||
|
</div>
|
||
|
<div id="tooltip" ondblclick="this.style.display = 'none';"></div>
|
||
|
</body>
|
||
|
</html>
|