Merge pull request #849 from prometheus/use-api-v1

Use v1 API for querying.
This commit is contained in:
Julius Volz 2015-06-25 15:14:01 +02:00
commit a8f117b02d
2 changed files with 62 additions and 46 deletions

View file

@ -176,16 +176,19 @@ Prometheus.Graph.prototype.populateInsertableMetrics = function() {
var self = this; var self = this;
$.ajax({ $.ajax({
method: "GET", method: "GET",
url: PATH_PREFIX + "/api/metrics", url: PATH_PREFIX + "/api/v1/label/__name__/values",
dataType: "json", dataType: "json",
success: function(json, textStatus) { success: function(json, textStatus) {
var availableMetrics = []; if (json.status !== "success") {
for (var i = 0; i < json.length; i++) { self.showError("Error loading available metrics!")
self.insertMetric[0].options.add(new Option(json[i], json[i])); return;
availableMetrics.push(json[i]); }
var metrics = json.data;
for (var i = 0; i < metrics.length; i++) {
self.insertMetric[0].options.add(new Option(metrics[i], metrics[i]));
} }
self.expr.typeahead({ self.expr.typeahead({
source: availableMetrics, source: metrics,
items: "all" items: "all"
}); });
// This needs to happen after attaching the typeahead plugin, as it // This needs to happen after attaching the typeahead plugin, as it
@ -267,7 +270,7 @@ Prometheus.Graph.prototype.decreaseRange = function() {
Prometheus.Graph.prototype.getEndDate = function() { Prometheus.Graph.prototype.getEndDate = function() {
var self = this; var self = this;
if (!self.endDate || !self.endDate.val()) { if (!self.endDate || !self.endDate.val()) {
return null; return new Date();
} }
return self.endDate.data('datetimepicker').getDate().getTime(); return self.endDate.data('datetimepicker').getDate().getTime();
}; };
@ -275,10 +278,6 @@ Prometheus.Graph.prototype.getEndDate = function() {
Prometheus.Graph.prototype.getOrSetEndDate = function() { Prometheus.Graph.prototype.getOrSetEndDate = function() {
var self = this; var self = this;
var date = self.getEndDate(); var date = self.getEndDate();
if (date) {
return date;
}
date = new Date();
self.setEndDate(date); self.setEndDate(date);
return date; return date;
} }
@ -311,36 +310,51 @@ Prometheus.Graph.prototype.submitQuery = function() {
self.evalStats.empty(); self.evalStats.empty();
var startTime = new Date().getTime(); var startTime = new Date().getTime();
var rangeSeconds = self.parseDuration(self.rangeInput.val()); var rangeSeconds = self.parseDuration(self.rangeInput.val());
self.queryForm.find("input[name=range]").val(rangeSeconds);
var resolution = self.queryForm.find("input[name=step_input]").val() || Math.max(Math.floor(rangeSeconds / 250), 1); var resolution = self.queryForm.find("input[name=step_input]").val() || Math.max(Math.floor(rangeSeconds / 250), 1);
self.queryForm.find("input[name=step]").val(resolution);
var endDate = self.getEndDate() / 1000; var endDate = self.getEndDate() / 1000;
self.queryForm.find("input[name=end]").val(endDate);
if (self.queryXhr) { if (self.queryXhr) {
self.queryXhr.abort(); self.queryXhr.abort();
} }
var url; var url;
var success; var success;
var params = {
"query": self.expr.val()
};
if (self.options["tab"] === 0) { if (self.options["tab"] === 0) {
url = self.queryForm.attr("action"); params['start'] = endDate - rangeSeconds;
params['end'] = endDate;
params['step'] = resolution;
url = PATH_PREFIX + "/api/v1/query_range";
success = function(json, textStatus) { self.handleGraphResponse(json, textStatus); }; success = function(json, textStatus) { self.handleGraphResponse(json, textStatus); };
} else { } else {
url = PATH_PREFIX + "/api/query"; params['time'] = startTime / 1000;
success = function(text, textStatus) { self.handleConsoleResponse(text, textStatus); }; url = PATH_PREFIX + "/api/v1/query";
success = function(json, textStatus) { self.handleConsoleResponse(json, textStatus); };
} }
self.queryXhr = $.ajax({ self.queryXhr = $.ajax({
method: self.queryForm.attr("method"), method: self.queryForm.attr("method"),
url: url, url: url,
dataType: "json", dataType: "json",
data: self.queryForm.serialize(), data: params,
success: success, success: function(json, textStatus) {
if (json.status !== "success") {
self.showError(json.error);
return;
}
success(json.data, textStatus);
},
error: function(xhr, resp) { error: function(xhr, resp) {
if (resp != "abort") { if (resp != "abort") {
self.showError("Error executing query: " + resp); var err;
if (xhr.responseJSON !== undefined) {
err = xhr.responseJSON.error;
} else {
err = xhr.statusText;
}
self.showError("Error executing query: " + err);
} }
}, },
complete: function() { complete: function() {
@ -414,14 +428,23 @@ Prometheus.Graph.prototype.parseValue = function(value) {
Prometheus.Graph.prototype.transformData = function(json) { Prometheus.Graph.prototype.transformData = function(json) {
var self = this; var self = this;
var palette = new Rickshaw.Color.Palette(); var palette = new Rickshaw.Color.Palette();
if (json.type != "matrix") { if (json.resultType != "matrix") {
self.showError("Result is not of matrix type! Please enter a correct expression."); self.showError("Result is not of matrix type! Please enter a correct expression.");
return []; return [];
} }
var data = json.value.map(function(ts) { var data = json.result.map(function(ts) {
var name;
var labels;
if (ts.metric === null) {
name = "scalar";
labels = {};
} else {
name = escapeHTML(self.metricToTsName(ts.metric));
labels = ts.metric;
}
return { return {
name: escapeHTML(self.metricToTsName(ts.metric)), name: name,
labels: ts.metric, labels: labels,
data: ts.values.map(function(value) { data: ts.values.map(function(value) {
return { return {
x: value[0], x: value[0],
@ -450,7 +473,7 @@ Prometheus.Graph.prototype.updateGraph = function() {
self.graphArea.append(self.graph); self.graphArea.append(self.graph);
self.graphArea.append(self.yAxis); self.graphArea.append(self.yAxis);
var endTime = (self.getEndDate() || (new Date()).getTime()) / 1000; // Convert to UNIX timestamp. var endTime = self.getEndDate() / 1000; // Convert to UNIX timestamp.
var duration = self.parseDuration(self.rangeInput.val()) || 3600; // 1h default. var duration = self.parseDuration(self.rangeInput.val()) || 3600; // 1h default.
var startTime = endTime - duration; var startTime = endTime - duration;
self.data.forEach(function(s) { self.data.forEach(function(s) {
@ -526,10 +549,6 @@ Prometheus.Graph.prototype.resizeGraph = function() {
Prometheus.Graph.prototype.handleGraphResponse = function(json, textStatus) { Prometheus.Graph.prototype.handleGraphResponse = function(json, textStatus) {
var self = this var self = this
if (json.type == "error") {
self.showError(json.value);
return;
}
// Rickshaw mutates passed series data for stacked graphs, so we need to save // Rickshaw mutates passed series data for stacked graphs, so we need to save
// the original AJAX response in order to re-transform it into series data // the original AJAX response in order to re-transform it into series data
// when the user disables the stacking. // when the user disables the stacking.
@ -551,25 +570,25 @@ Prometheus.Graph.prototype.handleConsoleResponse = function(data, textStatus) {
var tBody = self.consoleTab.find(".console_table tbody"); var tBody = self.consoleTab.find(".console_table tbody");
tBody.empty(); tBody.empty();
switch(data.type) { switch(data.resultType) {
case "vector": case "vector":
if (data.value.length === 0) { if (data.result.length === 0) {
tBody.append("<tr><td colspan='2'><i>no data</i></td></tr>"); tBody.append("<tr><td colspan='2'><i>no data</i></td></tr>");
return; return;
} }
for (var i = 0; i < data.value.length; i++) { for (var i = 0; i < data.result.length; i++) {
var v = data.value[i]; var s = data.result[i];
var tsName = self.metricToTsName(v.metric); var tsName = self.metricToTsName(s.metric);
tBody.append("<tr><td>" + escapeHTML(tsName) + "</td><td>" + v.value + "</td></tr>"); tBody.append("<tr><td>" + escapeHTML(tsName) + "</td><td>" + s.value + "</td></tr>");
} }
break; break;
case "matrix": case "matrix":
if (data.value.length === 0) { if (data.result.length === 0) {
tBody.append("<tr><td colspan='2'><i>no data</i></td></tr>"); tBody.append("<tr><td colspan='2'><i>no data</i></td></tr>");
return; return;
} }
for (var i = 0; i < data.value.length; i++) { for (var i = 0; i < data.result.length; i++) {
var v = data.value[i]; var v = data.result[i];
var tsName = self.metricToTsName(v.metric); var tsName = self.metricToTsName(v.metric);
var valueText = ""; var valueText = "";
for (var j = 0; j < v.values.length; j++) { for (var j = 0; j < v.values.length; j++) {
@ -579,10 +598,10 @@ Prometheus.Graph.prototype.handleConsoleResponse = function(data, textStatus) {
} }
break; break;
case "scalar": case "scalar":
tBody.append("<tr><td>scalar</td><td>" + data.value + "</td></tr>"); tBody.append("<tr><td>scalar</td><td>" + data.result.value + "</td></tr>");
break; break;
case "error": case "string":
self.showError(data.value); tBody.append("<tr><td>string</td><td>" + data.result.value + "</td></tr>");
break; break;
default: default:
self.showError("Unsupported value type!"); self.showError("Unsupported value type!");

View file

@ -1,5 +1,5 @@
<div id="graph_wrapper{{id}}" class="graph_wrapper"> <div id="graph_wrapper{{id}}" class="graph_wrapper">
<form action="{{ pathPrefix }}/api/query_range" method="GET" class="query_form form-inline"> <form class="query_form form-inline">
<div class="row"> <div class="row">
<div class="col-lg-10"> <div class="col-lg-10">
<textarea rows="1" placeholder="Expression (press Shift+Enter for newlines)" name="expr" id="expr{{id}}" class="form-control expression_input" data-provide="typeahead" autocomplete="off">{{expr}}</textarea> <textarea rows="1" placeholder="Expression (press Shift+Enter for newlines)" name="expr" id="expr{{id}}" class="form-control expression_input" data-provide="typeahead" autocomplete="off">{{expr}}</textarea>
@ -38,7 +38,6 @@
<div role="tabpanel" class="tab-pane graph_container reload" id="graph{{id}}"> <div role="tabpanel" class="tab-pane graph_container reload" id="graph{{id}}">
<div class="clearfix"> <div class="clearfix">
<!-- Extracted to force grouped inputs. --> <!-- Extracted to force grouped inputs. -->
<input type="hidden" name="range">
<div class="prometheus_input_group range_input pull-left"> <div class="prometheus_input_group range_input pull-left">
<button <button
class="btn btn-default pull-left" class="btn btn-default pull-left"
@ -65,7 +64,6 @@
</div> </div>
<!-- Extracted to force grouped inputs. --> <!-- Extracted to force grouped inputs. -->
<input type="hidden" name="end">
<div class="prometheus_input_group pull-left"> <div class="prometheus_input_group pull-left">
<button <button
@ -98,7 +96,6 @@
<div class="prometheus_input_group pull-left"> <div class="prometheus_input_group pull-left">
<input class="input" title="Resolution in seconds" placeholder="Res. (s)" type="text" name="step_input" id="step_input{{id}}" value="{{step_input}}" size="6"> <input class="input" title="Resolution in seconds" placeholder="Res. (s)" type="text" name="step_input" id="step_input{{id}}" value="{{step_input}}" size="6">
<input type="hidden" name="step">
</div> </div>
<div class="prometheus_input_group pull-left"> <div class="prometheus_input_group pull-left">