Commit 50fd5512 by Torkel Ödegaard

more work on influxdb datasource, query editor, and refactoring

parent 291dd9bd
......@@ -52,14 +52,17 @@ function (_, crypto) {
if (options.graphiteUrl) {
settings.datasources = {
graphite: {
name: 'default',
type: 'graphite',
url: options.graphiteUrl,
default: true
}
};
}
_.map(settings.datasources, parseBasicAuth);
_.each(settings.datasources, function(datasource, key) {
datasource.name = key;
parseBasicAuth(datasource);
});
var elasticParsed = parseBasicAuth({ url: settings.elasticsearch });
settings.elasticsearchBasicAuth = elasticParsed.basicAuth;
......
......@@ -27,16 +27,6 @@
<div class="tab-content" ng-repeat="tab in panelMeta.fullEditorTabs" ng-show="editorTabs[editor.index] == tab.title">
<div ng-include src="tab.src"></div>
<div class="editor-row" ng-show="editor.index === 0">
<div class="section">
<h5>Datasource options</h5>
<div class="editor-option">
<label class="small">Datasource name</label>
<select class="input-large" ng-options="obj.value as obj.name for obj in datasources" ng-model="panel.datasource" ng-change="datasourceChanged()"></select>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
......@@ -46,6 +46,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
},
{
title: 'Metrics',
src:'app/partials/metrics.html'
},
{
title:'Axes & Grid',
......@@ -206,12 +207,12 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
$scope.hiddenSeries = {};
$scope.datasources = datasourceSrv.listOptions();
$scope.datasourceChanged();
$scope.setDatasource($scope.panel.datasource);
};
$scope.datasourceChanged = function() {
$scope.datasource = datasourceSrv.get($scope.panel.datasource);
$scope.panelMeta.fullEditorTabs[1].src = $scope.datasource.editorSrc;
$scope.setDatasource = function(datasource) {
$scope.panel.datasource = datasource;
$scope.datasource = datasourceSrv.get(datasource);
$scope.get_data();
};
......@@ -299,6 +300,8 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
yaxis: yaxis
};
$scope.legend.push(seriesInfo);
var series = new timeSeries.ZeroFilled({
datapoints: datapoints,
info: seriesInfo,
......
<div class="editor-row">
<div class="editor-row" style="margin-top: 10px;">
<div ng-repeat="target in panel.targets"
class="grafana-target"
......@@ -112,6 +112,3 @@
</div>
</div>
<div class="editor-row" style="margin-top: 20px" ng-show="editor.index == 1">
<button class="btn btn-success pull-right" ng-click="add_target(panel.target)">Add target</button>
</div>
\ No newline at end of file
<h5>InfluxDB queries<h5>
<div class="editor-row">
<div class="editor-row" style="margin-top: 10px;">
<div ng-repeat="target in panel.targets"
class="grafana-target"
......@@ -44,10 +43,8 @@
</ul>
<ul class="grafana-segment-list" role="menu">
<li>
<a class="grafana-target-segment">
from series
</a>
<li class="grafana-target-segment">
from series
</li>
<li>
<input type="text"
......@@ -55,12 +52,10 @@
ng-model="target.series"
spellcheck='false'
placeholder="series name"
ng-model-onblur ng-change="targetTextChanged()" >
ng-model-onblur ng-change="get_data()" >
</li>
<li>
<a class="grafana-target-segment">
select
</a>
<li class="grafana-target-segment">
select
</li>
<li>
<input type="text"
......@@ -68,25 +63,31 @@
ng-model="target.column"
placeholder="value column"
spellcheck='false'
ng-model-onblur ng-change="targetTextChanged()" >
ng-model-onblur ng-change="get_data()" >
</li>
<li class="grafana-target-segment">
function
</li>
<li>
<a class="grafana-target-segment">
function
</a>
<select class="input-medium grafana-target-segment-input" ng-change="get_data()" ng-model="target.function" ng-options="f for f in ['mean', 'sum', 'min', 'max', 'median', 'derivative', 'stddev']" ></select>
</li>
<li class="grafana-target-segment">
group by time
</li>
<li>
<select class="input-small grafana-target-segment-input" ng-model="target.function" ng-options="f for f in ['mean', 'sum']" ></select>
<input type="text"
class="input-mini grafana-target-segment-input"
ng-model="target.interval"
placeholder="{{interval}}"
bs-tooltip="'Leave blank for auto handling based on time range and panel width'"
spellcheck='false'
ng-model-onblur ng-change="get_data()" >
</li>
</ul>
<div class="clearfix"></div>
</div>
</div>
</div>
</div>
<div class="editor-row" style="margin-top: 20px" ng-show="editor.index == 1">
<button class="btn btn-success pull-right" ng-click="add_target(panel.target)">Add query</button>
</div>
\ No newline at end of file
<div ng-include src="datasource.editorSrc"></div>
<div class="editor-row" style="margin-top: 20px">
<button class="btn btn-success pull-right" ng-click="add_target(panel.target)">Add query</button>
<div class="btn-group pull-right" style="margin-right: 10px;">
<button class="btn btn-info dropdown-toggle" data-toggle="dropdown">DS {{datasource.name}} <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li ng-repeat="datasource in datasources" role="menuitem">
<a ng-click="setDatasource(datasource.value);">{{datasource.name}}</a>
</li>
</ul>
</div>
</div>
......@@ -18,6 +18,7 @@ function (angular, _, $, config, kbn, moment) {
this.basicAuth = datasource.basicAuth;
this.url = datasource.url;
this.editorSrc = 'app/partials/graphite/editor.html';
this.name = datasource.name;
}
GraphiteDatasource.prototype.query = function(options) {
......
define([
'angular',
'underscore',
'kbn'
],
function (angular, _) {
function (angular, _, kbn) {
'use strict';
var module = angular.module('kibana.services');
......@@ -15,6 +16,7 @@ function (angular, _) {
this.url = datasource.url;
this.username = datasource.username;
this.password = datasource.password;
this.name = datasource.name;
this.templateSettings = {
interpolate : /\[\[([\s\S]+?)\]\]/g,
......@@ -22,49 +24,32 @@ function (angular, _) {
}
InfluxDatasource.prototype.query = function(options) {
var target = options.targets[0];
var template = "select [[func]]([[column]]) from [[series]] where [[timeFilter]] group by time([[interval]])";
var templateData = {
series: target.series,
column: target.column,
func: target.function,
timeFilter: getTimeFilter(options),
interval: options.interval
};
var query = _.template(template, templateData, this.templateSettings);
console.log(query);
var output = { data: [] };
return this.doInfluxRequest(query).then(function(results) {
var promises = _.map(options.targets, function(target) {
if (!target.series || !target.column || target.hide) {
return [];
}
_.each(results.data, function(series) {
var timeCol = series.columns.indexOf('time');
var template = "select [[func]]([[column]]) from [[series]] where [[timeFilter]] group by time([[interval]]) order asc";
_.each(series.columns, function(column, index) {
if (column === "time" || column === "sequence_number") {
return;
}
var templateData = {
series: target.series,
column: target.column,
func: target.function,
timeFilter: getTimeFilter(options),
interval: target.interval || options.interval
};
console.log("series:"+series.name + ": "+series.points.length + " points");
var query = _.template(template, templateData, this.templateSettings);
console.log(query);
var target = series.name + "." + column;
var datapoints = [];
return this.doInfluxRequest(query).then(handleInfluxQueryResponse);
var i, y;
for(i = series.points.length - 1, y = 0; i >= 0; i--, y++) {
var t = Math.floor(series.points[i][timeCol] / 1000);
var v = series.points[i][index];
datapoints[y] = [v,t];
}
}, this);
output.data.push({ target:target, datapoints:datapoints });
});
});
return $q.all(promises).then(function(results) {
return output;
return { data: _.flatten(results) };
});
};
......@@ -85,24 +70,59 @@ function (angular, _) {
return $http(options);
};
function handleInfluxQueryResponse(results) {
var output = [];
_.each(results.data, function(series) {
var timeCol = series.columns.indexOf('time');
_.each(series.columns, function(column, index) {
if (column === "time" || column === "sequence_number") {
return;
}
console.log("series:"+series.name + ": "+series.points.length + " points");
var target = series.name + "." + column;
var datapoints = [];
for(var i = 0; i < series.points.length; i++) {
var t = Math.floor(series.points[i][timeCol] / 1000);
var v = series.points[i][index];
datapoints[i] = [v,t];
}
output.push({ target:target, datapoints:datapoints });
});
});
return output;
}
function getTimeFilter(options) {
var from = options.range.from;
var until = options.range.to;
var from = getInfluxTime(options.range.from);
var until = getInfluxTime(options.range.to);
if (_.isString(from)) {
return 'time > now() - ' + from.substring(4);
}
else {
from = to_utc_epoch_seconds(from);
if (until === 'now()') {
return 'time > now() - ' + from;
}
if (until === 'now') {
return 'time > ' + from;
}
else {
until = to_utc_epoch_seconds(until);
return 'time > ' + from + ' and time < ' + until;
return 'time > ' + from + ' and time < ' + until;
}
function getInfluxTime(date) {
if (_.isString(date)) {
if (date === 'now') {
return 'now()';
}
else if (date.indexOf('now') >= 0) {
return date.substring(4);
}
date = kbn.parseDate(date);
}
return to_utc_epoch_seconds(date);
}
function to_utc_epoch_seconds(date) {
......
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