-<!--\r
-Tracing template\r
-----------------\r
-Test_shell has an optional tracing feature. It can be enabled by running\r
-with the --enable-tracing option. Tracing causes events to be dropped into\r
-a trace file during runtime.\r
-\r
-This HTML file can be used to render the output from the trace. You'll need\r
-to rename your trace data to "trace_data.js" in the same directory with this\r
-HTML file, and then you can visualize the trace.\r
-\r
-Lots of work remains on this tracing tool; currently development is on hold.\r
-\r
--->\r
-\r
-<html>\r
-<head>\r
-<title>\r
-Trace Events\r
-</title>\r
-<style>\r
-body {\r
- font-family: "Courier New";\r
- font-size: 9pt;\r
-}\r
-\r
-#header {\r
- position: absolute;\r
- top: 0px;\r
- left: 0px;\r
- border-bottom: 1px dashed black;\r
- background-color: #F0F0F0;\r
- z-index: 3;\r
-}\r
-\r
-#outer {\r
- position: relative;\r
- height: 200px;\r
-}\r
-\r
-#time_scale {\r
- height: 15px;\r
- width: 100%;\r
-}\r
-\r
-#tooltip {\r
- position: absolute;\r
- background-color: #FFFFCC;\r
- display: none;\r
- font-family: "Courier New";\r
- font-size: 9pt;\r
- padding: 5px;\r
- border: 1px solid #CCCC88;\r
- z-index: 3;\r
-}\r
-\r
-#legend {\r
- position: fixed;\r
- left: 10px;\r
- bottom: 10px;\r
- padding: 5px;\r
- border: 1px solid silver;\r
- z-index: 10;\r
- background-color: #f0f0f0;\r
-}\r
-\r
-h2 {\r
- margin: 5px;\r
-}\r
-\r
-#instructions {\r
- position: absolute;\r
- top: \r
- float: right;\r
- display: none;\r
-}\r
-\r
-li.time_tick {\r
- background-color: #FFFFCC;\r
- height: 15px;\r
-}\r
-\r
-li {\r
- background: pink;\r
- position: absolute;\r
- height: 10px;\r
- list-style: none;\r
- margin: 0px;\r
- padding: 0px;\r
- z-index: 2;\r
-}\r
-\r
-li:hover {\r
- border: 1px solid red;\r
-}\r
-\r
-.url {\r
- background-color: green;\r
-}\r
-\r
-.http {\r
- background-color: blue;\r
-}\r
-\r
-.socket {\r
- background-color: black;\r
-}\r
-\r
-.v8 {\r
- background-color: orange; \r
-}\r
-\r
-.loop {\r
- background-color: gray; \r
-}\r
-\r
-.io {\r
- background-color: blue;\r
-}\r
-\r
-</style>\r
-\r
-<script src='trace_data.js'></script>\r
-<script>\r
-var scale = 100000;\r
-var row_height = 15;\r
-var trace_initial_time = 0;\r
-var trace_threads = {};\r
-var heartbeats = [];\r
-var trace_total_time = 0;\r
-\r
-function process_raw_events() {\r
- trace_initial_time = raw_trace_events[0].usec_begin;\r
- var stack = [];\r
- var e;\r
- for (var i in raw_trace_events) {\r
- e = raw_trace_events[i];\r
- var trace_events = trace_threads["e.tid"];\r
- if (!trace_events) {\r
- trace_events = [];\r
- trace_threads["e.tid"] = trace_events;\r
- }\r
- if (e.name.indexOf("heartbeat.") == 0) {\r
- heartbeats.push(e);\r
- } else if (e.type == "BEGIN") {\r
- trace_events.push(e);\r
- stack.unshift(e);\r
- } else if (e.type == "END") {\r
- for (var s in stack) {\r
- var begin = stack[s];\r
- if ((begin.id == e.id) && (begin.name == e.name) &&\r
- (begin.pid == e.pid) && (begin.tid == e.tid)) {\r
- begin.usec_end = e.usec_begin;\r
- begin.duration = begin.usec_end - begin.usec_begin;\r
- begin.extra += " " + e.extra;\r
- stack.splice(s, 1);\r
- break;\r
- } \r
- }\r
- } else if (e.type == "INSTANT") {\r
- trace_events.push(e);\r
- e.duration = 0;\r
- }\r
- }\r
- if (e.usec_end)\r
- trace_total_time = e.usec_end - trace_initial_time;\r
- else\r
- trace_total_time = e.usec_begin - trace_initial_time;\r
-}\r
-\r
-function compute_scale() {\r
- var outer = document.getElementById("outer");\r
- scale = Math.floor(trace_total_time / (outer.offsetWidth - (row_height * 2)));\r
-};\r
-\r
-function show_details(tid, i, event) {\r
- var trace_events = trace_threads["e.tid"];\r
- var inner = trace_events[i].name + " " +\r
- trace_events[i].duration / 1000 + "ms<br />" + \r
- trace_events[i].id + "<br />" + \r
- trace_events[i].extra + "<br />";\r
- var tooltip = document.getElementById("tooltip");\r
- tooltip.innerHTML = inner;\r
- if (window.event)\r
- event = window.event;\r
- tooltip.style.top = event.pageY + 3;\r
- tooltip.style.left = event.pageX + 3;\r
- tooltip.style.display = "block";\r
-};\r
-\r
-function generate_time_scale() {\r
- var view_size = window.clientWidth;\r
- var body_size = document.body.scrollWidth;\r
- var inner = "";\r
- \r
- var step_ms = Math.floor(scale / 10); // ms per 100px\r
- var pow10 = Math.pow(10, Math.floor(Math.log(step_ms) / Math.log(10)));\r
- var round = .5 * pow10;\r
- step_ms = round * (Math.floor(step_ms / round)); // round to a multiple of round\r
- for (var i = step_ms; i < trace_total_time / 1000; i += step_ms) {\r
- var x = Math.floor(i * 1000 / scale);\r
- inner += "<li class='time_tick' style='left: " + x + "px'>" + i + "</li>";\r
- }\r
- var time_scale = document.getElementById("time_scale");\r
- time_scale.innerHTML = inner;\r
- time_scale.style.width = document.body.scrollWidth;\r
-}\r
-\r
-function generate_io_graph(trace_events, top) {\r
- var max_height = 200;\r
- var bucket_size = 50000; // millisecs\r
-\r
- var inner = "";\r
- var buckets = new Array();\r
- var value = 0;\r
- var max_bucket = 0;\r
-\r
- // Go through events and find all read samples.\r
- // Aggregate data into buckets.\r
- for (var i in trace_events) {\r
- var e = trace_events[i];\r
- if (e.name != "socket.read") {\r
- continue;\r
- }\r
-\r
- var bytes = parseInt(e.extra);\r
-// bytes = 400;\r
-\r
- var start_time = e.usec_begin - trace_initial_time;\r
- var mybucket = Math.floor(start_time / bucket_size);\r
-\r
- if (buckets[mybucket] == undefined) {\r
- buckets[mybucket] = 0;\r
- }\r
- buckets[mybucket] += bytes;\r
-\r
- if (buckets[max_bucket] == undefined || \r
- buckets[max_bucket] < buckets[mybucket]) {\r
- max_bucket = mybucket;\r
- }\r
- }\r
-\r
- for (var index = 0; index < buckets.length; index++) {\r
- var left = index * Math.floor(bucket_size / scale);\r
- var width = Math.floor(bucket_size / scale);\r
- if (width == 0)\r
- width = 1;\r
-\r
- var height;\r
- if (buckets[index] == undefined) {\r
- height = 0;\r
- } else {\r
- height = (buckets[index] / buckets[max_bucket]) * max_height;\r
- }\r
-\r
- var my_top = max_height - height;\r
-\r
- var style = "top: " + my_top + "px; left: " + left + "px; width: " + width + "px; height:" + height + "px;";\r
- var cls = "io";\r
- inner += "<li title='" + buckets[index] + " bytes' class='" + cls + "' id='li-" + i + "' style='" + style + "'></li>\n";\r
- }\r
-\r
- var subchart = document.createElement('div');\r
- subchart.setAttribute("class", "iograph");\r
- subchart.setAttribute("id", trace_events[0].tid);\r
- subchart.innerHTML = inner;\r
- subchart.style.height = max_height;\r
- subchart.style.top = top;\r
- subchart.style.left = 0;\r
- subchart.style.position = "absolute";\r
-// subchart.style.width = row_height + last_max_x;\r
- var chart = document.getElementById("chart");\r
- chart.appendChild(subchart);\r
-\r
- return top + max_height;\r
-}\r
-\r
-function generate_subchart(trace_events, top) {\r
- var start_top = top;\r
- var heights = new Array();\r
- var max_row = 0;\r
- var inner = "";\r
- var last_max_time = 0;\r
- var last_max_x = 0;\r
- for (var i in trace_events) {\r
- var e = trace_events[i];\r
- var start_time = e.usec_begin - trace_initial_time;\r
- var left = row_height + Math.floor(start_time / scale);\r
- var width = Math.floor(e.duration / scale);\r
- if (width == 0)\r
- width = 1;\r
-\r
- if (heights[e.id]) {\r
- top = heights[e.id];\r
- } else {\r
- max_row += row_height;\r
- heights[e.id] = max_row;\r
- top = heights[e.id];\r
- }\r
- //if (start_time < last_max_time)\r
- // top += row_height;\r
- var style = "top: " + top + "px; left: " + left + "px; width: " + width + "px;";\r
- var js = 'javascript:show_details("' + e.tid + '", ' + i + ', event);';\r
- var cls = e.name.split('.')[0];\r
- inner += "<li class='" + cls + "' onmouseover='" + js + "' id='li-" + i + "' style='" + style + "'></li>\n";\r
- last_max_time = start_time + e.duration;\r
- last_max_x = left + width;\r
- }\r
- var subchart = document.createElement('div');\r
- subchart.setAttribute("class", "subchart");\r
- subchart.setAttribute("id", trace_events[0].tid);\r
- subchart.innerHTML = inner;\r
- subchart.style.top = start_top + "px";\r
- subchart.style.height = top + row_height;\r
- subchart.style.width = row_height + last_max_x;\r
- subchart.style.position = "absolute";\r
- var chart = document.getElementById("chart");\r
- chart.appendChild(subchart);\r
- \r
- return top;\r
-};\r
-\r
-function generate_chart() {\r
- var chart = document.getElementById("chart");\r
- chart.innerHTML = "";\r
- var top = 60;\r
- for (var t in trace_threads) {\r
- top = generate_io_graph(trace_threads[t], top);\r
- top = generate_subchart(trace_threads[t], top);\r
- }\r
- generate_time_scale();\r
-}\r
-\r
-function change_scale(event) {\r
- if (!event)\r
- event = window.event;\r
- if (!event.shiftKey)\r
- return;\r
- var delta = 0;\r
- if (event.wheelDelta) {\r
- delta = event.wheelDelta / 120;\r
- } else if (event.detail) {\r
- delta = - event.detail / 3;\r
- }\r
- if (delta) {\r
- var tooltip = document.getElementById("tooltip");\r
- tooltip.style.display = "none";\r
- var factor = 1.1;\r
- if (delta < 0)\r
- scale = Math.floor(scale * factor);\r
- else\r
- scale = Math.floor(scale / factor);\r
- if (scale > 300000)\r
- scale = 300000;\r
- generate_chart();\r
- if (event.preventDefault)\r
- event.preventDefault();\r
- }\r
- event.returnValue = false;\r
-};\r
-\r
-function initial_load() {\r
- if (window.addEventListener)\r
- window.addEventListener('DOMMouseScroll', change_scale, false);\r
- window.onmousewheel = document.onmousewheel = change_scale;\r
-\r
- process_raw_events();\r
- compute_scale();\r
- generate_chart();\r
-};\r
-\r
-</script>\r
-</head>\r
-<body onload='initial_load();'>\r
-<div id="header">\r
-<h2>Trace Events</h2>\r
-<div id="instructions">\r
-Use shift+mouse-wheel to zoom in and out.\r
-</div>\r
-<div id="time_scale"></div>\r
-</div>\r
-<div id="legend">\r
-<span class="url"> </span> URL<br />\r
-<span class="http"> </span> HTTP<br />\r
-<span class="socket"> </span> Socket<br />\r
-<span class="v8"> </span> V8<br />\r
-<span class="loop"> </span> TASKS<br />\r
-</div>\r
-<div id="chart">\r
-<div id="outer">\r
-</div>\r
-</div>\r
-<div id="tooltip" ondblclick="this.style.display = 'none';"></div>\r
-</body>\r
-</html>\r
+<!--
+Tracing template
+----------------
+Test_shell has an optional tracing feature. It can be enabled by running
+with the --enable-tracing option. Tracing causes events to be dropped into
+a trace file during runtime.
+
+This HTML file can be used to render the output from the trace. You'll need
+to rename your trace data to "trace_data.js" in the same directory with this
+HTML file, and then you can visualize the trace.
+
+Lots of work remains on this tracing tool; currently development is on hold.
+
+-->
+
+<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;
+}
+
+.loop {
+ background-color: gray;
+}
+
+.io {
+ background-color: blue;
+}
+
+</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;
+ begin.extra += " " + e.extra;
+ 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_io_graph(trace_events, top) {
+ var max_height = 200;
+ var bucket_size = 50000; // millisecs
+
+ var inner = "";
+ var buckets = new Array();
+ var value = 0;
+ var max_bucket = 0;
+
+ // Go through events and find all read samples.
+ // Aggregate data into buckets.
+ for (var i in trace_events) {
+ var e = trace_events[i];
+ if (e.name != "socket.read") {
+ continue;
+ }
+
+ var bytes = parseInt(e.extra);
+// bytes = 400;
+
+ var start_time = e.usec_begin - trace_initial_time;
+ var mybucket = Math.floor(start_time / bucket_size);
+
+ if (buckets[mybucket] == undefined) {
+ buckets[mybucket] = 0;
+ }
+ buckets[mybucket] += bytes;
+
+ if (buckets[max_bucket] == undefined ||
+ buckets[max_bucket] < buckets[mybucket]) {
+ max_bucket = mybucket;
+ }
+ }
+
+ for (var index = 0; index < buckets.length; index++) {
+ var left = index * Math.floor(bucket_size / scale);
+ var width = Math.floor(bucket_size / scale);
+ if (width == 0)
+ width = 1;
+
+ var height;
+ if (buckets[index] == undefined) {
+ height = 0;
+ } else {
+ height = (buckets[index] / buckets[max_bucket]) * max_height;
+ }
+
+ var my_top = max_height - height;
+
+ var style = "top: " + my_top + "px; left: " + left + "px; width: " + width + "px; height:" + height + "px;";
+ var cls = "io";
+ inner += "<li title='" + buckets[index] + " bytes' class='" + cls + "' id='li-" + i + "' style='" + style + "'></li>\n";
+ }
+
+ var subchart = document.createElement('div');
+ subchart.setAttribute("class", "iograph");
+ subchart.setAttribute("id", trace_events[0].tid);
+ subchart.innerHTML = inner;
+ subchart.style.height = max_height;
+ subchart.style.top = top;
+ subchart.style.left = 0;
+ subchart.style.position = "absolute";
+// subchart.style.width = row_height + last_max_x;
+ var chart = document.getElementById("chart");
+ chart.appendChild(subchart);
+
+ return top + max_height;
+}
+
+function generate_subchart(trace_events, top) {
+ var start_top = top;
+ var heights = new Array();
+ var max_row = 0;
+ 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 (heights[e.id]) {
+ top = heights[e.id];
+ } else {
+ max_row += row_height;
+ heights[e.id] = max_row;
+ top = heights[e.id];
+ }
+ //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.top = start_top + "px";
+ subchart.style.height = top + row_height;
+ subchart.style.width = row_height + last_max_x;
+ subchart.style.position = "absolute";
+ 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_io_graph(trace_threads[t], top);
+ 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 />
+<span class="loop"> </span> TASKS<br />
+</div>
+<div id="chart">
+<div id="outer">
+</div>
+</div>
+<div id="tooltip" ondblclick="this.style.display = 'none';"></div>
+</body>
+</html>