Browse Source

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

Torkel Ödegaard 11 năm trước cách đây
mục cha
commit
e3f56f2645

+ 1 - 2
src/app/dashboards/default.json

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

+ 1 - 1
src/app/directives/grafanaGraph.js

@@ -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)+

+ 1 - 2
src/app/directives/kibanaPanel.js

@@ -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

+ 12 - 16
src/app/panels/graphite/module.html

@@ -27,27 +27,23 @@
   </div>
 
   <div class="panel-full-edit-tabs" ng-if="editMode">
-      <div ng-model="editor.index" bs-tabs>
-        <div ng-repeat="tab in editorTabs" data-title="{{tab}}">
-        </div>
+    <div ng-model="editor.index" bs-tabs>
+      <div ng-repeat="tab in editorTabs" data-title="{{tab}}">
       </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="section">
-            <div class="editor-option">
-              <label class="small">Datasource</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 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 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>
 </div>

+ 7 - 10
src/app/panels/graphite/module.js

@@ -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();
     };
 

+ 2 - 1
src/app/panels/graphite/editor.html → src/app/partials/graphite/editor.html

@@ -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>

+ 0 - 0
src/app/panels/graphite/funcEditor.html → src/app/partials/graphite/funcEditor.html


+ 1 - 0
src/app/partials/influxdb/editor.html

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

+ 6 - 6
src/app/partials/paneladd.html

@@ -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">
-    <h5>{{tab.title}}</h5>
-    <div ng-include="tab.src"></div>
-  </div>
+<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>

+ 18 - 22
src/app/partials/panelgeneral.html

@@ -1,24 +1,20 @@
-  <div class="editor-row">
-    <div class="section">
-      <strong>{{panelMeta.status}}</strong> // <span ng-bind-html="panelMeta.description"></span>
+<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>
-  </div>
-  <div class="editor-row">
-    <div class="section">
-      <div class="editor-option">
-        <label class="small">Title</label><input type="text" class="input-medium" ng-model='panel.title'></input>
-      </div>
-      <div class="editor-option" ng-hide="panel.sizeable == false">
-        <label class="small">Span</label> <select class="input-mini" ng-model="panel.span" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10,11,12]"></select>
-      </div>
-      <div class="editor-option">
-        <label class="small">Editable</label><input type="checkbox" ng-model="panel.editable" ng-checked="panel.editable">
-      </div>
-      <div class="editor-option" ng-show="!_.isUndefined(panel.spyable)">
-        <label class="small">
-          Inspect <i class="icon-question-sign" bs-tooltip="'Allow query reveal via <i class=icon-eye-open></i>'"></i>
-        </label>
-        <input type="checkbox" ng-model="panel.spyable" ng-checked="panel.spyable">
-      </div>
+    <div class="editor-option" ng-hide="panel.sizeable == false">
+      <label class="small">Span</label> <select class="input-mini" ng-model="panel.span" ng-options="f for f in [0,1,2,3,4,5,6,7,8,9,10,11,12]"></select>
+    </div>
+    <div class="editor-option">
+      <label class="small">Editable</label><input type="checkbox" ng-model="panel.editable" ng-checked="panel.editable">
     </div>
-  </div>
+    <div class="editor-option" ng-show="!_.isUndefined(panel.spyable)">
+      <label class="small">
+        Inspect <i class="icon-question-sign" bs-tooltip="'Allow query reveal via <i class=icon-eye-open></i>'"></i>
+      </label>
+      <input type="checkbox" ng-model="panel.spyable" ng-checked="panel.spyable">
+    </div>
+  </div>
+</div>

+ 0 - 1
src/app/services/all.js

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

+ 13 - 6
src/app/services/datasourceSrv.js

@@ -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; }
+
+      var ds = config.datasources[name];
 
-      return new GraphiteDatasource(config.datasources[name]);
+      switch(ds.type) {
+      case 'graphite':
+        return new GraphiteDatasource(ds);
+      case 'influxdb':
+        return new InfluxDatasource(ds);
+      }
     };
 
     this.listOptions = function() {

+ 1 - 0
src/app/services/graphite/graphiteDatasource.js

@@ -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) {

+ 77 - 0
src/app/services/influxdb/influxdbDatasource.js

@@ -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;
+
+  });
+
+});