org.apache.zookeeper.graph.resources.loggraph.server.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of zookeeper-contrib-loggraph Show documentation
Show all versions of zookeeper-contrib-loggraph Show documentation
LogGraph is an application for viewing and filtering zookeeper logs. It can handle transaction logs and message logs.
/**
* 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.
*/
LogGraph.ServerGraph = function(asyncq, canvas, starttime, endtime, filter) {
this.starttime = starttime;
this.endtime = endtime;
this.millis = endtime - starttime;
this.nextserverid = 0;
this.serveroffset = 100;
this.filter = filter;
this.pixels_per_tick = 20;
this.ticker = new LogGraph.ticker();
var paper = Raphael(canvas, 1, 1);
var self = this;
this.timescale = new LogGraph.timescale(starttime, endtime);
this.objects = new Array();
this.add = function(obj) {
this.objects.push(obj);
}
this.tick_to_x = function (timestamp) {
var x = timestamp * this.pixels_per_tick;
return x;
};
this._drawTime = function(paper, x, time) {
var p = paper.path("M" + x + " 0 L" + x + " " + paper.height);
var t = paper.text(x, 10, dateFormat(time, "h:MM:ss,l"));
t.hide();
p.mouseover(function(evt) {
t.show();
p.attr({stroke: "red"});
});
p.mouseout(function(evt) {
t.hide();
p.attr({stroke: "lightgray"});
});
return p;
};
this.draw = function(paper) {
var grid = paper.set();
for (var i = 0; i < paper.height; i += 20) {
grid.push(paper.path("M0 " + i + " L" + paper.width + " " + i));
}
var lasttick = this.starttime;
var scale = 500; // 500 ms
var y = 0;
for (var t = 0, len = this.ticker.ticks.length; t < len; t++) {
var basex = t * this.pixels_per_tick;
var thistick = this.ticker.ticks[t];
var nexttick = t + 1 == this.ticker.ticks.length ? this.endtime : this.ticker.ticks[t+1];
if (nexttick == thistick) {
continue;
}
var time = thistick - lasttick;
var first = scale - (lasttick % scale);
/* for (var i = 0; (first+scale*i) < time; i++) {
var toffset = first+scale*i;
var x = basex + LogGraph._pixels_per_tick * toffset/time;
grid.push(this._drawTime(paper, x, lasttick + toffset, grid));
}*/
//grid.push(paper.path("M" + i + " 0 L" + i + " " + paper.height));
lasttick = thistick;
}
grid.attr({stroke: "lightgray"});
this.timescale.draw(paper);
for (o in this.objects) {
this.objects[o].draw(paper);
}
};
var processdata = function(data) {
var servermap = {};
var servers = data.servers;
var count = 0;
for (s in servers) {
var server = new LogGraph.ServerGraph.server(self, "Server " + servers[s]);
servermap[servers[s]] = server;
self.add(server);
count++;
}
var messages = {};
var events = data.events;
for (var i in events) {
var e = events[i];
var t = e.time;
if (e.type == "stateChange") {
servermap[e.server].addState(e.state, self.ticker.tick(e.time));
}
if (e.type == "postmessage") {
src = servermap[e.src];
dst = servermap[e.dst];
var key = "key:s" + e.src + ",d" + e.dst + ",z" + e.zxid;
var m = new LogGraph.ServerGraph.message(self, src, self.ticker.tick(e.time), dst, e.zxid);
messages[key] = m;
}
if (e.type == "delivermessage") {
var key = "key:s" + e.src + ",d" + e.dst + ",z" + e.zxid;
var m = messages[key];
if (m) {
m.dsttime = self.ticker.tick(e.time);
m.name = "Propose";
self.add(m);
delete messages[key];
}
}
if (e.type == "exception") {
servermap[e.server].addException(self.ticker.tick(e.time), e.text, e.time);
}
count++;
}
for (var i in messages) {
var m = messages[i];
m.markIncomplete();
self.add(m);
count++;
}
if (count != 0) {
paper.setSize(self.tick_to_x(self.ticker.current()), 1000);
var line = paper.path("M0 0 L0 1000");
line.attr({"stroke": "red", "stroke-dasharray": "- "});
var base = canvas.offsetLeft;// + ((canvas.offsetWidth - paper.width)/2);
canvas.onmousemove = function (evt) {
var x = evt.screenX - base;
line.attr({"path": "M" + x + " 0 L"+ x +" 1000"});
};
self.draw(paper);
return true;
} else {
return false;
}
};
var uri = "/data?start=" + self.starttime + "&end=" + self.endtime + "&filter=" + filter;
LogGraph.loadData(asyncq, uri, processdata);
};
LogGraph.ServerGraph.server = function (graph, name) {
this.graph = graph;
this.serverid = graph.nextserverid++;
this.name = name;
this.y = (this.serverid * 300 + graph.serveroffset);
this.states = new Array();
this.exception = new Array();
this.addState = function(state, time) {
this.states.push([state, time]);
}
this.addException = function(tick, exception, time) {
this.exception.push(new LogGraph.ServerGraph.exception(this.graph, tick, exception, time));
}
this.draw = function(paper) {
var st = paper.set();
st.push(paper.path("M0 " + this.y + " L" + paper.width + " " + this.y));
st.push(paper.text(20, this.y - 10, this.name));
st.attr({stroke: "gray"});
var numstates = this.states.length;
for (s = 0; s < numstates; s++) {
var style = {};
switch (this.states[s][0]) {
case "INIT": style = {stroke: "yellow", "stroke-width":3}; break;
case "FOLLOWING": style = {stroke: "lightgreen", "stroke-width":7}; break;
case "LEADING": style = {stroke: "green", "stroke-width":10}; break;
case "LOOKING": style = {stroke: "orange", "stroke-width":5}; break;
}
var startx = this.graph.tick_to_x(this.states[s][1]);
var endx = s + 1 < numstates ? this.graph.tick_to_x(this.states[(s+1)][1]) : paper.width;
var p = paper.path("M" + startx + " " + this.y + " L" + endx + " " + this.y);
p.attr(style);
}
for (e in this.exception) {
this.exception[e].draw(paper, this);
}
}
};
LogGraph.ServerGraph.message = function(graph, src, srctime, dst, zxid) {
this.graph = graph;
this.src = src;
this.srctime = srctime;
this.dst = dst;
this.dsttime = 0; //dsttime;
this.name = "Unknown";
this.zxid = zxid;
this.moreinfo = "No extra information";
this.incomplete = false;
this.markIncomplete = function() {
this.incomplete = true;
this.dsttime = this.srctime;
}
this.draw = function(paper) {
var srcx = this.graph.tick_to_x(this.srctime);
var dstx = this.graph.tick_to_x(this.dsttime);
var arrow = paper.set();
var p = paper.path("M" + srcx + " " + this.src.y + " L" + dstx + " " + this.dst.y);
arrow.push(p);
var tx = (srcx + dstx)/2;
var ty = (this.src.y + this.dst.y)/2;
var t = paper.text(tx, ty, this.name);
var gradiant = (this.dst.y - this.src.y)/(dstx - srcx);
var angle = Math.atan(gradiant) * 57.2958;
t.rotate(angle, true);
var arrowl = paper.path("M" + dstx + " " + this.dst.y + " L" + (dstx - 10) +" " + this.dst.y);
arrowl.rotate(angle + 20, dstx, this.dst.y);
arrow.push(arrowl);
var arrowr = paper.path("M" + dstx + " " + this.dst.y + " L" + (dstx - 10) +" " + this.dst.y);
arrowr.rotate(angle - 20, dstx, this.dst.y);
arrow.push(arrowr);
arrow.attr({"stroke-width": 2, stroke: "gray"});
if (this.incomplete) {
arrow.attr({"stroke-dasharray": "- .", stroke: "pink", "stroke-width": 2});
}
arrow.mouseover(function(evt) {
t.attr({"font-size": 20});
arrow.attr({stroke: "red", "stroke-width": 3});
});
arrow.mouseout(function(evt) {
t.attr({"font-size": 10});
if (this.incomplete) {
arrow.attr({stroke: "pink", "stroke-width": 2});
} else {
arrow.attr({stroke: "gray", "stroke-width": 2});
}
});
arrow.click(function(evt) {
var popup = document.createElement("div");
popup.className = "popUp";
popup.innerHTML = "zxid: " + parseInt(this.zxid).toString(16);
popup.style.top = evt.clientY;
popup.style.left = evt.clientX;
document.body.appendChild(popup);
popup.onclick = function(evt) {
document.body.removeChild(popup);
};
});
}
};
LogGraph.ServerGraph.exception = function(graph, tick, exceptiontext, time) {
this.graph = graph;
this.time = time;
this.text = exceptiontext;
this.tick = tick;
var self = this;
this.draw = function(paper, server) {
var center = this.graph.tick_to_x(this.tick);
var p = paper.circle(center, server.y, 5);
p.attr({stroke: "orange", fill: "red"});
p.mouseover(function(evt) {
p.popup = document.createElement("div");
p.popup.className = "popUp";
p.popup.innerHTML = self.text.replace("\n", "
");;
p.popup.style.top = server.y + 50;
p.popup.style.left = center + 25;
document.body.appendChild(p.popup);
p.animate({r: 10}, 500, "elastic");
});
p.mouseout(function(evt) {
document.body.removeChild(p.popup);
p.animate({r: 5}, 100);
});
}
};
© 2015 - 2025 Weber Informatics LLC | Privacy Policy