Home | History | Annotate | Download | only in trace
      1 <html>
      2 <head>
      3 <title>
      4 Trace Events
      5 </title>
      6 <style>
      7 body {
      8   font-family: "Courier New";
      9   font-size: 9pt;
     10 }
     11 
     12 #header {
     13   position: absolute;
     14   top: 0px;
     15   left: 0px;
     16   border-bottom: 1px dashed black;
     17   background-color: #F0F0F0;
     18   z-index: 3;
     19 }
     20 
     21 #outer {
     22   position: relative;
     23   height: 200px;
     24 }
     25 
     26 #time_scale {
     27   height: 15px;
     28   width: 100%;
     29 }
     30 
     31 #tooltip {
     32   position: absolute;
     33   background-color: #FFFFCC;
     34   display: none;
     35   font-family: "Courier New";
     36   font-size: 9pt;
     37   padding: 5px;
     38   border: 1px solid #CCCC88;
     39   z-index: 3;
     40 }
     41 
     42 #legend {
     43   position: fixed;
     44   left: 10px;
     45   bottom: 10px;
     46   padding: 5px;
     47   border: 1px solid silver;
     48   z-index: 10;
     49   background-color: #f0f0f0;
     50 }
     51 
     52 h2 {
     53   margin: 5px;
     54 }
     55 
     56 #instructions {
     57   position: absolute;
     58   top: 
     59   float: right;
     60   display: none;
     61 }
     62 
     63 li.time_tick {
     64   background-color: #FFFFCC;
     65   height: 15px;
     66 }
     67 
     68 li {
     69   background: pink;
     70   position: absolute;
     71   height: 10px;
     72   list-style: none;
     73   margin: 0px;
     74   padding: 0px;
     75   z-index: 2;
     76 }
     77 
     78 li:hover {
     79   border: 1px solid red;
     80 }
     81 
     82 .url {
     83   background-color: green;
     84 }
     85 
     86 .http {
     87   background-color: blue;
     88 }
     89 
     90 .socket {
     91   background-color: black;
     92 }
     93 
     94 .v8 {
     95   background-color: orange; 
     96 }
     97 
     98 </style>
     99 
    100 <script src='trace_data.js'></script>
    101 <script>
    102 var scale = 100000;
    103 var row_height = 15;
    104 var trace_initial_time = 0;
    105 var trace_threads = {};
    106 var heartbeats = [];
    107 var trace_total_time = 0;
    108 
    109 function process_raw_events() {
    110   trace_initial_time = raw_trace_events[0].usec_begin;
    111   var stack = [];
    112   var e;
    113   for (var i in raw_trace_events) {
    114     e = raw_trace_events[i];
    115     var trace_events = trace_threads["e.tid"];
    116     if (!trace_events) {
    117       trace_events = [];
    118       trace_threads["e.tid"] = trace_events;
    119     }
    120     if (e.name.indexOf("heartbeat.") == 0) {
    121       heartbeats.push(e);
    122     } else if (e.type == "BEGIN") {
    123       trace_events.push(e);
    124       stack.unshift(e);
    125     } else if (e.type == "END") {
    126       for (var s in stack) {
    127         var begin = stack[s];
    128         if ((begin.id == e.id) && (begin.name == e.name) &&
    129             (begin.pid == e.pid) && (begin.tid == e.tid)) {
    130           begin.usec_end = e.usec_begin;
    131           begin.duration = begin.usec_end - begin.usec_begin;
    132           stack.splice(s, 1);
    133           break;
    134         } 
    135       }
    136     } else if (e.type == "INSTANT") {
    137       trace_events.push(e);
    138       e.duration = 0;
    139     }
    140   }
    141   if (e.usec_end)
    142     trace_total_time = e.usec_end - trace_initial_time;
    143   else
    144     trace_total_time = e.usec_begin - trace_initial_time;
    145 }
    146 
    147 function compute_scale() {
    148   var outer = document.getElementById("outer");
    149   scale = Math.floor(trace_total_time / (outer.offsetWidth - (row_height * 2)));
    150 };
    151 
    152 function show_details(tid, i, event) {
    153   var trace_events = trace_threads["e.tid"];
    154   var inner = trace_events[i].name + " " +
    155               trace_events[i].duration / 1000 + "ms<br />" + 
    156               trace_events[i].id  + "<br />" + 
    157               trace_events[i].extra  + "<br />";
    158   var tooltip = document.getElementById("tooltip");
    159   tooltip.innerHTML = inner;
    160   if (window.event)
    161     event = window.event;
    162   tooltip.style.top = event.pageY + 3;
    163   tooltip.style.left = event.pageX + 3;
    164   tooltip.style.display = "block";
    165 };
    166 
    167 function generate_time_scale() {
    168   var view_size = window.clientWidth;
    169   var body_size = document.body.scrollWidth;
    170   var inner = "";
    171   
    172   var step_ms = Math.floor(scale / 10); // ms per 100px
    173   var pow10 = Math.pow(10, Math.floor(Math.log(step_ms) / Math.log(10)));
    174   var round = .5 * pow10;
    175   step_ms = round * (Math.floor(step_ms / round)); // round to a multiple of round
    176   for (var i = step_ms; i < trace_total_time / 1000; i += step_ms) {
    177     var x = Math.floor(i * 1000 / scale);
    178     inner += "<li class='time_tick' style='left: " + x + "px'>" + i + "</li>";
    179   }
    180   var time_scale = document.getElementById("time_scale");
    181   time_scale.innerHTML = inner;
    182   time_scale.style.width = document.body.scrollWidth;
    183 }
    184 
    185 function generate_subchart(trace_events, top) {
    186   var inner = "";
    187   var last_max_time = 0;
    188   var last_max_x = 0;
    189   for (var i in trace_events) {
    190     var e = trace_events[i];
    191     var start_time = e.usec_begin - trace_initial_time;
    192     var left = row_height + Math.floor(start_time / scale);
    193     var width = Math.floor(e.duration / scale);
    194     if (width == 0)
    195       width = 1;
    196     if (start_time < last_max_time)
    197       top += row_height;
    198     var style = "top: " + top + "px; left: " + left + "px; width: " + width + "px;";
    199     var js = 'javascript:show_details("' + e.tid + '", ' + i + ', event);';
    200     var cls = e.name.split('.')[0];
    201     inner += "<li class='" + cls + "' onmouseover='" + js + "' id='li-" + i + "' style='" + style + "'></li>\n";
    202     last_max_time = start_time + e.duration;
    203     last_max_x = left + width;
    204   }
    205   var subchart = document.createElement('div');
    206   subchart.setAttribute("class", "subchart");
    207   subchart.setAttribute("id", trace_events[0].tid);
    208   subchart.innerHTML = inner;
    209   subchart.style.height = top + row_height;
    210   subchart.style.width = row_height + last_max_x;
    211   var chart = document.getElementById("chart");
    212   chart.appendChild(subchart);
    213   
    214   return top;
    215 };
    216 
    217 function generate_chart() {
    218   var chart = document.getElementById("chart");
    219   chart.innerHTML = "";
    220   var top = 60;
    221   for (var t in trace_threads) {
    222     top = generate_subchart(trace_threads[t], top);
    223   }
    224   generate_time_scale();
    225 }
    226 
    227 function change_scale(event) {
    228   if (!event)
    229     event = window.event;
    230   if (!event.shiftKey)
    231     return;
    232   var delta = 0;
    233   if (event.wheelDelta) {
    234     delta = event.wheelDelta / 120;
    235   } else if (event.detail) {
    236     delta = - event.detail / 3;
    237   }
    238   if (delta) {
    239     var tooltip = document.getElementById("tooltip");
    240     tooltip.style.display = "none";
    241     var factor = 1.1;
    242     if (delta < 0)
    243       scale = Math.floor(scale * factor);
    244     else
    245       scale = Math.floor(scale / factor);
    246     if (scale > 300000)
    247       scale = 300000;
    248     generate_chart();
    249     if (event.preventDefault)
    250       event.preventDefault();
    251   }
    252   event.returnValue = false;
    253 };
    254 
    255 function initial_load() {
    256   if (window.addEventListener)
    257     window.addEventListener('DOMMouseScroll', change_scale, false);
    258   window.onmousewheel = document.onmousewheel = change_scale;
    259 
    260   process_raw_events();
    261   compute_scale();
    262   generate_chart();
    263 };
    264 
    265 </script>
    266 </head>
    267 <body onload='initial_load();'>
    268 <div id="header">
    269 <h2>Trace Events</h2>
    270 <div id="instructions">
    271 Use shift+mouse-wheel to zoom in and out.
    272 </div>
    273 <div id="time_scale"></div>
    274 </div>
    275 <div id="legend">
    276 <span class="url">&nbsp;</span> URL<br />
    277 <span class="http">&nbsp;</span> HTTP<br />
    278 <span class="socket">&nbsp;</span> Socket<br />
    279 <span class="v8">&nbsp;</span> V8<br />
    280 </div>
    281 <div id="chart">
    282 <div id="outer">
    283 </div>
    284 </div>
    285 <div id="tooltip" ondblclick="this.style.display = 'none';"></div>
    286 </body>
    287 </html>
    288