Commit c592db40 by Torkel Ödegaard

Merge branch 'influxdb-updates' of github.com:influxdb/grafana into influxdb-influxdb-updates

parents 02af2dbe b3e45986
......@@ -49,6 +49,11 @@ function (_, crypto) {
return datasource;
};
var parseMultipleHosts = function(datasource) {
datasource.urls = _.map(datasource.url.split(","), function (url) { return url.trim(); });
return datasource;
};
if (options.graphiteUrl) {
settings.datasources = {
graphite: {
......@@ -62,6 +67,7 @@ function (_, crypto) {
_.each(settings.datasources, function(datasource, key) {
datasource.name = key;
parseBasicAuth(datasource);
if (datasource.type === 'influxdb') { parseMultipleHosts(datasource); }
});
var elasticParsed = parseBasicAuth({ url: settings.elasticsearch });
......
......@@ -15,6 +15,8 @@ function (angular) {
$scope.target.function = 'mean';
}
$scope.rawQuery = false;
$scope.functions = ['count', 'mean', 'sum', 'min', 'max', 'mode', 'distinct', 'median', 'derivative', 'stddev', 'first', 'last'];
$scope.oldSeries = $scope.target.series;
$scope.$on('typeahead-updated', function(){
......@@ -22,6 +24,14 @@ function (angular) {
});
};
$scope.showQuery = function () {
$scope.target.rawQuery = true;
};
$scope.hideQuery = function () {
$scope.target.rawQuery = false;
};
// Cannot use typeahead and ng-change on blur at the same time
$scope.seriesBlur = function() {
if ($scope.oldSeries !== $scope.target.series) {
......@@ -65,4 +75,4 @@ function (angular) {
});
});
\ No newline at end of file
});
......@@ -11,17 +11,16 @@
<div class="grafana-target-inner">
<ul class="grafana-target-controls">
<li class="dropdown">
<a class="pointer dropdown-toggle"
data-toggle="dropdown"
tabindex="1">
<a class="pointer dropdown-toggle"
data-toggle="dropdown"
tabindex="1">
<i class="icon-cog"></i>
</a>
<ul class="dropdown-menu pull-right" role="menu">
<li role="menuitem">
<a tabindex="1"
ng-click="duplicate()">
Duplicate
</a>
<a tabindex="1" ng-click="duplicate()">Duplicate</a>
<a tabindex="2" ng-click="showQuery()" ng-hide="target.rawQuery">Show Query</a>
<a tabindex="2" ng-click="hideQuery()" ng-show="target.rawQuery">Hide Query</a>
</li>
</ul>
</li>
......@@ -34,19 +33,30 @@
<ul class="grafana-target-controls-left">
<li>
<a class="grafana-target-segment"
ng-click="target.hide = !target.hide; get_data();"
role="menuitem">
<a class="grafana-target-segment"
ng-click="target.hide = !target.hide; get_data();"
role="menuitem">
<i class="icon-eye-open"></i>
</a>
</li>
</ul>
<ul class="grafana-segment-list" role="menu">
<li class="grafana-target-segment">
<li ng-show="target.rawQuery">
<input type="text"
class="input-large grafana-target-segment-input"
style="width:843px;"
ng-model="target.query"
placeholder="select ..."
data-min-length=0 data-items=100
ng-blur="get_data()">
</li>
<li class="grafana-target-segment" ng-hide="target.rawQuery">
from series
</li>
<li>
<li ng-hide="target.rawQuery">
<input type="text"
class="input-medium grafana-target-segment-input"
ng-model="target.series"
......@@ -54,13 +64,14 @@
bs-typeahead="listSeries"
placeholder="series name"
data-min-length=0 data-items=100
ng-blur="seriesBlur()"
>
ng-blur="seriesBlur()">
</li>
<li class="grafana-target-segment">
<li class="grafana-target-segment" ng-hide="target.rawQuery">
select
</li>
<li>
<li ng-hide="target.rawQuery">
<input type="text"
class="input-medium grafana-target-segment-input"
ng-model="target.column"
......@@ -70,20 +81,23 @@
data-min-length=0
ng-blur="get_data()">
</li>
<li class="grafana-target-segment">
<li class="grafana-target-segment" ng-hide="target.rawQuery">
function
</li>
<li>
<li ng-hide="target.rawQuery">
<select class="input-medium grafana-target-segment-input"
ng-change="get_data()"
ng-model="target.function"
ng-options="f for f in functions" ></select>
</li>
</li>
<li class="grafana-target-segment">
<li class="grafana-target-segment" ng-hide="target.rawQuery">
group by time
</li>
<li>
<li ng-hide="target.rawQuery">
<input type="text"
class="input-mini grafana-target-segment-input"
ng-model="target.interval"
......
......@@ -13,7 +13,7 @@ function (angular, _, kbn) {
function InfluxDatasource(datasource) {
this.type = 'influxDB';
this.editorSrc = 'app/partials/influxdb/editor.html';
this.url = datasource.url;
this.urls = datasource.urls;
this.username = datasource.username;
this.password = datasource.password;
this.name = datasource.name;
......@@ -26,78 +26,129 @@ function (angular, _, kbn) {
InfluxDatasource.prototype.query = function(options) {
var promises = _.map(options.targets, function(target) {
if (!target.series || !target.column || target.hide) {
var query;
if (target.hide || !((target.series && target.column) || target.query)) {
return [];
}
var template = "select [[func]]([[column]]) as [[column]]_[[func]] from [[series]] where [[timeFilter]]" +
" group by time([[interval]]) order asc";
var timeFilter = getTimeFilter(options);
var templateData = {
series: target.series,
column: target.column,
func: target.function,
timeFilter: getTimeFilter(options),
interval: target.interval || options.interval
};
if (target.rawQuery) {
query = target.query;
query = query.replace(";", "");
var queryElements = query.split(" ");
var lowerCaseQueryElements = query.toLowerCase().split(" ");
var whereIndex = lowerCaseQueryElements.indexOf("where");
var groupByIndex = lowerCaseQueryElements.indexOf("group");
var orderIndex = lowerCaseQueryElements.indexOf("order");
if (whereIndex !== -1) {
queryElements.splice(whereIndex+1, 0, timeFilter, "and");
}
else {
if (groupByIndex !== -1) {
queryElements.splice(groupByIndex, 0, "where", timeFilter);
}
else if (orderIndex !== -1) {
queryElements.splice(orderIndex, 0, "where", timeFilter);
}
else {
queryElements.push("where");
queryElements.push(timeFilter);
}
}
query = queryElements.join(" ");
var query = _.template(template, templateData, this.templateSettings);
}
else {
var template = "select [[func]]([[column]]) as [[column]]_[[func]] from [[series]] where [[timeFilter]]" +
" group by time([[interval]]) order asc";
var templateData = {
series: target.series,
column: target.column,
func: target.function,
timeFilter: timeFilter,
interval: target.interval || options.interval
};
query = _.template(template, templateData, this.templateSettings);
target.query = query;
}
return this.doInfluxRequest(query).then(handleInfluxQueryResponse);
}, this);
return $q.all(promises).then(function(results) {
return { data: _.flatten(results) };
});
};
InfluxDatasource.prototype.listColumns = function(seriesName) {
return this.doInfluxRequest('select * from ' + seriesName + ' limit 1').then(function(results) {
console.log('response!');
if (!results.data) {
return this.doInfluxRequest('select * from ' + seriesName + ' limit 1').then(function(data) {
if (!data) {
return [];
}
return results.data[0].columns;
return data[0].columns;
});
};
InfluxDatasource.prototype.listSeries = function() {
return this.doInfluxRequest('list series').then(function(results) {
if (!results.data) {
return [];
}
return _.map(results.data, function(series) {
return this.doInfluxRequest('list series').then(function(data) {
return _.map(data, function(series) {
return series.name;
});
});
};
function retry(deferred, callback, delay) {
return callback().then(undefined, function(reason) {
if (reason.status !== 0) {
deferred.reject(reason);
}
setTimeout(function() {
return retry(deferred, callback, Math.min(delay * 2, 30000));
}, delay);
});
}
InfluxDatasource.prototype.doInfluxRequest = function(query) {
var params = {
u: this.username,
p: this.password,
q: query
};
var _this = this;
var deferred = $q.defer();
var options = {
method: 'GET',
url: this.url + '/series',
params: params,
};
retry(deferred, function() {
var currentUrl = _this.urls.shift();
_this.urls.push(currentUrl);
var params = {
u: _this.username,
p: _this.password,
q: query
};
var options = {
method: 'GET',
url: currentUrl + '/series',
params: params,
};
return $http(options).success(function (data) {
deferred.resolve(data);
});
}, 10);
console.log(query);
return $http(options);
return deferred.promise;
};
function handleInfluxQueryResponse(results) {
function handleInfluxQueryResponse(data) {
var output = [];
_.each(results.data, function(series) {
_.each(data, function(series) {
var timeCol = series.columns.indexOf('time');
_.each(series.columns, function(column, index) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment