http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/dcd1bc0e/blur-status/src/main/resources/webapp/js/thrift.js ---------------------------------------------------------------------- diff --git a/blur-status/src/main/resources/webapp/js/thrift.js b/blur-status/src/main/resources/webapp/js/thrift.js new file mode 100644 index 0000000..e8436b9 --- /dev/null +++ b/blur-status/src/main/resources/webapp/js/thrift.js @@ -0,0 +1,775 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +var Thrift = { + Version: '0.9.0', +/* + Description: 'JavaScript bindings for the Apache Thrift RPC system', + License: 'http://www.apache.org/licenses/LICENSE-2.0', + Homepage: 'http://thrift.apache.org', + BugReports: 'https://issues.apache.org/jira/browse/THRIFT', + Maintainer: '[email protected]', +*/ + + Type: { + 'STOP' : 0, + 'VOID' : 1, + 'BOOL' : 2, + 'BYTE' : 3, + 'I08' : 3, + 'DOUBLE' : 4, + 'I16' : 6, + 'I32' : 8, + 'I64' : 10, + 'STRING' : 11, + 'UTF7' : 11, + 'STRUCT' : 12, + 'MAP' : 13, + 'SET' : 14, + 'LIST' : 15, + 'UTF8' : 16, + 'UTF16' : 17 + }, + + MessageType: { + 'CALL' : 1, + 'REPLY' : 2, + 'EXCEPTION' : 3 + }, + + objectLength: function(obj) { + var length = 0; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + length++; + } + } + + return length; + }, + + inherits: function(constructor, superConstructor) { + //Prototypal Inheritance http://javascript.crockford.com/prototypal.html + function F() {} + F.prototype = superConstructor.prototype; + constructor.prototype = new F(); + } +}; + + + +Thrift.TException = function(message) { + this.message = message; +}; +Thrift.inherits(Thrift.TException, Error); +Thrift.TException.prototype.name = 'TException'; + +Thrift.TApplicationExceptionType = { + 'UNKNOWN' : 0, + 'UNKNOWN_METHOD' : 1, + 'INVALID_MESSAGE_TYPE' : 2, + 'WRONG_METHOD_NAME' : 3, + 'BAD_SEQUENCE_ID' : 4, + 'MISSING_RESULT' : 5, + 'INTERNAL_ERROR' : 6, + 'PROTOCOL_ERROR' : 7 +}; + +Thrift.TApplicationException = function(message, code) { + this.message = message; + this.code = (code === null) ? 0 : code; +}; +Thrift.inherits(Thrift.TApplicationException, Thrift.TException); +Thrift.TApplicationException.prototype.name = 'TApplicationException'; + +Thrift.TApplicationException.prototype.read = function(input) { + while (1) { + var ret = input.readFieldBegin(); + + if (ret.ftype == Thrift.Type.STOP) { + break; + } + + var fid = ret.fid; + + switch (fid) { + case 1: + if (ret.ftype == Thrift.Type.STRING) { + ret = input.readString(); + this.message = ret.value; + } else { + ret = input.skip(ret.ftype); + } + break; + case 2: + if (ret.ftype == Thrift.Type.I32) { + ret = input.readI32(); + this.code = ret.value; + } else { + ret = input.skip(ret.ftype); + } + break; + default: + ret = input.skip(ret.ftype); + break; + } + + input.readFieldEnd(); + } + + input.readStructEnd(); +}; + +Thrift.TApplicationException.prototype.write = function(output) { + var xfer = 0; + + output.writeStructBegin('TApplicationException'); + + if (this.message) { + output.writeFieldBegin('message', Thrift.Type.STRING, 1); + output.writeString(this.getMessage()); + output.writeFieldEnd(); + } + + if (this.code) { + output.writeFieldBegin('type', Thrift.Type.I32, 2); + output.writeI32(this.code); + output.writeFieldEnd(); + } + + output.writeFieldStop(); + output.writeStructEnd(); +}; + +Thrift.TApplicationException.prototype.getCode = function() { + return this.code; +}; + +Thrift.TApplicationException.prototype.getMessage = function() { + return this.message; +}; + +/** + *If you do not specify a url then you must handle ajax on your own. + *This is how to use js bindings in a async fashion. + */ +Thrift.Transport = function(url) { + this.url = url; + this.wpos = 0; + this.rpos = 0; + + this.send_buf = ''; + this.recv_buf = ''; +}; + +Thrift.Transport.prototype = { + + //Gets the browser specific XmlHttpRequest Object + getXmlHttpRequestObject: function() { + try { return new XMLHttpRequest(); } catch (e1) { } + try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch (e2) { } + try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch (e3) { } + + throw "Your browser doesn't support the XmlHttpRequest object."; + }, + + flush: function(async) { + //async mode + if (async || this.url === undefined || this.url === '') { + return this.send_buf; + } + + var xreq = this.getXmlHttpRequestObject(); + + if (xreq.overrideMimeType) { + xreq.overrideMimeType('application/json'); + } + + xreq.open('POST', this.url, false); + xreq.send(this.send_buf); + + if (xreq.readyState != 4) { + throw 'encountered an unknown ajax ready state: ' + xreq.readyState; + } + + if (xreq.status != 200) { + throw 'encountered a unknown request status: ' + xreq.status; + } + + this.recv_buf = xreq.responseText; + this.recv_buf_sz = this.recv_buf.length; + this.wpos = this.recv_buf.length; + this.rpos = 0; + }, + + jqRequest: function(client, postData, args, recv_method) { + if (typeof jQuery === 'undefined' || + typeof jQuery.Deferred === 'undefined') { + throw 'Thrift.js requires jQuery 1.5+ to use asynchronous requests'; + } + + var thriftTransport = this; + + var jqXHR = jQuery.ajax({ + url: this.url, + data: postData, + type: 'POST', + cache: false, + dataType: 'text thrift', + converters: { + 'text thrift' : function(responseData) { + thriftTransport.setRecvBuffer(responseData); + var value = recv_method.call(client); + return value; + } + }, + context: client, + success: jQuery.makeArray(args).pop() + }); + + return jqXHR; + }, + + setRecvBuffer: function(buf) { + this.recv_buf = buf; + this.recv_buf_sz = this.recv_buf.length; + this.wpos = this.recv_buf.length; + this.rpos = 0; + }, + + isOpen: function() { + return true; + }, + + open: function() {}, + + close: function() {}, + + read: function(len) { + var avail = this.wpos - this.rpos; + + if (avail === 0) { + return ''; + } + + var give = len; + + if (avail < len) { + give = avail; + } + + var ret = this.read_buf.substr(this.rpos, give); + this.rpos += give; + + //clear buf when complete? + return ret; + }, + + readAll: function() { + return this.recv_buf; + }, + + write: function(buf) { + this.send_buf = buf; + }, + + getSendBuffer: function() { + return this.send_buf; + } + +}; + + + +Thrift.Protocol = function(transport) { + this.transport = transport; +}; + +Thrift.Protocol.Type = {}; +Thrift.Protocol.Type[Thrift.Type.BOOL] = '"tf"'; +Thrift.Protocol.Type[Thrift.Type.BYTE] = '"i8"'; +Thrift.Protocol.Type[Thrift.Type.I16] = '"i16"'; +Thrift.Protocol.Type[Thrift.Type.I32] = '"i32"'; +Thrift.Protocol.Type[Thrift.Type.I64] = '"i64"'; +Thrift.Protocol.Type[Thrift.Type.DOUBLE] = '"dbl"'; +Thrift.Protocol.Type[Thrift.Type.STRUCT] = '"rec"'; +Thrift.Protocol.Type[Thrift.Type.STRING] = '"str"'; +Thrift.Protocol.Type[Thrift.Type.MAP] = '"map"'; +Thrift.Protocol.Type[Thrift.Type.LIST] = '"lst"'; +Thrift.Protocol.Type[Thrift.Type.SET] = '"set"'; + + +Thrift.Protocol.RType = {}; +Thrift.Protocol.RType.tf = Thrift.Type.BOOL; +Thrift.Protocol.RType.i8 = Thrift.Type.BYTE; +Thrift.Protocol.RType.i16 = Thrift.Type.I16; +Thrift.Protocol.RType.i32 = Thrift.Type.I32; +Thrift.Protocol.RType.i64 = Thrift.Type.I64; +Thrift.Protocol.RType.dbl = Thrift.Type.DOUBLE; +Thrift.Protocol.RType.rec = Thrift.Type.STRUCT; +Thrift.Protocol.RType.str = Thrift.Type.STRING; +Thrift.Protocol.RType.map = Thrift.Type.MAP; +Thrift.Protocol.RType.lst = Thrift.Type.LIST; +Thrift.Protocol.RType.set = Thrift.Type.SET; + +Thrift.Protocol.Version = 1; + +Thrift.Protocol.prototype = { + + getTransport: function() { + return this.transport; + }, + + //Write functions + writeMessageBegin: function(name, messageType, seqid) { + this.tstack = []; + this.tpos = []; + + this.tstack.push([Thrift.Protocol.Version, '"' + + name + '"', messageType, seqid]); + }, + + writeMessageEnd: function() { + var obj = this.tstack.pop(); + + this.wobj = this.tstack.pop(); + this.wobj.push(obj); + + this.wbuf = '[' + this.wobj.join(',') + ']'; + + this.transport.write(this.wbuf); + }, + + + writeStructBegin: function(name) { + this.tpos.push(this.tstack.length); + this.tstack.push({}); + }, + + writeStructEnd: function() { + + var p = this.tpos.pop(); + var struct = this.tstack[p]; + var str = '{'; + var first = true; + for (var key in struct) { + if (first) { + first = false; + } else { + str += ','; + } + + str += key + ':' + struct[key]; + } + + str += '}'; + this.tstack[p] = str; + }, + + writeFieldBegin: function(name, fieldType, fieldId) { + this.tpos.push(this.tstack.length); + this.tstack.push({ 'fieldId': '"' + + fieldId + '"', 'fieldType': Thrift.Protocol.Type[fieldType] + }); + + }, + + writeFieldEnd: function() { + var value = this.tstack.pop(); + var fieldInfo = this.tstack.pop(); + + this.tstack[this.tstack.length - 1][fieldInfo.fieldId] = '{' + + fieldInfo.fieldType + ':' + value + '}'; + this.tpos.pop(); + }, + + writeFieldStop: function() { + //na + }, + + writeMapBegin: function(keyType, valType, size) { + //size is invalid, we'll set it on end. + this.tpos.push(this.tstack.length); + this.tstack.push([Thrift.Protocol.Type[keyType], + Thrift.Protocol.Type[valType], 0]); + }, + + writeMapEnd: function() { + var p = this.tpos.pop(); + + if (p == this.tstack.length) { + return; + } + + if ((this.tstack.length - p - 1) % 2 !== 0) { + this.tstack.push(''); + } + + var size = (this.tstack.length - p - 1) / 2; + + this.tstack[p][this.tstack[p].length - 1] = size; + + var map = '}'; + var first = true; + while (this.tstack.length > p + 1) { + var v = this.tstack.pop(); + var k = this.tstack.pop(); + if (first) { + first = false; + } else { + map = ',' + map; + } + + if (! isNaN(k)) { k = '"' + k + '"'; } //json "keys" need to be strings + map = k + ':' + v + map; + } + map = '{' + map; + + this.tstack[p].push(map); + this.tstack[p] = '[' + this.tstack[p].join(',') + ']'; + }, + + writeListBegin: function(elemType, size) { + this.tpos.push(this.tstack.length); + this.tstack.push([Thrift.Protocol.Type[elemType], size]); + }, + + writeListEnd: function() { + var p = this.tpos.pop(); + + while (this.tstack.length > p + 1) { + var tmpVal = this.tstack[p + 1]; + this.tstack.splice(p + 1, 1); + this.tstack[p].push(tmpVal); + } + + this.tstack[p] = '[' + this.tstack[p].join(',') + ']'; + }, + + writeSetBegin: function(elemType, size) { + this.tpos.push(this.tstack.length); + this.tstack.push([Thrift.Protocol.Type[elemType], size]); + }, + + writeSetEnd: function() { + var p = this.tpos.pop(); + + while (this.tstack.length > p + 1) { + var tmpVal = this.tstack[p + 1]; + this.tstack.splice(p + 1, 1); + this.tstack[p].push(tmpVal); + } + + this.tstack[p] = '[' + this.tstack[p].join(',') + ']'; + }, + + writeBool: function(value) { + this.tstack.push(value ? 1 : 0); + }, + + writeByte: function(i8) { + this.tstack.push(i8); + }, + + writeI16: function(i16) { + this.tstack.push(i16); + }, + + writeI32: function(i32) { + this.tstack.push(i32); + }, + + writeI64: function(i64) { + this.tstack.push(i64); + }, + + writeDouble: function(dbl) { + this.tstack.push(dbl); + }, + + writeString: function(str) { + // We do not encode uri components for wire transfer: + if (str === null) { + this.tstack.push(null); + } else { + // concat may be slower than building a byte buffer + var escapedString = ''; + for (var i = 0; i < str.length; i++) { + var ch = str.charAt(i); // a single double quote: " + if (ch === '\"') { + escapedString += '\\\"'; // write out as: \" + } else if (ch === '\\') { // a single backslash: \ + escapedString += '\\\\'; // write out as: \\ + /* Currently escaped forward slashes break TJSONProtocol. + * As it stands, we can simply pass forward slashes into + * our strings across the wire without being escaped. + * I think this is the protocol's bug, not thrift.js + * } else if(ch === '/') { // a single forward slash: / + * escapedString += '\\/'; // write out as \/ + * } + */ + } else if (ch === '\b') { // a single backspace: invisible + escapedString += '\\b'; // write out as: \b" + } else if (ch === '\f') { // a single formfeed: invisible + escapedString += '\\f'; // write out as: \f" + } else if (ch === '\n') { // a single newline: invisible + escapedString += '\\n'; // write out as: \n" + } else if (ch === '\r') { // a single return: invisible + escapedString += '\\r'; // write out as: \r" + } else if (ch === '\t') { // a single tab: invisible + escapedString += '\\t'; // write out as: \t" + } else { + escapedString += ch; // Else it need not be escaped + } + } + this.tstack.push('"' + escapedString + '"'); + } + }, + + writeBinary: function(str) { + this.writeString(str); + }, + + + + // Reading functions + readMessageBegin: function(name, messageType, seqid) { + this.rstack = []; + this.rpos = []; + + if (typeof jQuery !== 'undefined') { + this.robj = jQuery.parseJSON(this.transport.readAll()); + } else { + this.robj = eval(this.transport.readAll()); + } + + var r = {}; + var version = this.robj.shift(); + + if (version != Thrift.Protocol.Version) { + throw 'Wrong thrift protocol version: ' + version; + } + + r.fname = this.robj.shift(); + r.mtype = this.robj.shift(); + r.rseqid = this.robj.shift(); + + + //get to the main obj + this.rstack.push(this.robj.shift()); + + return r; + }, + + readMessageEnd: function() { + }, + + readStructBegin: function(name) { + var r = {}; + r.fname = ''; + + //incase this is an array of structs + if (this.rstack[this.rstack.length - 1] instanceof Array) { + this.rstack.push(this.rstack[this.rstack.length - 1].shift()); + } + + return r; + }, + + readStructEnd: function() { + if (this.rstack[this.rstack.length - 2] instanceof Array) { + this.rstack.pop(); + } + }, + + readFieldBegin: function() { + var r = {}; + + var fid = -1; + var ftype = Thrift.Type.STOP; + + //get a fieldId + for (var f in (this.rstack[this.rstack.length - 1])) { + if (f === null) { + continue; + } + + fid = parseInt(f, 10); + this.rpos.push(this.rstack.length); + + var field = this.rstack[this.rstack.length - 1][fid]; + + //remove so we don't see it again + delete this.rstack[this.rstack.length - 1][fid]; + + this.rstack.push(field); + + break; + } + + if (fid != -1) { + + //should only be 1 of these but this is the only + //way to match a key + for (var i in (this.rstack[this.rstack.length - 1])) { + if (Thrift.Protocol.RType[i] === null) { + continue; + } + + ftype = Thrift.Protocol.RType[i]; + this.rstack[this.rstack.length - 1] = + this.rstack[this.rstack.length - 1][i]; + } + } + + r.fname = ''; + r.ftype = ftype; + r.fid = fid; + + return r; + }, + + readFieldEnd: function() { + var pos = this.rpos.pop(); + + //get back to the right place in the stack + while (this.rstack.length > pos) { + this.rstack.pop(); + } + + }, + + readMapBegin: function(keyType, valType, size) { + var map = this.rstack.pop(); + + var r = {}; + r.ktype = Thrift.Protocol.RType[map.shift()]; + r.vtype = Thrift.Protocol.RType[map.shift()]; + r.size = map.shift(); + + + this.rpos.push(this.rstack.length); + this.rstack.push(map.shift()); + + return r; + }, + + readMapEnd: function() { + this.readFieldEnd(); + }, + + readListBegin: function(elemType, size) { + var list = this.rstack[this.rstack.length - 1]; + + var r = {}; + r.etype = Thrift.Protocol.RType[list.shift()]; + r.size = list.shift(); + + this.rpos.push(this.rstack.length); + this.rstack.push(list); + + return r; + }, + + readListEnd: function() { + this.readFieldEnd(); + }, + + readSetBegin: function(elemType, size) { + return this.readListBegin(elemType, size); + }, + + readSetEnd: function() { + return this.readListEnd(); + }, + + readBool: function() { + var r = this.readI32(); + + if (r !== null && r.value == '1') { + r.value = true; + } else { + r.value = false; + } + + return r; + }, + + readByte: function() { + return this.readI32(); + }, + + readI16: function() { + return this.readI32(); + }, + + readI32: function(f) { + if (f === undefined) { + f = this.rstack[this.rstack.length - 1]; + } + + var r = {}; + + if (f instanceof Array) { + if (f.length === 0) { + r.value = undefined; + } else { + r.value = f.shift(); + } + } else if (f instanceof Object) { + for (var i in f) { + if (i === null) { + continue; + } + this.rstack.push(f[i]); + delete f[i]; + + r.value = i; + break; + } + } else { + r.value = f; + this.rstack.pop(); + } + + return r; + }, + + readI64: function() { + return this.readI32(); + }, + + readDouble: function() { + return this.readI32(); + }, + + readString: function() { + var r = this.readI32(); + return r; + }, + + readBinary: function() { + return this.readString(); + }, + + + //Method to arbitrarily skip over data. + skip: function(type) { + throw 'skip not supported yet'; + } +};
http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/dcd1bc0e/blur-status/src/main/resources/webapp/metrics.html ---------------------------------------------------------------------- diff --git a/blur-status/src/main/resources/webapp/metrics.html b/blur-status/src/main/resources/webapp/metrics.html new file mode 100644 index 0000000..f06cec4 --- /dev/null +++ b/blur-status/src/main/resources/webapp/metrics.html @@ -0,0 +1,110 @@ +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<html> +<head> +<title>Blur - Metrics</title> +<meta charset="utf-8"> +<link href="css/bootstrap.min.css" rel="stylesheet"> +<link href="css/bs-docs.css" rel="stylesheet" media="screen"> +</head> + +<script src="js/jquery-1.9.1.min.js"></script> +<script src="js/thrift.js"></script> +<script src="js/Blur.js"></script> +<script src="js/Blur_types.js"></script> +<script> +function displayPage() { + var transport = new Thrift.Transport("/blur"); + var protocol = new Thrift.Protocol(transport); + var client = new BlurClient(protocol); + + try { + var metrics = client.metrics(null); + var body = $("#page_body"); + var keys = Object.keys(metrics).sort(); + var s = ""; + s += "<h2>Metrics</h2>"; + s += "<table border=1 class=\"table-bordered table-striped table-condensed\"><tr><th>Name</th><th>Value</th></tr>"; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + var metric = metrics[key]; + s += "<tr><td>"+key+"</td><td>"; + s += "<table border=1 class=\"table-bordered table-striped table-condensed\">" + writeValueMap(metrics,key,metric.strMap,false) + "</table>"; + s += "<table border=1 class=\"table-bordered table-striped table-condensed\">" + writeValueMap(metrics,key,metric.longMap,false) + "</table>"; + s += "<table border=1 class=\"table-bordered table-striped table-condensed\">" + writeValueMap(metrics,key,metric.doubleMap,true) + "</table>"; + s += "</td></tr>"; + } + s += "</table>"; + body.html(s); + } catch(ouch){ + alert (ouch); + } + setTimeout(displayPage,3000); +} +function writeValueMap(metrics,key,map,formatNumber) { + if (map) { + var s = "<tr>"; + var keys = Object.keys(map).sort(); + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + s += "<th>"+key+"</th>"; + } + s += "</tr><tr>"; + for (var i = 0; i < keys.length; i++) { + var key = keys[i]; + if (formatNumber) { + s += "<td>"+map[key].toPrecision(6)+"</td>"; + } else { + s += "<td>"+map[key]+"</td>"; + } + } + s += "</tr>"; + return s; + } + return ""; +} +$(window).bind("load", displayPage); +</script> +<body> + <div class="navbar navbar-inverse navbar-fixed-top"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="http://incubator.apache.org/blur">Apache Blur (Incubator)</a> + </div> + <div class="collapse navbar-collapse"> + <ul class="nav navbar-nav"> + <li><a href="index.html">Home</a></li> + <li><a href="config.html">Configuration</a></li> + <li class="active"><a href="metrics.html">Metrics</a></li> + <li><a href="traces.html">Traces</a></li> + </ul> + </div> + </div> + </div> + <table class="table-bordered table-condensed"> + <tr><td id="page_body"></td></tr> + </table> + +</body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/dcd1bc0e/blur-status/src/main/resources/webapp/traces.html ---------------------------------------------------------------------- diff --git a/blur-status/src/main/resources/webapp/traces.html b/blur-status/src/main/resources/webapp/traces.html new file mode 100644 index 0000000..fc8394a --- /dev/null +++ b/blur-status/src/main/resources/webapp/traces.html @@ -0,0 +1,302 @@ +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> +<html> +<head> +<title>Blur - Traces</title> +<meta charset="utf-8"> +<link href="css/bootstrap.min.css" rel="stylesheet"> +<link href="css/bs-docs.css" rel="stylesheet" media="screen"> +</head> + +<script src="js/jquery-1.9.1.min.js"></script> +<script src="js/thrift.js"></script> +<script src="js/Blur.js"></script> +<script src="js/Blur_types.js"></script> +<script> +var colors = ["FF0600","FF0C00","FF1200","FF1800","FF1E00","FF2400","FF2A00","FF3000","FF3600","FF3C00","FF4200","FF4800","FF4E00","FF5400","FF5A00","FF6000","FF6600","FF6C00","FF7200","FF7800","FF7E00","FF8400","FF8A00","FF9000","FF9600","FF9C00","FFA200","FFA800","FFAE00","FFB400","FFBA00","FFC000","FFC600","FFCC00","FFD200","FFD800","FFDE00","FFE400","FFEA00","FFF000","FFF600","FFFC00","FFFF00","F9FF00","F3FF00","EDFF00","E7FF00","E1FF00","DBFF00","D5FF00","CFFF00","C9FF00","C3FF00","BDFF00","B7FF00","B1FF00","ABFF00","A5FF00","9FFF00","99FF00","93FF00","8DFF00","87FF00","81FF00","7BFF00","75FF00","6FFF00","69FF00","63FF00","5DFF00","57FF00","51FF00","4BFF00","45FF00","3FFF00","39FF00","33FF00","2DFF00","27FF00","21FF00","1BFF00","15FF00","0FFF00","09FF00","03FF00","00FF00"]; +var transport = new Thrift.Transport("/blur"); +var protocol = new Thrift.Protocol(transport); +var client = new BlurClient(protocol); +function displayPage() { + try { + var traceList = client.traceList(); + var body = $("#page_body"); + var lst = traceList.sort(); + var s = "<table border=1 class=\"table-bordered table-striped table-condensed\"><tr><th>Trace Id</th><th>Time</th></tr>"; + for (var i = 0; i < lst.length; i++) { + var traceId = lst[i]; + s += "<tr><td nowrap=1><a title=\""+traceId+"\" id=\"traceid_"+traceId+"\" href=\"#\">"+shortenString(traceId)+"</a><td nowrap=1>"+getTraceTime(traceId,client)+"</td></td></tr>"; + } + body.html(s + "</table>"); + for (var i = 0; i < lst.length; i++) { + var traceId = lst[i]; + $("#traceid_"+traceId).click(function(event){ + displayRequestIds(event.target.id); + return false; + }); + } + + } catch(ouch){ + if (window.console) console.log(ouch); + } + setTimeout(displayPage,5000); +} +function shortenString(traceId) { +return traceId.substring(0,6) + "..." + traceId.substring(traceId.length - 6,traceId.length); +} +function getTraceTime(traceId,client){ + var lst = client.traceRequestList(traceId); + if (lst.length == 0) { + return "unknown"; + } + var info = getRequestInfo(client,traceId,traceId); + return formatTimeNoNano(info.created); +} +function displayRequestIds(traceIdAttr) { + var parts = traceIdAttr.split("_"); + traceId = parts[1]; + $("#trace_contents").html("No Request Selected"); + try { + var traceRequestList = client.traceRequestList(traceId); + var rbody = $("#request_id_body"); + var lst = traceRequestList.sort(); + var s = "<h5>" + traceId + "<h5><table border=1 class=\"table-bordered table-striped table-condensed\"><tr><th nowrap=1>Request Id</th><th nowrap=1>Time Offset (ms)</th><th nowrap=1>Total Time (ms)</th></tr>"; + var requestArray = new Array(); + for (var i = 0; i < lst.length; i++) { + var info = getRequestInfo(client,traceId,lst[i]); + info.requestId = lst[i]; + requestArray.push(info); + } + requestArray.sort(function(a,b){ + if (a.created < b.created) { + return -1; + } else if (a.created > b.created) { + return 1; + } + return 0; + }); + var lastTime = requestArray[0].created; + for (var i = 0; i < requestArray.length; i++) { + var id = "requestid_"+traceId+"_"+requestArray[i].requestId; + if (traceId == requestArray[i].requestId) { + s += "<tr><td nowrap=1><a id=\""+id+"\" href=\"#\">"+requestArray[i].nodeName+" (Root)</a></td>"; + } else { + s += "<tr><td nowrap=1><a id=\""+id+"\" href=\"#\">"+requestArray[i].nodeName+" (Request "+i+")</a></td>"; + } + var diff = requestArray[i].created - lastTime; + s += "<td>"+diff / 1000000+"</td><td>" + requestArray[i].totalTime / 1000000 + "</td></tr>"; + lastTime = requestArray[i].created; + } + rbody.html(s + "</table>"); + for (var i = 0; i < lst.length; i++) { + var requestId = lst[i]; + $("#requestid_"+traceId+"_"+requestId).click( + function(event){ + displayTrace(event.target.id); + return false; + }); + } + } catch(ouch){ + if (window.console) console.log(ouch); + } +} +function getRequestInfo(client,traceId,requestId) { + var json = client.traceRequestFetch(traceId,requestId); + var traceRequest = $.parseJSON(json); + var result = {}; + result.created = traceRequest.created; + result.totalTime = traceRequest.totalTime; + result.nodeName = traceRequest.nodeName; + return result; +} +function displayTrace(traceIdPlusRequestId) { + var parts = traceIdPlusRequestId.split("_"); + var traceId = parts[1]; + var requestId = parts[2]; + + var requestIds = client.traceRequestList(traceId); + + var json = client.traceRequestFetch(traceId,requestId); + var traceRequest = $.parseJSON(json); + var ids = new Array(); + var header = "<h5>" + traceId + "<h5><h6>"+requestId + "</h6>"; + header += "<table border=1 class=\"table-bordered table-striped table-condensed\">"; + header += "<tr><th>Node</th><th>Pid</th><th>Main Thread</th><th>Create Time</th><th>Total Time</th></tr>"; + header += "<tr><td>" + traceRequest.nodeName + "</td>"; + header += "<td>" + traceRequest.pid + "</td>"; + header += "<td>" + traceRequest.thread + "</td>"; + header += "<td>" + formatTime(traceRequest.created) + "</td>"; + header += "<td>" + traceRequest.totalTime / 1000000 + " ms</td></tr>"; + header += "</table><br/>"; + var s = gatherTraceInfo(traceRequest,requestIds,traceId,ids,traceRequest.totalTime,true); + $("#trace_contents").html(header + s); + for (var i = 0; i < ids.length; i++) { + $("#"+ids[i]).click( + function(event){ + displayTrace(event.target.id); + return false; + }); + } +} +function formatTimeNoNano(t) { + var d = new Date(0); + d.setUTCMilliseconds(t / 1000000); + var date = d.getDate(); + var month = d.getMonth(); + month++; + var year = d.getFullYear(); + var hours = d.getHours(); + var minutes = d.getMinutes(); + var seconds = d.getSeconds(); + var millis = d.getMilliseconds(); + return year + "-" + bufDigits(month,2) + "-" + bufDigits(date,2) + " " + bufDigits(hours,2) + ":" + bufDigits(minutes,2) + ":" + bufDigits(seconds,2) + "." + bufDigits(millis,3); +} +function formatTime(t) { + var nanos = t % 1000000; + var d = new Date(0); + d.setUTCMilliseconds(t / 1000000); + var date = d.getDate(); + var month = d.getMonth(); + month++; + var year = d.getFullYear(); + var hours = d.getHours(); + var minutes = d.getMinutes(); + var seconds = d.getSeconds(); + var millis = d.getMilliseconds(); + return year + "-" + bufDigits(month,2) + "-" + bufDigits(date,2) + " " + bufDigits(hours,2) + ":" + bufDigits(minutes,2) + ":" + bufDigits(seconds,2) + "." + bufDigits(millis,3) + "."+bufDigits(nanos,6); +} +function bufDigits(num,len) { + num = num + ""; + while (num.length < len) { + num = "0" + num; + } + return num; +} +function gatherTraceInfo(collector,requestIds,traceId,ids,totalRequestTime,parent) { + var traces = collector.traces; + var s = "<table border=1 class=\"table-bordered table-striped table-condensed\">"; + s += "<tr><th>Trace Name</th><th>Thread</th><th>Scope</th><th>Time (ms)</th></tr>"; + traces.sort(function(a,b){ + if (a.id < b.id) { + return -1; + } else if (a.id > b.id) { + return 1; + } + return 0; + }) + + for (var i = 0; i < traces.length; i++) { + var trace = traces[i]; + + var colName = "<td valign=top nowrap=1>"; + var colValue = "<td valign=top nowrap=1>"; + if (trace.collector) { + var requestIdInAnotherProcess = getNewRequestId(trace.collector,requestIds) + if (requestIdInAnotherProcess) { + var id = "requestid_"+traceId+"_"+requestIdInAnotherProcess + "_2"; + ids.push(id); + colName += "<a href=\"#\" id=\""+id+"\">" + trace.id + " - " + trace.name + "</a>"; + colValue += gatherTraceInfo(trace.collector,requestIds,traceId,ids,totalRequestTime,false); + } else { + colName += trace.id + " - " + trace.name + "</td>"; + colValue += gatherTraceInfo(trace.collector,requestIds,traceId,ids,totalRequestTime,false); + } + } else { + var p = (trace.took / totalRequestTime * 100); + colName += trace.id + " - " + trace.name; + if (i!=0 || !parent) { + colValue = "<td valign=top nowrap=1 bgcolor=\"#"+colors[100-Math.round(p)] +"\">" + (trace.took / 1000000.0).toPrecision(6) + " (" + p.toPrecision(3) + "% of Request)"; + } else { + colValue += (trace.took / 1000000.0).toPrecision(6); + } + } + s += "<tr>"; + s += colName + "</td>"; + s += "<td valign=top nowrap=1>"+trace.thread+"</td>"; + s += "<td valign=top nowrap=1>"+trace.scope+"</td>"; + s += colValue + "</td>"; + s += getParams(trace); + } + s += "</table>"; + return s; +} +function getParams(trace) { + var s = ""; + if (trace.parameters) { + var parameters = trace.parameters; + if (parameters.length > 0) { + s += "</tr><tr><td valign=top align=right><b>Parameters:</b></td><td valign=top colspan=3>" + for (var i = 0; i < parameters.length; i++) { + var parameter = parameters[i]; + var keys = Object.keys(parameter); + for (var t = 0; t < keys.length; t++) { + var key = keys[t]; + var value = parameter[key]; + s += key + "=" + value + "<br/>"; + } + } + } + s += "</td>"; + } + s += "</tr>"; + return s; +} +function getNewRequestId(collector,requestIds) { + if ($.inArray(collector.id.requestId, requestIds) != -1) { + return collector.id.requestId; + } + return null; +} +$(window).bind("load", displayPage); +</script> +<body> + <div class="navbar navbar-inverse navbar-fixed-top"> + <div class="container"> + <div class="navbar-header"> + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + <span class="icon-bar"></span> + </button> + <a class="navbar-brand" href="http://incubator.apache.org/blur">Apache Blur (Incubator)</a> + </div> + <div class="collapse navbar-collapse"> + <ul class="nav navbar-nav"> + <li><a href="index.html">Home</a></li> + <li><a href="config.html">Configuration</a></li> + <li><a href="metrics.html">Metrics</a></li> + <li class="active"><a href="traces.html">Traces</a></li> + </ul> + </div> + </div> + </div> + <table class="table-bordered table-condensed"> + <tbody> + <tr><td colspan=3 valign="top"><h1>System Traces</h1></td></tr> + <tr> + <td valign="top"><h2>Traces</h2><div id="page_body"></div></td> + <td valign="top"><h2>Requests</h2><div id="request_id_body"></div></td> + <td valign="top"><h2>Trace Contents</h2><div id="trace_contents"></div></td> + </tr> + </tbody> + </table> + + +</body> +</html> http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/dcd1bc0e/blur-status/src/main/webapp/WEB-INF/web.xml ---------------------------------------------------------------------- diff --git a/blur-status/src/main/webapp/WEB-INF/web.xml b/blur-status/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 0740e28..0000000 --- a/blur-status/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,25 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. ---> -<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" - version="2.5"> - - <display-name>Blur YARN</display-name> -</web-app> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/dcd1bc0e/blur-status/src/main/webapp/config.html ---------------------------------------------------------------------- diff --git a/blur-status/src/main/webapp/config.html b/blur-status/src/main/webapp/config.html deleted file mode 100644 index 5e20675..0000000 --- a/blur-status/src/main/webapp/config.html +++ /dev/null @@ -1,81 +0,0 @@ -<!-- -Licensed to the Apache Software Foundation (ASF) under one -or more contributor license agreements. See the NOTICE file -distributed with this work for additional information -regarding copyright ownership. The ASF licenses this file -to you under the Apache License, Version 2.0 (the -"License"); you may not use this file except in compliance -with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, -software distributed under the License is distributed on an -"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, either express or implied. See the License for the -specific language governing permissions and limitations -under the License. ---> -<html> -<head> -<title>Blur - Config</title> -<meta charset="utf-8"> -<link href="css/bootstrap.min.css" rel="stylesheet"> -<link href="css/bs-docs.css" rel="stylesheet" media="screen"> -</head> - -<script src="js/jquery-1.9.1.min.js"></script> -<script src="js/thrift.js"></script> -<script src="js/Blur.js"></script> -<script src="js/Blur_types.js"></script> -<script> -function displayPage() { - var transport = new Thrift.Transport("/blur"); - var protocol = new Thrift.Protocol(transport); - var client = new BlurClient(protocol); - - try { - var config = client.configuration(); - var body = $("#page_body"); - var keys = Object.keys(config).sort(); - body.append("<h2>Configuration</h2>"); - var s = "<table border=1 class=\"table-bordered table-striped table-condensed\"><tr><th>Name</th><th>Value</th></tr>"; - for (var i = 0; i < keys.length; i++) { - var key = keys[i]; - s += "<tr><td>"+key+"</td><td>"+config[key]+"</td></tr>"; - } - body.append(s + "</table>"); - } catch(ouch){ -alert (ouch); - } -} -$(window).bind("load", displayPage); -</script> -<body> - <div class="navbar navbar-inverse navbar-fixed-top"> - <div class="container"> - <div class="navbar-header"> - <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - <span class="icon-bar"></span> - </button> - <a class="navbar-brand" href="http://incubator.apache.org/blur">Apache Blur (Incubator)</a> - </div> - <div class="collapse navbar-collapse"> - <ul class="nav navbar-nav"> - <li><a href="index.html">Home</a></li> - <li class="active"><a href="config.html">Configuration</a></li> - <li><a href="metrics.html">Metrics</a></li> - <li><a href="traces.html">Traces</a></li> - </ul> - </div> - </div> - </div> - <table class="table-bordered table-condensed"> - <tr><td id="page_body"></td></tr> - </table> - - -</body> -</html>
