mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Merge branch 'influxdb-updates' of github.com:influxdb/grafana into influxdb-influxdb-updates
This commit is contained in:
commit
c592db4024
@ -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) {
|
||||
|
@ -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");
|
||||
|
||||
var query = _.template(template, templateData, this.templateSettings);
|
||||
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(" ");
|
||||
|
||||
}
|
||||
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);
|
||||
|
||||
console.log(query);
|
||||
return $http(options);
|
||||
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);
|
||||
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user