Ver código fonte

OpenTSDB: Support for template variable values lookup queries, Closes #1250

Torkel Ödegaard 10 anos atrás
pai
commit
e508db994e

+ 1 - 0
CHANGELOG.md

@@ -4,6 +4,7 @@
 - [Issue #1525](https://github.com/grafana/grafana/issues/1525). InfluxDB: Full support for InfluxDB 0.9 with new adapted query editor
 - [Issue #1525](https://github.com/grafana/grafana/issues/1525). InfluxDB: Full support for InfluxDB 0.9 with new adapted query editor
 - [Issue #2191](https://github.com/grafana/grafana/issues/2191). KariosDB: Grafana now ships with a KariosDB data source plugin, thx @masaori335
 - [Issue #2191](https://github.com/grafana/grafana/issues/2191). KariosDB: Grafana now ships with a KariosDB data source plugin, thx @masaori335
 - [Issue #1177](https://github.com/grafana/grafana/issues/1177). OpenTSDB: Limit tags by metric, OpenTSDB config option tsd.core.meta.enable_realtime_ts must enabled for OpenTSDB lookup api
 - [Issue #1177](https://github.com/grafana/grafana/issues/1177). OpenTSDB: Limit tags by metric, OpenTSDB config option tsd.core.meta.enable_realtime_ts must enabled for OpenTSDB lookup api
+- [Issue #1250](https://github.com/grafana/grafana/issues/1250). OpenTSDB: Support for template variable values lookup queries
 
 
 **New dashboard features**
 **New dashboard features**
 - [Issue #1144](https://github.com/grafana/grafana/issues/1144). Templating: You can now select multiple template variables values at the same time.
 - [Issue #1144](https://github.com/grafana/grafana/issues/1144). Templating: You can now select multiple template variables values at the same time.

+ 51 - 31
public/app/plugins/datasource/opentsdb/datasource.js

@@ -76,35 +76,20 @@ function (angular, _, kbn) {
       return backendSrv.datasourceRequest(options);
       return backendSrv.datasourceRequest(options);
     };
     };
 
 
-    OpenTSDBDatasource.prototype.performSuggestQuery = function(query, type) {
-      var options = {
-        method: 'GET',
-        url: this.url + '/api/suggest',
-        params: {
-          type: type,
-          q: query
-        }
-      };
-      return backendSrv.datasourceRequest(options).then(function(result) {
+    OpenTSDBDatasource.prototype._performSuggestQuery = function(query) {
+      return this._get('/api/suggest', {type: 'metrics', q: query}).then(function(result) {
         return result.data;
         return result.data;
       });
       });
     };
     };
 
 
-    OpenTSDBDatasource.prototype.performMetricKeyValueLookup = function(metric, key) {
+    OpenTSDBDatasource.prototype._performMetricKeyValueLookup = function(metric, key) {
       if(!metric || !key) {
       if(!metric || !key) {
         return $q.when([]);
         return $q.when([]);
       }
       }
 
 
       var m = metric + "{" + key + "=*}";
       var m = metric + "{" + key + "=*}";
-      var options = {
-        method: 'GET',
-        url: this.url + '/api/search/lookup',
-        params: {
-          m: m,
-        }
-      };
 
 
-      return backendSrv.datasourceRequest(options).then(function(result) {
+      return this._get('/api/search/lookup', {m: m}).then(function(result) {
         result = result.data.results;
         result = result.data.results;
         var tagvs = [];
         var tagvs = [];
         _.each(result, function(r) {
         _.each(result, function(r) {
@@ -114,18 +99,10 @@ function (angular, _, kbn) {
       });
       });
     };
     };
 
 
-    OpenTSDBDatasource.prototype.performMetricKeyLookup = function(metric) {
-      if(metric === "") {
-        throw "Metric not set.";
-      }
-      var options = {
-        method: 'GET',
-        url: this.url + '/api/search/lookup',
-        params: {
-          m: metric,
-        }
-      };
-      return backendSrv.datasourceRequest(options).then(function(result) {
+    OpenTSDBDatasource.prototype._performMetricKeyLookup = function(metric) {
+      if(!metric) { return $q.when([]); }
+
+      return this._get('/api/search/lookup', {m: metric}).then(function(result) {
         result = result.data.results;
         result = result.data.results;
         var tagks = [];
         var tagks = [];
         _.each(result, function(r) {
         _.each(result, function(r) {
@@ -139,6 +116,49 @@ function (angular, _, kbn) {
       });
       });
     };
     };
 
 
+    OpenTSDBDatasource.prototype._get = function(relativeUrl, params) {
+      return backendSrv.datasourceRequest({
+        method: 'GET',
+        url: this.url + relativeUrl,
+        params: params,
+      });
+    };
+
+    OpenTSDBDatasource.prototype.metricFindQuery = function(query) {
+      var interpolated;
+      try {
+        interpolated = templateSrv.replace(query);
+      }
+      catch (err) {
+        return $q.reject(err);
+      }
+
+      var responseTransform = function(result) {
+        return _.map(result, function(value) {
+          return {text: value};
+        });
+      };
+
+      var metrics_regex = /metrics\((.*)\)/;
+      var tag_names_regex = /tag_names\((.*)\)/;
+      var tag_values_regex = /tag_values\((\w+),\s?(\w+)/;
+
+      var metrics_query = interpolated.match(metrics_regex);
+      if (metrics_query) {
+        return this._performSuggestQuery(metrics_query[1]).then(responseTransform);
+      }
+      var tag_names_query = interpolated.match(tag_names_regex);
+
+      if (tag_names_query) {
+        return this._performMetricKeyLookup(tag_names_query[1]).then(responseTransform);
+      }
+
+      var tag_values_query = interpolated.match(tag_values_regex);
+      if (tag_values_query) {
+        return this._performMetricKeyValueLookup(tag_values_query[1], tag_values_query[2]).then(responseTransform);
+      }
+    };
+
     OpenTSDBDatasource.prototype.testDatasource = function() {
     OpenTSDBDatasource.prototype.testDatasource = function() {
       return this.performSuggestQuery('cpu', 'metrics').then(function () {
       return this.performSuggestQuery('cpu', 'metrics').then(function () {
         return { status: "success", message: "Data source is working", title: "Success" };
         return { status: "success", message: "Data source is working", title: "Success" };

+ 10 - 6
public/app/plugins/datasource/opentsdb/queryCtrl.js

@@ -42,21 +42,25 @@ function (angular, _, kbn) {
       $scope.panel.targets.push(clone);
       $scope.panel.targets.push(clone);
     };
     };
 
 
+    $scope.getTextValues = function(metricFindResult) {
+      return _.map(metricFindResult, function(value) { return value.text; });
+    };
+
     $scope.suggestMetrics = function(query, callback) {
     $scope.suggestMetrics = function(query, callback) {
-      $scope.datasource
-        .performSuggestQuery(query, 'metrics')
+      $scope.datasource.metricFindQuery('metrics()')
+        .then($scope.getTextValues)
         .then(callback);
         .then(callback);
     };
     };
 
 
     $scope.suggestTagKeys = function(query, callback) {
     $scope.suggestTagKeys = function(query, callback) {
-      $scope.datasource
-        .performMetricKeyLookup($scope.target.metric)
+      $scope.datasource.metricFindQuery('tag_names(' + $scope.target.metric + ')')
+        .then($scope.getTextValues)
         .then(callback);
         .then(callback);
     };
     };
 
 
     $scope.suggestTagValues = function(query, callback) {
     $scope.suggestTagValues = function(query, callback) {
-      $scope.datasource
-        .performMetricKeyValueLookup($scope.target.metric, $scope.target.currentTagKey)
+      $scope.datasource.metricFindQuery('tag_names(' + $scope.target.metric + ',' + $scope.target.currentTagKey + ')')
+        .then($scope.getTextValues)
         .then(callback);
         .then(callback);
     };
     };
 
 

+ 52 - 0
public/test/specs/opentsdbDatasource-specs.js

@@ -0,0 +1,52 @@
+define([
+  'helpers',
+  'plugins/datasource/opentsdb/datasource'
+], function(helpers) {
+  'use strict';
+
+  describe('opentsdb', function() {
+    var ctx = new helpers.ServiceTestContext();
+
+    beforeEach(module('grafana.services'));
+    beforeEach(ctx.providePhase(['backendSrv']));
+
+    beforeEach(ctx.createService('OpenTSDBDatasource'));
+    beforeEach(function() {
+      ctx.ds = new ctx.service({ url: [''] });
+    });
+
+    describe('When performing metricFindQuery', function() {
+      var results;
+      var requestOptions;
+
+      beforeEach(function() {
+        ctx.backendSrv.datasourceRequest = function(options) {
+          requestOptions = options;
+          return ctx.$q.when({data: [{ target: 'prod1.count', datapoints: [[10, 1], [12,1]] }]});
+        };
+      });
+
+      it('metrics() should generate api suggest query', function() {
+        ctx.ds.metricFindQuery('metrics()').then(function(data) { results = data; });
+        ctx.$rootScope.$apply();
+        expect(requestOptions.url).to.be('/api/suggest');
+      });
+
+      it('tag_names(cpu) should generate looku  query', function() {
+        ctx.ds.metricFindQuery('tag_names(cpu)').then(function(data) { results = data; });
+        ctx.$rootScope.$apply();
+        expect(requestOptions.url).to.be('/api/search/lookup');
+        expect(requestOptions.params.m).to.be('cpu');
+      });
+
+      it('tag_values(cpu, test) should generate looku  query', function() {
+        ctx.ds.metricFindQuery('tag_values(cpu, hostname)').then(function(data) { results = data; });
+        ctx.$rootScope.$apply();
+        expect(requestOptions.url).to.be('/api/search/lookup');
+        expect(requestOptions.params.m).to.be('cpu{hostname=*}');
+      });
+
+    });
+  });
+});
+

+ 1 - 0
public/test/test-main.js

@@ -146,6 +146,7 @@ require([
     'specs/dynamicDashboardSrv-specs',
     'specs/dynamicDashboardSrv-specs',
     'specs/unsavedChangesSrv-specs',
     'specs/unsavedChangesSrv-specs',
     'specs/valueSelectDropdown-specs',
     'specs/valueSelectDropdown-specs',
+    'specs/opentsdbDatasource-specs',
   ];
   ];
 
 
   var pluginSpecs = (config.plugins.specs || []).map(function (spec) {
   var pluginSpecs = (config.plugins.specs || []).map(function (spec) {