summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormbelshe@google.com <mbelshe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-05 07:15:27 +0000
committermbelshe@google.com <mbelshe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-05 07:15:27 +0000
commitafb14af4fd9db9c357b391c1cbb6b95e25bb82a3 (patch)
tree0a63f8a6f2389928bc19bbd11c53030818f6d9da
parent98179700f91d242ce6a4edb5f0865e12d3a662c6 (diff)
downloadchromium_src-afb14af4fd9db9c357b391c1cbb6b95e25bb82a3.zip
chromium_src-afb14af4fd9db9c357b391c1cbb6b95e25bb82a3.tar.gz
chromium_src-afb14af4fd9db9c357b391c1cbb6b95e25bb82a3.tar.bz2
Checkin Erik's tracing tool.
Added a short writeup about how to use it at the top. TEST=none BUG=none Review URL: http://codereview.chromium.org/118275 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17721 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/tools/tracing/trace.html395
1 files changed, 395 insertions, 0 deletions
diff --git a/chrome/tools/tracing/trace.html b/chrome/tools/tracing/trace.html
new file mode 100644
index 0000000..f6dd14c
--- /dev/null
+++ b/chrome/tools/tracing/trace.html
@@ -0,0 +1,395 @@
+<!--
+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">&nbsp;</span> URL<br />
+<span class="http">&nbsp;</span> HTTP<br />
+<span class="socket">&nbsp;</span> Socket<br />
+<span class="v8">&nbsp;</span> V8<br />
+<span class="loop">&nbsp;</span> TASKS<br />
+</div>
+<div id="chart">
+<div id="outer">
+</div>
+</div>
+<div id="tooltip" ondblclick="this.style.display = 'none';"></div>
+</body>
+</html>