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