refactoring of graphite panel to be more datasource agnostic, start of experimental influxdb support

This commit is contained in:
Torkel Ödegaard 2014-02-27 21:46:06 +01:00
parent ed2770e380
commit e3f56f2645
14 changed files with 140 additions and 67 deletions

View File

@ -69,8 +69,7 @@
"nullPointMode": "connected",
"steppedLine": false,
"tooltip": {
"value_type": "cumulative",
"query_as_alias": true
"value_type": "cumulative"
},
"targets": [
{

View File

@ -289,7 +289,7 @@ function (angular, $, kbn, moment, _) {
seriesInfo = item.series.info;
format = scope.panel.y_formats[seriesInfo.yaxis - 1];
if (seriesInfo.alias || scope.panel.tooltip.query_as_alias) {
if (seriesInfo.alias) {
group = '<small style="font-size:0.9em;">' +
'<i class="icon-circle" style="color:'+item.series.color+';"></i>' + ' ' +
(seriesInfo.alias || seriesInfo.query)+

View File

@ -88,8 +88,7 @@ function (angular, $) {
var nameAsPath = name.replace(".", "/");
$scope.require([
'jquery',
'text!panels/'+nameAsPath+'/module.html',
'text!panels/'+nameAsPath+'/editor.html'
'text!panels/'+nameAsPath+'/module.html'
], function ($, moduleTemplate) {
var $module = $(moduleTemplate);
// top level controllers

View File

@ -32,22 +32,18 @@
</div>
</div>
<!-- <div class="tab-content" ng-show="editorTabs[editor.index] == 'General'">
<div ng-include src="'app/partials/panelgeneral.html'"></div>
<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="datasources.length > 0">
<div class="editor-row" ng-show="editor.index === 0">
<div class="section">
<h5>Datasource options</h5>
<div class="editor-option">
<label class="small">Datasource</label>
<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 class="tab-content" ng-repeat="tab in panelMeta.editorTabs" ng-show="editorTabs[editor.index] == tab.title">
<div ng-include src="tab.src"></div>
</div>
</div>
</div>

View File

@ -38,15 +38,15 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
$scope.panelMeta = {
modals : [],
editorTabs: [],
editorTabs : [
fullEditorTabs : [
{
title: 'General',
src:'app/partials/panelgeneral.html'
},
{
title:'Targets',
src:'app/panels/graphite/editor.html'
title: 'Metrics',
},
{
title:'Axes & Grid',
@ -80,7 +80,7 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
],
status : "Unstable",
description : "Graphite graphing panel <br /><br />"
description : "Graphs panel"
};
// Set and populate defaults
@ -224,21 +224,18 @@ function (angular, app, $, _, kbn, moment, timeSeries) {
$scope.fullscreen = false;
$scope.options = false;
$scope.editor = {index: 1};
$scope.editorTabs = _.pluck($scope.panelMeta.editorTabs,'title');
$scope.editorTabs = _.pluck($scope.panelMeta.fullEditorTabs,'title');
$scope.hiddenSeries = {};
$scope.datasources = datasourceSrv.listOptions();
$scope.datasource = datasourceSrv.get($scope.panel.datasource);
// Always show the query if an alias isn't set. Users can set an alias if the query is too
// long
$scope.panel.tooltip.query_as_alias = true;
$scope.datasourceChanged();
$scope.get_data();
};
$scope.datasourceChanged = function() {
$scope.datasource = datasourceSrv.get($scope.panel.datasource);
$scope.panelMeta.fullEditorTabs[1].src = $scope.datasource.editorSrc;
$scope.get_data();
};

View File

@ -1,3 +1,4 @@
<div class="editor-row">
<div ng-repeat="target in panel.targets"
@ -75,7 +76,7 @@
</ul>
</li>
<li ng-repeat="func in functions">
<a class="grafana-target-segment grafana-target-function dropdown-toggle" bs-popover="'app/panels/graphite/funcEditor.html'" data-placement="bottom">
<a class="grafana-target-segment grafana-target-function dropdown-toggle" bs-popover="'app/partials/graphite/funcEditor.html'" data-placement="bottom">
{{func.text}}
</a>
</li>

View File

@ -0,0 +1 @@
<h5>InfluxDB<h5>

View File

@ -1,6 +1,6 @@
<div ng-include="'app/partials/panelgeneral.html'"></div>
<div ng-include="edit_path(panel.type)"></div>
<div ng-repeat="tab in panelMeta.editorTabs">
<div ng-include="'app/partials/panelgeneral.html'"></div>
<div ng-if="!panelMeta.fullEditorTabs" ng-include="edit_path(panel.type)"></div>
<div ng-repeat="tab in panelMeta.editorTabs">
<h5>{{tab.title}}</h5>
<div ng-include="tab.src"></div>
</div>
</div>

View File

@ -1,10 +1,6 @@
<div class="editor-row">
<div class="section">
<strong>{{panelMeta.status}}</strong> // <span ng-bind-html="panelMeta.description"></span>
</div>
</div>
<div class="editor-row">
<div class="editor-row">
<div class="section">
<h5>General options</h5>
<div class="editor-option">
<label class="small">Title</label><input type="text" class="input-medium" ng-model='panel.title'></input>
</div>
@ -21,4 +17,4 @@
<input type="checkbox" ng-model="panel.spyable" ng-checked="panel.spyable">
</div>
</div>
</div>
</div>

View File

@ -7,6 +7,5 @@ define([
'./datasourceSrv',
'./keyboardManager',
'./annotationsSrv',
'./graphite/graphiteDatasource',
],
function () {});

View File

@ -1,25 +1,32 @@
define([
'angular',
'underscore',
'config'
'config',
'./graphite/graphiteDatasource',
'./influxdb/influxdbDatasource',
],
function (angular, _, config) {
'use strict';
var module = angular.module('kibana.services');
module.service('datasourceSrv', function($q, filterSrv, $http, GraphiteDatasource) {
module.service('datasourceSrv', function($q, filterSrv, $http, GraphiteDatasource, InfluxDatasource) {
var defaultDatasource = _.findWhere(_.values(config.datasources), { default: true } );
this.default = new GraphiteDatasource(defaultDatasource);
this.get = function(name) {
if (!name) {
return this.default;
}
if (!name) { return this.default; }
return new GraphiteDatasource(config.datasources[name]);
var ds = config.datasources[name];
switch(ds.type) {
case 'graphite':
return new GraphiteDatasource(ds);
case 'influxdb':
return new InfluxDatasource(ds);
}
};
this.listOptions = function() {

View File

@ -17,6 +17,7 @@ function (angular, _, $, config, kbn, moment) {
this.type = 'graphite';
this.basicAuth = datasource.basicAuth;
this.url = datasource.url;
this.editorSrc = 'app/partials/graphite/editor.html';
}
GraphiteDatasource.prototype.query = function(options) {

View File

@ -0,0 +1,77 @@
define([
'angular',
'underscore',
],
function (angular, _) {
'use strict';
var module = angular.module('kibana.services');
module.factory('InfluxDatasource', function($q, $http) {
function InfluxDatasource(datasource) {
this.type = 'influxDB';
this.editorSrc = 'app/partials/influxDB/editor.html';
this.url = datasource.url;
this.username = datasource.username;
this.password = datasource.password;
}
InfluxDatasource.prototype.query = function() {
var q = "select value from request_count where time > now() - 1h group by time(1m)";
var output = { data: [] };
return this.doInfluxRequest(q).then(function(results) {
_.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.data.push({ target:target, datapoints:datapoints });
});
});
return output;
});
};
InfluxDatasource.prototype.doInfluxRequest = function(query) {
var params = {
u: this.username,
p: this.password,
q: query
};
var options = {
method: 'GET',
url: this.url + '/series',
params: params,
};
return $http(options);
};
return InfluxDatasource;
});
});