|  | <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> |