lib/logstash/web/public/js/logstash.js in logstash-lite-0.2.20110206003603 vs lib/logstash/web/public/js/logstash.js in logstash-lite-0.2.20110329105411
- old
+ new
@@ -1,28 +1,88 @@
(function() {
+ // TODO(sissel): Write something that will use history.pushState and fall back
+ // to document.location.hash madness.
var logstash = {
params: {
offset: 0,
count: 50,
},
- search: function(query) {
+ search: function(query, options) {
if (query == undefined || query == "") {
return;
}
- //console.log("Searching: " + query);
+ /* Default options */
+ if (typeof(options) == 'undefined') {
+ options = { graph: true };
+ }
+
var display_query = query.replace("<", "<").replace(">", ">")
- $("#querystatus").html("Loading query '" + display_query + "'")
+ $("#querystatus, #results h1").html("Loading query '" + display_query + "' (offset:" + logstash.params.offset + ", count:" + logstash.params.count + ") <img class='throbber' src='/media/construction.gif'>")
//console.log(logstash.params)
logstash.params.q = query;
document.location.hash = escape(JSON.stringify(logstash.params));
- $("#results").load("/search/ajax", logstash.params);
+
+ /* Load the search results */
+ $("#results").load("/api/search?format=html", logstash.params);
+
+ if (options.graph != false) {
+ /* Load the default histogram graph */
+ logstash.params.interval = 3600000; /* 1 hour, default */
+ logstash.histogram();
+ } /* if options.graph != false */
$("#query").val(logstash.params.q);
}, /* search */
+ histogram: function(tries) {
+ if (typeof(tries) == 'undefined') {
+ tries = 7;
+ }
+
+ /* GeoCities mode on the graph while waiting ...
+ * This won't likely survive 1.0, but it's fun for now... */
+ $("#visual").html("<center><img src='/media/truckconstruction.gif'><center>");
+
+ jQuery.getJSON("/api/histogram", logstash.params, function(histogram, text, jqxhr) {
+ /* Load the data into the graph */
+ var flot_data = [];
+ // histogram is an array of { "key": ..., "count": ... }
+ for (var i in histogram) {
+ flot_data.push([parseInt(histogram[i]["key"]), histogram[i]["count"]])
+ }
+ logstash.plot(flot_data, logstash.params.interval);
+ //console.log(histogram);
+
+ /* Try to be intelligent about how we choose the histogram interval.
+ * If there are too few data points, try a smaller interval.
+ * If there are too many data points, try a larger interval.
+ * Give up after a few tries and go with the last result.
+ *
+ * This queries the backend several times, but should be reasonably
+ * speedy as this behaves roughly as a binary search. */
+ //if (flot_data.length < 6 && flot_data.length > 0 && tries > 0) {
+ //console.log("Histogram bucket " + logstash.params.interval + " has only " + flot_data.length + " data points, trying smaller...");
+ //logstash.params.interval /= 2;
+ //if (logstash.params.interval < 1000) {
+ //tries = 0; /* stop trying, too small... */
+ //logstash.plot(flot_data, logstash.params.interval);
+ //return;
+ //}
+ //logstash.histogram(tries - 1);
+ //} else if (flot_data.length > 50 && tries > 0) {
+ //console.log("Histogram bucket " + logstash.params.interval + " too many (" + flot_data.length + ") data points, trying larger interval...");
+ //logstash.params.interval *= 2;
+ //logstash.histogram(tries - 1);
+ //} else {
+ //console.log("Histo:" + logstash.params.interval);
+ //logstash.plot(flot_data, logstash.params.interval);
+ //}
+ });
+ },
+
parse_params: function(href) {
var query = href.replace(/^[^?]*\?/, "");
if (query == href) {
//console.log("No query params in link " + href);
/* No query params */
@@ -46,18 +106,19 @@
var newquery = $("#query").val();
newquery += " " + query;
logstash.search(newquery.trim());
}, /* appendquery */
- plot: function(data) {
+ plot: function(data, interval) {
var target = $("#visual");
+ target.css("display", "block");
var plot = $.plot(target,
[ { /* data */
data: data,
bars: {
show: true,
- barWidth: 3600000,
+ barWidth: interval,
}
} ],
{ /* options */
xaxis: { mode: "time" },
grid: { hoverable: true, clickable: true },
@@ -65,12 +126,16 @@
);
target.bind("plotclick", function(e, pos, item) {
if (item) {
start = logstash.ms_to_iso8601(item.datapoint[0]);
- end = logstash.ms_to_iso8601(item.datapoint[0] + 3600000);
+ end = logstash.ms_to_iso8601(item.datapoint[0] + interval);
+ /* Clicking on the graph means a new search, means
+ * we probably don't want to keep the old offset since
+ * the search results will change. */
+ logstash.params.offset = 0;
logstash.appendquery("@timestamp:[" + start + " TO " + end + "]");
}
});
}, /* plot */
@@ -123,17 +188,20 @@
var href = $(this).attr("href");
var params = logstash.parse_params(href);
for (var p in params) {
logstash.params[p] = params[p];
}
- logstash.search(logstash.params.q)
+ logstash.search(logstash.params.q, { graph: false })
return false;
});
var result_row_selector = "table.results tr.event";
$(result_row_selector).live("click", function() {
- var data = eval($("td.message", this).data("full"));
+ var data = $("td.message", this).data("full");
+ if (typeof(data) == "string") {
+ data = JSON.parse(data);
+ }
/* Apply template to the dialog */
var query = $("#query").val().replace(/^\s+|\s+$/g, "")
var sanitize = function(str) {
if (!/^".*"$/.test(str)) {
@@ -153,23 +221,23 @@
"{{/each}}" +
"</li>");
/* TODO(sissel): recurse through the data */
var fields = new Array();
- for (var i in data._source["@fields"]) {
- var value = data._source["@fields"][i]
+ for (var i in data["@fields"]) {
+ var value = data["@fields"][i]
if (/^[, ]*$/.test(value)) {
continue; /* Skip empty data fields */
}
if (!(value instanceof Array)) {
value = [value];
}
fields.push( { type: "field", field: i, value: value })
}
- for (var i in data._source) {
+ for (var i in data) {
if (i == "@fields") continue;
- var value = data._source[i]
+ var value = data[i]
if (!(value instanceof Array)) {
value = [value];
}
if (i.charAt(0) == "@") { /* metadata */