Kaynağa Gözat

Graphite 1.0 functions (#8987)

* graphite-ds: add graphite version to config editor

* graphite-ds: modify add-graphite-function to show only version-related functions

* graphite-ds: refactor, move func filtering to gfunc.js

* graphite-ds: add new functions for graphite 1.0.x

* graphite-ds: fix unit tests (add jsonData)
Alexander Zobnin 8 yıl önce
ebeveyn
işleme
4fe79edd40

+ 11 - 8
public/app/plugins/datasource/graphite/add_graphite_func.js

@@ -20,9 +20,10 @@ function (angular, _, $, gfunc) {
 
       return {
         link: function($scope, elem) {
-          var categories = gfunc.getCategories();
-          var allFunctions = getAllFunctionNames(categories);
           var ctrl = $scope.ctrl;
+          var graphiteVersion = ctrl.datasource.graphiteVersion;
+          var categories = gfunc.getCategories(graphiteVersion);
+          var allFunctions = getAllFunctionNames(categories);
 
           $scope.functionMenu = createFunctionDropDownMenu(categories);
 
@@ -94,14 +95,16 @@ function (angular, _, $, gfunc) {
 
   function createFunctionDropDownMenu(categories) {
     return _.map(categories, function(list, category) {
+      var submenu = _.map(list, function(value) {
+        return {
+          text: value.name,
+          click: "ctrl.addFunction('" + value.name + "')",
+        };
+      });
+
       return {
         text: category,
-        submenu: _.map(list, function(value) {
-          return {
-            text: value.name,
-            click: "ctrl.addFunction('" + value.name + "')",
-          };
-        })
+        submenu: submenu
       };
     });
   }

+ 20 - 0
public/app/plugins/datasource/graphite/config_ctrl.ts

@@ -0,0 +1,20 @@
+///<reference path="../../../headers/common.d.ts" />
+
+import angular from 'angular';
+import _ from 'lodash';
+
+export class GraphiteConfigCtrl {
+  static templateUrl = 'public/app/plugins/datasource/graphite/partials/config.html';
+  current: any;
+
+  /** @ngInject */
+  constructor($scope) {
+    this.current.jsonData.graphiteVersion = this.current.jsonData.graphiteVersion || '0.9';
+  }
+
+  graphiteVersions = [
+    {name: '0.9.x', value: '0.9'},
+    {name: '1.0.x', value: '1.0'},
+  ];
+}
+

+ 1 - 0
public/app/plugins/datasource/graphite/datasource.ts

@@ -11,6 +11,7 @@ export function GraphiteDatasource(instanceSettings, $q, backendSrv, templateSrv
   this.basicAuth = instanceSettings.basicAuth;
   this.url = instanceSettings.url;
   this.name = instanceSettings.name;
+  this.graphiteVersion = instanceSettings.jsonData.graphiteVersion || '0.9';
   this.cacheTimeout = instanceSettings.cacheTimeout;
   this.withCredentials = instanceSettings.withCredentials;
   this.render_method = instanceSettings.render_method || 'POST';

+ 255 - 72
public/app/plugins/datasource/graphite/gfunc.js

@@ -115,27 +115,6 @@ function (_, $) {
     category: categories.Combine,
   });
 
-  addFuncDef({
-    name: 'mapSeries',
-    shortName: 'map',
-    params: [{ name: "node", type: 'int' }],
-    defaultParams: [3],
-    category: categories.Combine,
-  });
-
-  addFuncDef({
-    name: 'reduceSeries',
-    shortName: 'reduce',
-    params: [
-      { name: "function", type: 'string', options: ['asPercent', 'diffSeries', 'divideSeries'] },
-      { name: "reduceNode", type: 'int', options: [0,1,2,3,4,5,6,7,8,9,10,11,12,13] },
-      { name: "reduceMatchers", type: 'string' },
-      { name: "reduceMatchers", type: 'string' },
-    ],
-    defaultParams: ['asPercent', 2, 'used_bytes', 'total_bytes'],
-    category: categories.Combine,
-  });
-
   addFuncDef({
     name: 'sumSeries',
     shortName: 'sum',
@@ -152,11 +131,6 @@ function (_, $) {
     defaultParams: [''],
   });
 
-  addFuncDef({
-    name: 'isNonNull',
-    category: categories.Combine,
-  });
-
   addFuncDef({
     name: 'rangeOfSeries',
     category: categories.Combine
@@ -262,23 +236,6 @@ function (_, $) {
     defaultParams: [3, "sum"]
   });
 
-  addFuncDef({
-    name: "groupByNodes",
-    category: categories.Special,
-    params: [
-      {
-        name: "function",
-        type: "string",
-        options: ['sum', 'avg', 'maxSeries']
-      },
-      { name: "node", type: "int", options: [0,1,2,3,4,5,6,7,8,9,10,12] },
-      { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true },
-      { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true },
-      { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true },
-    ],
-    defaultParams: ["sum", 3]
-  });
-
   addFuncDef({
     name: 'aliasByNode',
     category: categories.Special,
@@ -381,11 +338,6 @@ function (_, $) {
     defaultParams: [10]
   });
 
-  addFuncDef({
-    name: 'offsetToZero',
-    category: categories.Transform,
-  });
-
   addFuncDef({
     name: 'transformNull',
     category: categories.Transform,
@@ -542,13 +494,6 @@ function (_, $) {
     defaultParams: ['exclude']
   });
 
-  addFuncDef({
-    name: "grep",
-    category: categories.Filter,
-    params: [{ name: "grep", type: 'string' }],
-    defaultParams: ['grep']
-  });
-
   addFuncDef({
     name: 'highestCurrent',
     category: categories.Filter,
@@ -577,16 +522,6 @@ function (_, $) {
     defaultParams: [10]
   });
 
-  addFuncDef({
-    name: 'weightedAverage',
-    category: categories.Filter,
-    params: [
-      { name: 'other', type: 'value_or_series', optional: true },
-      { name: "node", type: "int", options: [0,1,2,3,4,5,6,7,8,9,10,12] },
-    ],
-    defaultParams: ['#A', 4]
-  });
-
   addFuncDef({
     name: 'movingMedian',
     category: categories.Filter,
@@ -643,11 +578,6 @@ function (_, $) {
     defaultParams: [5]
   });
 
-  addFuncDef({
-    name: 'removeEmptySeries',
-    category: categories.Filter
-  });
-
   addFuncDef({
     name: 'useSeriesAbove',
     category: categories.Filter,
@@ -659,6 +589,239 @@ function (_, $) {
     defaultParams: [0, 'search', 'replace']
   });
 
+  ////////////////////
+  // Graphite 1.0.x //
+  ////////////////////
+
+  addFuncDef({
+    name: 'aggregateLine',
+    category: categories.Combine,
+    params: [{ name: "func", type: "select", options: ['sum', 'avg', 'min', 'max', 'last']}],
+    defaultParams: ['avg'],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'averageOutsidePercentile',
+    category: categories.Filter,
+    params: [{ name: "n", type: "int", }],
+    defaultParams: [95],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'delay',
+    category: categories.Transform,
+    params: [{ name: 'steps', type: 'int', }],
+    defaultParams: [1],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'exponentialMovingAverage',
+    category: categories.Calculate,
+    params: [{ name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }],
+    defaultParams: [10],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'fallbackSeries',
+    category: categories.Special,
+    params: [{ name: 'fallback', type: 'string' }],
+    defaultParams: ['constantLine(0)'],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: "grep",
+    category: categories.Filter,
+    params: [{ name: "grep", type: 'string' }],
+    defaultParams: ['grep'],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: "groupByNodes",
+    category: categories.Special,
+    params: [
+      {
+        name: "function",
+        type: "string",
+        options: ['sum', 'avg', 'maxSeries']
+      },
+      { name: "node", type: "int", options: [0,1,2,3,4,5,6,7,8,9,10,12] },
+      { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true },
+      { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true },
+      { name: "node", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true },
+    ],
+    defaultParams: ["sum", 3],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'integralByInterval',
+    category: categories.Transform,
+    params: [{ name: "intervalUnit", type: "select", options: ['1h', '6h', '12h', '1d', '2d', '7d', '14d', '30d'] }],
+    defaultParams: ['1d'],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'interpolate',
+    category: categories.Transform,
+    params: [{ name: 'limit', type: 'int', optional: true}],
+    defaultParams: [],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'invert',
+    category: categories.Transform,
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'isNonNull',
+    category: categories.Combine,
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'linearRegression',
+    category: categories.Calculate,
+    params: [
+      { name: "startSourceAt", type: "select", options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'], optional: true },
+      { name: "endSourceAt", type: "select", options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'], optional: true }
+    ],
+    defaultParams: [],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'mapSeries',
+    shortName: 'map',
+    params: [{ name: "node", type: 'int' }],
+    defaultParams: [3],
+    category: categories.Combine,
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'movingMin',
+    category: categories.Calculate,
+    params: [{ name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }],
+    defaultParams: [10],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'movingMax',
+    category: categories.Calculate,
+    params: [{ name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }],
+    defaultParams: [10],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'movingSum',
+    category: categories.Calculate,
+    params: [{ name: 'windowSize', type: 'int_or_interval', options: ['5', '7', '10', '5min', '10min', '30min', '1hour'] }],
+    defaultParams: [10],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: "multiplySeriesWithWildcards",
+    category: categories.Calculate,
+    params: [
+      { name: "position", type: "int", options: [0,1,2,3,4,5,6,7,8,9,10,12] },
+      { name: "position", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true },
+      { name: "position", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true },
+      { name: "position", type: "int", options: [0,-1,-2,-3,-4,-5,-6,-7], optional: true },
+    ],
+    defaultParams: [2],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'offsetToZero',
+    category: categories.Transform,
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'pow',
+    category: categories.Transform,
+    params: [{ name: 'factor', type: 'int' }],
+    defaultParams: [10],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'powSeries',
+    category: categories.Transform,
+    params: optionalSeriesRefArgs,
+    defaultParams: [''],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'reduceSeries',
+    shortName: 'reduce',
+    params: [
+      { name: "function", type: 'string', options: ['asPercent', 'diffSeries', 'divideSeries'] },
+      { name: "reduceNode", type: 'int', options: [0,1,2,3,4,5,6,7,8,9,10,11,12,13] },
+      { name: "reduceMatchers", type: 'string' },
+      { name: "reduceMatchers", type: 'string' },
+    ],
+    defaultParams: ['asPercent', 2, 'used_bytes', 'total_bytes'],
+    category: categories.Combine,
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'removeBetweenPercentile',
+    category: categories.Filter,
+    params: [{ name: "n", type: "int", }],
+    defaultParams: [95],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'removeEmptySeries',
+    category: categories.Filter,
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'squareRoot',
+    category: categories.Transform,
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'timeSlice',
+    category: categories.Transform,
+    params: [
+      { name: "startSliceAt", type: "select", options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d']},
+      { name: "endSliceAt", type: "select", options: ['-1h', '-6h', '-12h', '-1d', '-2d', '-7d', '-14d', '-30d'], optional: true }
+    ],
+    defaultParams: ['-1h'],
+    version: '1.0'
+  });
+
+  addFuncDef({
+    name: 'weightedAverage',
+    category: categories.Filter,
+    params: [
+      { name: 'other', type: 'value_or_series', optional: true },
+      { name: "node", type: "int", options: [0,1,2,3,4,5,6,7,8,9,10,12] },
+    ],
+    defaultParams: ['#A', 4],
+    version: '1.0'
+  });
+
   _.each(categories, function(funcList, catName) {
     categories[catName] = _.sortBy(funcList, 'name');
   });
@@ -737,6 +900,16 @@ function (_, $) {
     this.text = text;
   };
 
+  function isVersionRelatedFunction(func, graphiteVersion) {
+    return isVersionGreaterOrEqual(graphiteVersion, func.version) || !func.version;
+  }
+
+  function isVersionGreaterOrEqual(a, b) {
+    var a_num = Number(a);
+    var b_num = Number(b);
+    return a_num >= b_num;
+  }
+
   return {
     createFuncInstance: function(funcDef, options) {
       if (_.isString(funcDef)) {
@@ -752,8 +925,18 @@ function (_, $) {
       return index[name];
     },
 
-    getCategories: function() {
-      return categories;
+    getCategories: function(graphiteVersion) {
+      var filteredCategories = {};
+      _.each(categories, function(functions, category) {
+        var filteredFuncs = _.filter(functions, function(func) {
+          return isVersionRelatedFunction(func, graphiteVersion);
+        });
+        if (filteredFuncs.length) {
+          filteredCategories[category] = filteredFuncs;
+        }
+      });
+
+      return filteredCategories;
     }
   };
 

+ 1 - 4
public/app/plugins/datasource/graphite/module.ts

@@ -1,9 +1,6 @@
 import {GraphiteDatasource} from './datasource';
 import {GraphiteQueryCtrl} from './query_ctrl';
-
-class GraphiteConfigCtrl {
-  static templateUrl = 'partials/config.html';
-}
+import {GraphiteConfigCtrl} from './config_ctrl';
 
 class GraphiteQueryOptionsCtrl {
   static templateUrl = 'partials/query.options.html';

+ 8 - 0
public/app/plugins/datasource/graphite/partials/config.html

@@ -3,3 +3,11 @@
 	suggest-url="http://localhost:8080">
 </datasource-http-settings>
 
+<h3 class="page-heading">Graphite details</h3>
+
+<div class="gf-form-group">
+	<div class="gf-form">
+		<span class="gf-form-label width-8">Version</span>
+		<select class="gf-form-input gf-size-auto" ng-model="ctrl.current.jsonData.graphiteVersion" ng-options="f.value as f.name for f in ctrl.graphiteVersions"></select>
+	</div>
+</div>

+ 1 - 1
public/app/plugins/datasource/graphite/specs/datasource_specs.ts

@@ -5,7 +5,7 @@ import {GraphiteDatasource} from "../datasource";
 
 describe('graphiteDatasource', function() {
   var ctx = new helpers.ServiceTestContext();
-  var instanceSettings: any = {url: [''], name: 'graphiteProd'};
+  var instanceSettings: any = {url: [''], name: 'graphiteProd', jsonData: {}};
 
   beforeEach(angularMocks.module('grafana.core'));
   beforeEach(angularMocks.module('grafana.services'));