Gracias, Wikipedia.
ShareCode
Permalink: http://www.treeweb.es/u/974/ 01/02/2011

ShareCode

1 <!DOCTYPE html>2 <html>3 <head>4  <title>Trace viewer</title>5  <style type="text/css">6  7  html {8  font-family: sans-serif;9  }10 11  .logs {12  font-family: monospace;13  }14 15  .logs .log-entry {16  font-family: monospace;17  white-space: pre-wrap;18  }19 20  .logs .log-entry[level="DEBUG"] { color: darkblue; }21  .logs .log-entry[level="INFO"] { color: green; }22  .logs .log-entry[level="WARNING"] { color: darkorange; }23  .logs .log-entry[level="ERROR"] { color: purple; }24  .logs .log-entry[level="FATAL"] { color: red; }25 26  .logs .log-entry[select="1"] { background-color: rgba(0,0,0,0.05); }27  .logs .log-entry[select="2"] { background-color: rgba(0,0,255,0.05); }28  .logs .log-entry[select="3"] { background-color: rgba(0,255,0,0.05); }29  .logs .log-entry[select="4"] { background-color: rgba(0,255,255,0.05); }30  .logs .log-entry[select="5"] { background-color: rgba(255,0,0,0.05); }31  .logs .log-entry[select="6"] { background-color: rgba(255,0,255,0.05); }32  .logs .log-entry[select="7"] { background-color: rgba(255,255,0,0.05); }33  .logs .log-entry[select="8"] { background-color: rgba(0,0,127,0.05); }34  .logs .log-entry[select="9"] { background-color: rgba(0,127,0,0.05); }35  .logs .log-entry[select="0"] { background-color: rgba(0,127,127,0.05); }36 37  .logs[select="1"] .log-entry[select="1"],38  .logs[select="2"] .log-entry[select="2"],39  .logs[select="3"] .log-entry[select="3"],40  .logs[select="4"] .log-entry[select="4"],41  .logs[select="5"] .log-entry[select="5"],42  .logs[select="6"] .log-entry[select="6"],43  .logs[select="7"] .log-entry[select="7"],44  .logs[select="8"] .log-entry[select="8"],45  .logs[select="9"] .log-entry[select="9"],46  .logs[select="0"] .log-entry[select="0"] {47  background-color: rgba(0,255,0,0.45);48  }49  50  .viewer {51  position: relative;52  _border: solid silver 1px;53  height: 200px;54  }55 56  .viewer .span {57  background-color: rgba(200,220,255,0.6);58  position: absolute;59  height: 16px;60  cursor: pointer;61  text-align: center;62  font-size: 10px;63  line-height: 16px;64  text-overflow: ellipsis;65  overflow: hidden;66  white-space: nowrap;67  font-family: monospace;68  transition: all 0.5s ease;69  }70 71  .viewer[span_parallel="true"] .span[paralell_index="0"] { top: 0px !important; }72  .viewer[span_parallel="true"] .span[paralell_index="1"] { top: 18px !important; }73  .viewer[span_parallel="true"] .span[paralell_index="2"] { top: 36px !important; }74  .viewer[span_parallel="true"] .span[paralell_index="3"] { top: 0px !important; }75  .viewer[span_parallel="true"] .span[paralell_index="4"] { top: 0px !important; }76  .viewer[span_parallel="true"] .span[paralell_index="5"] { top: 0px !important; }77  .viewer[span_parallel="true"] .span[paralell_index="6"] { top: 0px !important; }78  .viewer[span_parallel="true"] .span[paralell_index="7"] { top: 0px !important; }79  .viewer[span_parallel="true"] .span[paralell_index="8"] { top: 0px !important; }80  .viewer[span_parallel="true"] .span[paralell_index="9"] { top: 0px !important; }81  .viewer[span_parallel="true"] .span[paralell_index="10"] { top: 0px !important; }82 83  .viewer .span:hover {84  box-shadow: 0 0 1px blue;85  } 86 87  .traces [trace_id] {88  font-family: monospace;89  white-space: pre-wrap;90  cursor: pointer;91  }92 93  .traces [trace_id]:hover {94  color: blue;95  }96 97  </style>98 </head>99 <body>100 101  <h1>Trace viewer </h1>102 103  <div>Spans parallel <input id="checkbox_spans_parallel" type="checkbox"></div>104 105  <div class="viewer" id="viewer"></div>106 107  <div style="float:left; width: 340px;">108  <h2>Traces</h2>109  <div>Paste your traces here <textarea id="input_traces" rows="1"></textarea></div>110  <div class="traces" id="div_traces"></div> 111  </div>112 113  <div style="margin-left: 340px;"> 114  <h2>Logs</h2>115  <div class="logs" id="div_logs"></div>116 117  <!--118  <h2>Spare logs</h2>119  <div class="logs" id="spare_logs"></div>120  -->121  </div>122 123  <script type="text/javascript">124 125  var checkbox_spans_parallel = document.getElementById('checkbox_spans_parallel');126  checkbox_spans_parallel.addEventListener('click', function() {127  var viewer = document.getElementById('viewer');128  viewer.setAttribute('span_parallel', this.checked);129  }, true);130 131 132  var lines = [];133 134  var add_line = function(line) {135  lines.push(line);136  };137 138  var span_parallell = true;139 140  var traces = {};141 142  var add_trace = function(line) {143 144  var parts = line.split('|');145 146  if ('TRACE.CREATE' == parts[1]) {147  var details = JSON.parse(parts[4]);148  var traceId = details.traceId;149 150  if (traceId in traces) {151  return true; // Already created :D152  }153 154  var trace = {155  id: traceId,156  namespace: parts[2],157  timestamp: parts[3],158  spans: {},159  }160  traces[traceId] = trace;161 162  print_trace_index(trace);163 164  return true; // Trace created :D165 166  } else if ('TRACE.SPAN.START' == parts[1]) {167  // "V1|TRACE.SPAN.START|ns|ac115589-d06d-49c7-81d5-525eedb48989|1517055732001191061|{"spanId":"71e51a26-c5d8-4de1-a258-463ca8f167af","monitoredResource":{"_id":"59bb80e520988c09f76c8e1f"},"startTime":1517055732001191061,"name":"","kind":"HTTP_SERVER","details":{"protocol":"http"}}"168 169  var traceId = parts[3];170 171  var trace = traces[traceId];172  if (!trace) {173  return false;174  }175 176  var details = JSON.parse(parts[5]);177 178  var spanId = details.spanId;179 180  var span = trace.spans[spanId];181  if (!span) {182  details.logs = [];183  trace.spans[spanId] = details;184  }185 186  return true;187 188  } else if ('TRACE.SPAN.FINISH' == parts[1]) {189  // "V1|TRACE.SPAN.FINISH|ns|ac115589-d06d-49c7-81d5-525eedb48989|1517055732005564980|{"spanId":"71e51a26-c5d8-4de1-a258-463ca8f167af","monitoredResource":{"_id":"59bb80e520988c09f76c8e1f"},"endTime":1517055732005500355,"details":{"http_response_status":201},"properties":{"handler":"/v0/organizations/{organization}:createNamespace","method":"POST","path":"/v0/organizations/jj:createNamespace","url":"/v0/organizations/jj:createNamespace"}}"190 191  var traceId = parts[3];192 193  var trace = traces[traceId];194  if (!trace) {195  return false;196  }197 198  var details = JSON.parse(parts[5]);199 200  var spanId = details.spanId;201 202  var span = trace.spans[spanId];203  if (!span) {204  console.log('span not started :_( ');205  return false;206  }207 208  span.endTime = details.endTime;209  span.properties = details.properties;210  span.details = details.details;211 212  return true;213  }214 215  };216 217  var print_trace_index = function(trace) {218  var parent = document.getElementById('div_traces');219 220  var div = document.createElement('div');221  div.setAttribute('trace_id', trace.id);222  div.textContent = trace.id; 223  div.addEventListener('click', function(e) {224  var trace_id = this.getAttribute('trace_id');225  print_trace(trace_id);226  }, true);227 228  parent.appendChild(div);229  };230 231 232  var pretty_nanos = function(nanos) {233 234  var power = 1000;235  var units = ['ns', 'µs', 'ms'];236  var i = 0;237  for (; nanos > power;) {238  i++;239  nanos /= power;240  }241 242  return nanos.toFixed(1) + units[i];243 244  };245 246  var print_trace = function(traceId) {247 248  var viewer = document.getElementById('viewer');249  viewer.innerHTML = '';250 251  var div_logs = document.getElementById('div_logs');252  div_logs.innerHTML = '';253 254  var trace = traces[traceId];255 256  var timestamp_min = null;257  var timestamp_max = null;258 259  var span2color={};260  var color2span={};261  var spanCounter=0;262 263  for (var spanId in trace.spans) {264  var span = trace.spans[spanId];265 266  if (null === timestamp_min || timestamp_min>span.startTime) {267  timestamp_min = span.startTime;268  }269 270  if (null === timestamp_max || timestamp_max<span.endTime) {271  timestamp_max = span.endTime;272  }273 274  var color = span2color[spanId]275  if (!color) {276  span2color[spanId] = spanCounter;277  color2span[spanCounter] = spanId;278  spanCounter++;279  }280 281  }282 283  var timestamp_range = timestamp_max - timestamp_min;284 285  var span_deep = function(span) {286 287  var MAX_DEEP = 100;288 289  for (var deep = 0; deep<MAX_DEEP; deep++) {290 291  var parentSpanId = span.parentSpanId;292  if (!parentSpanId) {293  return deep;294  }295 296  span = trace.spans[parentSpanId];297  if (!span) {298  return deep;299  }300  }301 302  return undefined;303  };304 305  var logs = [];306  var i=0;307  for (var spanId in trace.spans) {308  var span = trace.spans[spanId];309 310  var span_delay = span.endTime-span.startTime;311 312  span.logs.map(function(log) {logs.push(log); });313 314  var left = (100*(span.startTime-timestamp_min)/timestamp_range).toFixed(2)315 316  var div = document.createElement('div');317  div.setAttribute('span_id', span.spanId);318  div.className = 'span';319  div.style.top = i*18 + 'px';320  div.setAttribute('paralell_index', span_deep(span));321  /*322  if (span_parallell) {323  div.style.top = span_deep(span)*18 + 'px';324  } else {325  div.style.top = i*18 + 'px';326  }*/327  div.style.left = left + '%';328  div.style.width = 100*(span.endTime-span.startTime)/timestamp_range + '%';329  div.addEventListener('mouseover', function(e){330  div_logs.setAttribute('select', span2color[this.getAttribute('span_id')] );331  }, true);332 333  console.log(span);334 335  var content = '(' + pretty_nanos(span_delay) + ') ';336  if (span.logs.length) {337  content += span.logs[0].message;338  }339 340  div.textContent = content;341 342  viewer.appendChild(div);343 344  i++;345  }346 347  // TODO: sort logs by timestamp...348  logs.sort( (a,b) => a.timestamp - b.timestamp );349 350  logs.map(function(log) {351  var div = document.createElement('div');352  div.className = 'log-entry';353  div.setAttribute('level', log.level);354  div.setAttribute('span_id', log.spanId);355  div.setAttribute('select', span2color[log.spanId]);356  div.textContent = (new Date(log.timestamp/1000000))+ 't' +log.level + 't' + log.message;357  div_logs.appendChild(div);358  });359 360  };361 362  var spare_logs = document.getElementById('spare_logs');363 364  var add_log = function(log) {365 366  //V1|LOG.INFO|ns|59bb80e520988c09f76c8e1f|7b35c96c-7405-4705-bba2-417e5f6415dc|78c84606-f966-41f1-8509-fc71c473e0d8|1517069566344381262|Response status: '200 OK'367 368  var parts = log.split('|');369 370  var traceId = parts[4];371 372  var trace = traces[traceId];373  if (!trace) {374  return false;375  }376 377  var spanId = parts[5];378  var span = trace.spans[spanId];379  if (!span) {380  return false;381  }382 383  var level = parts[1].split('.')[1];384  var message = parts[7];385 386  span.logs.push({387  spanId: spanId,388  level: level,389  message: message,390  timestamp: parts[6],391  });392 393  return true;394  };395  396  var input_traces = document.getElementById('input_traces');397  input_traces.addEventListener('paste', function(e) {398  var text = e.clipboardData.getData('text');399  process_text(text);400  }, true);401 402  input_traces.addEventListener('keyup', function(e) {403  if (13 == e.keyCode) {404  process_text(this.value);405  }406  }, true);407 408  var process_text = function(text) {409  var lines = text.split('n');410  lines.map(add_line);411  process_lines();412  };413 414  var process_lines = function() {415  var n = 1;416  while (n) {417  n = process_lines_iterative();418  }419  };420 421  var process_lines_iterative = function() {422 423  var remove = [];424 425  for (var i in lines) {426  var line = lines[i];427 428  var processed = false;429  if (line.startsWith('V1|LOG')) {430  processed = add_log(line);431  } else if (line.startsWith('V1|TRACE')) {432  processed = add_trace(line);433  }434 435  if (processed) {436  remove.push(i);437  }438  }439 440  for (var i=remove.length-1; i>=0; i--) {441  var j = remove[i];442  lines.splice(j, 1);443  }444 445  return remove.length;446  };447 448  </script>449 450 </body>451 </html>
Enlace
El enlace para compartir es: