var pm_root = "http://" + location.hostname + ":" + location.port + "/pmapi";
var pm_context = -1;
// ----------------------------------------------------------------------
function Predicate(name,index,operator,threshold) {
this.name = name;
this.index = index;
this.operator = operator;
this.threshold = threshold;
this.inames = {};
}
Predicate.prototype.to_string = function() {
return this.name + "[" + this.index + "] "
+ this.operator + " " + this.threshold;
};
Predicate.prototype.get_iname = function(iid) {
if (!(iid in this.inames)) {
var pm_url = pm_root + "/" + pm_context + "/_indom?name=" + this.name + "&instance=" + iid;
var predicate = this;
$.getJSON(pm_url, function(data, status) {
// TODOXXX error check: should return 1 instance
predicate.inames[iid] = data.instances[0].name;
});
return "..."; // will be reloaded next cycle
}
return this.inames[iid];
}
Predicate.prototype.test = function(elt,data_dict,index) {
if (this.index == "*" && typeof(index) == "undefined") {
var predicate = this;
$.each(data_dict[this.name].instances, function(i,_instance) {
predicate.test(elt,data_dict,i);
});
return;
}
if (typeof(index) == "undefined") index = this.index;
var metric = data_dict[this.name].instances[index].value;
var iid = data_dict[this.name].instances[index].instance;
var result = 0, error = "";
if (this.operator == "<") result = metric < this.threshold;
else if (this.operator == ">") result = metric > this.threshold;
else if (this.operator == "<=") result = metric <= this.threshold;
else if (this.operator == ">=") result = metric >= this.threshold;
else if (this.operator == "==") result = metric == this.threshold;
else { error = "unknown operator '" + this.operator + "'"; result = -1; }
// TODOXXX avoid $("#blinkenlights").empty() by using existing li's??
var bclass = result < 0 ? "error" : result ? "on" : "off";
var source = "" + metric + " -- "
+ this.name + " ( " + this.get_iname(iid) + " : " + iid + " ) "
+ this.operator + " " + this.threshold;
var content = "" + source + ""
+ (result < 0 ? " -- error: " + error : "");
elt.append("
" + content + "");
};
var predicates = [];
function parsePredicate(src) {
var matches = /^([^[ ]+)\s*(\[\d+\]|\[\*\]|\[\]|)\s*(<=|>=|==|<|>)\s*(\S*)$/.exec(src);
if (matches == null) return null;
var name = matches[1];
var index = matches[2]; index = index == "" ? "*" : index.substring(1,index.length-1);
var operator = matches[3];
var threshold = parseFloat(matches[4]); // TODOXXX what about other types?; accepts 40foobar
if (isNaN(threshold)) return null;
console.log ("create predicate " + name + " : " + index + " : " + operator + " : " + threshold)
return new Predicate(name,index,operator,threshold);
}
// ----------------------------------------------------------------------
var updateInterval = 10000; // milliseconds
var updateIntervalID = 1;
function setUpdateInterval(i) {
if (updateIntervalID >= 0) { clearInterval(updateIntervalID); }
if (i > updateInterval) { pm_context = -1; } // will likely need a new context
updateInterval = i;
updateIntervalID = setInterval(updateBlinkenlights, updateInterval);
}
// default mode
var pm_context_type = "hostspec";
var pm_context_spec = "localhost";
function setPMContextType(k) {
pm_context_type = k;
pm_context = -1;
updateBlinkenlights();
}
function setPMContextSpec(i) {
pm_context_spec = i;
pm_context = -1;
updateBlinkenlights();
}
function updateBlinkenlights() {
var pm_url;
if (pm_context < 0) {
pm_url = pm_root
+ "/context?"
+ pm_context_type + "=" + encodeURIComponent(pm_context_spec)
+ "&polltimeout=" + Math.floor(5*updateInterval/1000);
$.getJSON(pm_url, function(data, status) {
pm_context = data.context;
setTimeout(updateBlinkenlights, 100); // retry soon
}).error(function() { pm_context = -1; });
return; // will retry one cycle later
}
if(predicates.length == 0) {
$("#blinkenlights").html("No predicates requested...");
return;
}
// ajax request for JSON data
pm_url = pm_root + "/" + pm_context + "/_fetch?names=";
$.each(predicates, function(i, predicate) {
if (i > 0) pm_url += ",";
pm_url += predicate.name;
});
$.getJSON(pm_url, function(data, status) {
// update data_dict
var data_dict = {};
$.each(data.values, function(i, value) {
data_dict[value.name] = value;
});
// update status field
theDate = new Date(0);
theDate.setUTCSeconds(data.timestamp.s);
theDate.setUTCMilliseconds(data.timestamp.us/1000);
$("#status").html("Timestamp: " + theDate.toString());
// update the view
$("#blinkenlights").empty();
$.each(predicates, function(i, predicate) {
predicate.test($("#blinkenlights"), data_dict);
});
}).error(function() {
$("#blinkenlights").html("error accessing server, retrying...");
pm_context = -1; });
}
function loadBlinkenlights() {
$("#header").html("pcp blinkenlights demo");
$("#content").html("");
// start timer for updateBlinkenlights
updateBlinkenlights();
setUpdateInterval(updateInterval);
}
$(document).ready(function() {
loadBlinkenlights();
// TODOXXX add support for editing mode
});